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

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

Issue 138363004: Views Textfield fixes and cleanup. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync and rebase. Created 6 years, 11 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) 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.h" 5 #include "ui/views/controls/textfield/textfield.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/i18n/case_conversion.h"
11 #include "grit/ui_strings.h" 10 #include "grit/ui_strings.h"
12 #include "ui/base/accessibility/accessible_view_state.h" 11 #include "ui/base/accessibility/accessible_view_state.h"
13 #include "ui/base/dragdrop/drag_drop_types.h" 12 #include "ui/base/dragdrop/drag_drop_types.h"
14 #include "ui/base/dragdrop/drag_utils.h" 13 #include "ui/base/dragdrop/drag_utils.h"
15 #include "ui/base/resource/resource_bundle.h" 14 #include "ui/base/resource/resource_bundle.h"
16 #include "ui/base/ui_base_switches_util.h" 15 #include "ui/base/ui_base_switches_util.h"
17 #include "ui/events/event.h" 16 #include "ui/events/event.h"
18 #include "ui/events/keycodes/keyboard_codes.h" 17 #include "ui/events/keycodes/keyboard_codes.h"
19 #include "ui/gfx/canvas.h" 18 #include "ui/gfx/canvas.h"
20 #include "ui/gfx/insets.h" 19 #include "ui/gfx/insets.h"
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 static const size_t system_value = ::GetCaretBlinkTime(); 67 static const size_t system_value = ::GetCaretBlinkTime();
69 if (system_value != 0) 68 if (system_value != 0)
70 return (system_value == INFINITE) ? 0 : system_value; 69 return (system_value == INFINITE) ? 0 : system_value;
71 #endif 70 #endif
72 return default_value; 71 return default_value;
73 } 72 }
74 73
75 Textfield::Textfield() 74 Textfield::Textfield()
76 : model_(new TextfieldModel(this)), 75 : model_(new TextfieldModel(this)),
77 controller_(NULL), 76 controller_(NULL),
78 style_(STYLE_DEFAULT),
79 read_only_(false), 77 read_only_(false),
80 default_width_in_chars_(0), 78 default_width_in_chars_(0),
81 text_color_(SK_ColorBLACK), 79 text_color_(SK_ColorBLACK),
82 use_default_text_color_(true), 80 use_default_text_color_(true),
83 background_color_(SK_ColorWHITE), 81 background_color_(SK_ColorWHITE),
84 use_default_background_color_(true), 82 use_default_background_color_(true),
85 placeholder_text_color_(kDefaultPlaceholderTextColor), 83 placeholder_text_color_(kDefaultPlaceholderTextColor),
86 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT), 84 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
87 skip_input_method_cancel_composition_(false), 85 skip_input_method_cancel_composition_(false),
88 cursor_visible_(false), 86 cursor_visible_(false),
89 drop_cursor_visible_(false), 87 drop_cursor_visible_(false),
90 initiating_drag_(false), 88 initiating_drag_(false),
91 aggregated_clicks_(0), 89 aggregated_clicks_(0),
92 weak_ptr_factory_(this) { 90 weak_ptr_factory_(this) {
93 set_context_menu_controller(this); 91 set_context_menu_controller(this);
94 set_drag_controller(this); 92 set_drag_controller(this);
95 set_border(new FocusableBorder()); 93 set_border(new FocusableBorder());
96 SetFocusable(true); 94 SetFocusable(true);
97 95
98 if (ViewsDelegate::views_delegate) { 96 if (ViewsDelegate::views_delegate) {
99 obscured_reveal_duration_ = ViewsDelegate::views_delegate-> 97 password_reveal_duration_ = ViewsDelegate::views_delegate->
100 GetDefaultTextfieldObscuredRevealDuration(); 98 GetDefaultTextfieldObscuredRevealDuration();
101 } 99 }
102 100
103 if (NativeViewHost::kRenderNativeControlFocus) 101 if (NativeViewHost::kRenderNativeControlFocus)
104 focus_painter_ = Painter::CreateDashedFocusPainter(); 102 focus_painter_ = Painter::CreateDashedFocusPainter();
105 } 103 }
106 104
107 Textfield::Textfield(StyleFlags style) 105 Textfield::~Textfield() {}
108 : model_(new TextfieldModel(this)),
109 controller_(NULL),
110 style_(style),
111 read_only_(false),
112 default_width_in_chars_(0),
113 text_color_(SK_ColorBLACK),
114 use_default_text_color_(true),
115 background_color_(SK_ColorWHITE),
116 use_default_background_color_(true),
117 placeholder_text_color_(kDefaultPlaceholderTextColor),
118 text_input_type_(ui::TEXT_INPUT_TYPE_TEXT),
119 skip_input_method_cancel_composition_(false),
120 cursor_visible_(false),
121 drop_cursor_visible_(false),
122 initiating_drag_(false),
123 aggregated_clicks_(0),
124 weak_ptr_factory_(this) {
125 set_context_menu_controller(this);
126 set_drag_controller(this);
127 set_border(new FocusableBorder());
128 SetFocusable(true);
129
130 if (IsObscured())
131 SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
132
133 if (ViewsDelegate::views_delegate) {
134 obscured_reveal_duration_ = ViewsDelegate::views_delegate->
135 GetDefaultTextfieldObscuredRevealDuration();
136 }
137
138 if (NativeViewHost::kRenderNativeControlFocus)
139 focus_painter_ = Painter::CreateDashedFocusPainter();
140 }
141
142 Textfield::~Textfield() {
143 }
144
145 void Textfield::SetController(TextfieldController* controller) {
146 controller_ = controller;
147 }
148
149 TextfieldController* Textfield::GetController() const {
150 return controller_;
151 }
152 106
153 void Textfield::SetReadOnly(bool read_only) { 107 void Textfield::SetReadOnly(bool read_only) {
154 // Update read-only without changing the focusable state (or active, etc.). 108 // Update read-only without changing the focusable state (or active, etc.).
155 read_only_ = read_only; 109 read_only_ = read_only;
156 if (GetInputMethod()) 110 if (GetInputMethod())
157 GetInputMethod()->OnTextInputTypeChanged(this); 111 GetInputMethod()->OnTextInputTypeChanged(this);
158 SetColor(GetTextColor()); 112 SetColor(GetTextColor());
159 UpdateBackgroundColor(); 113 UpdateBackgroundColor();
160 } 114 }
161 115
162 bool Textfield::IsObscured() const { 116 void Textfield::SetTextInputType(ui::TextInputType type) {
163 return style_ & STYLE_OBSCURED; 117 GetRenderText()->SetObscured(type == ui::TEXT_INPUT_TYPE_PASSWORD);
164 } 118 text_input_type_ = type;
165
166 void Textfield::SetObscured(bool obscured) {
167 if (obscured) {
168 style_ = static_cast<StyleFlags>(style_ | STYLE_OBSCURED);
169 SetTextInputType(ui::TEXT_INPUT_TYPE_PASSWORD);
170 } else {
171 style_ = static_cast<StyleFlags>(style_ & ~STYLE_OBSCURED);
172 SetTextInputType(ui::TEXT_INPUT_TYPE_TEXT);
173 }
174 GetRenderText()->SetObscured(obscured);
175 OnCaretBoundsChanged(); 119 OnCaretBoundsChanged();
176 if (GetInputMethod()) 120 if (GetInputMethod())
177 GetInputMethod()->OnTextInputTypeChanged(this); 121 GetInputMethod()->OnTextInputTypeChanged(this);
178 SchedulePaint(); 122 SchedulePaint();
179 } 123 }
180 124
181 void Textfield::SetTextInputType(ui::TextInputType type) {
182 text_input_type_ = type;
183 bool should_be_obscured = type == ui::TEXT_INPUT_TYPE_PASSWORD;
184 if (IsObscured() != should_be_obscured)
185 SetObscured(should_be_obscured);
186 }
187
188 void Textfield::SetText(const base::string16& new_text) { 125 void Textfield::SetText(const base::string16& new_text) {
189 model_->SetText(GetTextForDisplay(new_text)); 126 model_->SetText(new_text);
190 OnCaretBoundsChanged(); 127 OnCaretBoundsChanged();
191 SchedulePaint(); 128 SchedulePaint();
192 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); 129 NotifyAccessibilityEvent(ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
193 } 130 }
194 131
195 void Textfield::AppendText(const base::string16& new_text) { 132 void Textfield::AppendText(const base::string16& new_text) {
196 if (new_text.empty()) 133 if (new_text.empty())
197 return; 134 return;
198 model_->Append(GetTextForDisplay(new_text)); 135 model_->Append(new_text);
199 OnCaretBoundsChanged(); 136 OnCaretBoundsChanged();
200 SchedulePaint(); 137 SchedulePaint();
201 } 138 }
202 139
203 void Textfield::InsertOrReplaceText(const base::string16& new_text) { 140 void Textfield::InsertOrReplaceText(const base::string16& new_text) {
204 if (new_text.empty()) 141 if (new_text.empty())
205 return; 142 return;
206 model_->InsertText(new_text); 143 model_->InsertText(new_text);
207 OnCaretBoundsChanged(); 144 OnCaretBoundsChanged();
208 SchedulePaint(); 145 SchedulePaint();
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
404 return true; 341 return true;
405 342
406 // TODO(oshima): Refactor and consolidate with ExecuteCommand. 343 // TODO(oshima): Refactor and consolidate with ExecuteCommand.
407 if (event.type() == ui::ET_KEY_PRESSED) { 344 if (event.type() == ui::ET_KEY_PRESSED) {
408 ui::KeyboardCode key_code = event.key_code(); 345 ui::KeyboardCode key_code = event.key_code();
409 if (key_code == ui::VKEY_TAB || event.IsUnicodeKeyCode()) 346 if (key_code == ui::VKEY_TAB || event.IsUnicodeKeyCode())
410 return false; 347 return false;
411 348
412 gfx::RenderText* render_text = GetRenderText(); 349 gfx::RenderText* render_text = GetRenderText();
413 const bool editable = !read_only(); 350 const bool editable = !read_only();
414 const bool readable = !IsObscured(); 351 const bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD;
415 const bool shift = event.IsShiftDown(); 352 const bool shift = event.IsShiftDown();
416 const bool control = event.IsControlDown(); 353 const bool control = event.IsControlDown();
417 const bool alt = event.IsAltDown() || event.IsAltGrDown(); 354 const bool alt = event.IsAltDown() || event.IsAltGrDown();
418 bool text_changed = false; 355 bool text_changed = false;
419 bool cursor_changed = false; 356 bool cursor_changed = false;
420 357
421 OnBeforeUserAction(); 358 OnBeforeUserAction();
422 switch (key_code) { 359 switch (key_code) {
423 case ui::VKEY_Z: 360 case ui::VKEY_Z:
424 if (control && !shift && !alt && editable) 361 if (control && !shift && !alt && editable)
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 572
636 // Border typically draws focus indicator. 573 // Border typically draws focus indicator.
637 SchedulePaint(); 574 SchedulePaint();
638 } 575 }
639 576
640 void Textfield::GetAccessibleState(ui::AccessibleViewState* state) { 577 void Textfield::GetAccessibleState(ui::AccessibleViewState* state) {
641 state->role = ui::AccessibilityTypes::ROLE_TEXT; 578 state->role = ui::AccessibilityTypes::ROLE_TEXT;
642 state->name = accessible_name_; 579 state->name = accessible_name_;
643 if (read_only()) 580 if (read_only())
644 state->state |= ui::AccessibilityTypes::STATE_READONLY; 581 state->state |= ui::AccessibilityTypes::STATE_READONLY;
645 if (IsObscured()) 582 if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD)
646 state->state |= ui::AccessibilityTypes::STATE_PROTECTED; 583 state->state |= ui::AccessibilityTypes::STATE_PROTECTED;
647 state->value = text(); 584 state->value = text();
648 585
649 const gfx::Range range = GetSelectedRange(); 586 const gfx::Range range = GetSelectedRange();
650 state->selection_start = range.start(); 587 state->selection_start = range.start();
651 state->selection_end = range.end(); 588 state->selection_end = range.end();
652 589
653 if (!read_only()) { 590 if (!read_only()) {
654 state->set_value_callback = 591 state->set_value_callback =
655 base::Bind(&Textfield::AccessibilitySetValue, 592 base::Bind(&Textfield::AccessibilitySetValue,
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after
834 gfx::RenderText* render_text = GetRenderText(); 771 gfx::RenderText* render_text = GetRenderText();
835 DCHECK(!initiating_drag_ || 772 DCHECK(!initiating_drag_ ||
836 !render_text->IsPointInSelection(event.location())); 773 !render_text->IsPointInSelection(event.location()));
837 OnBeforeUserAction(); 774 OnBeforeUserAction();
838 skip_input_method_cancel_composition_ = true; 775 skip_input_method_cancel_composition_ = true;
839 776
840 gfx::SelectionModel drop_destination_model = 777 gfx::SelectionModel drop_destination_model =
841 render_text->FindCursorPosition(event.location()); 778 render_text->FindCursorPosition(event.location());
842 base::string16 new_text; 779 base::string16 new_text;
843 event.data().GetString(&new_text); 780 event.data().GetString(&new_text);
844 new_text = GetTextForDisplay(new_text);
845 781
846 // Delete the current selection for a drag and drop within this view. 782 // Delete the current selection for a drag and drop within this view.
847 const bool move = initiating_drag_ && !event.IsControlDown() && 783 const bool move = initiating_drag_ && !event.IsControlDown() &&
848 event.source_operations() & ui::DragDropTypes::DRAG_MOVE; 784 event.source_operations() & ui::DragDropTypes::DRAG_MOVE;
849 if (move) { 785 if (move) {
850 // Adjust the drop destination if it is on or after the current selection. 786 // Adjust the drop destination if it is on or after the current selection.
851 size_t pos = drop_destination_model.caret_pos(); 787 size_t pos = drop_destination_model.caret_pos();
852 pos -= render_text->selection().Intersect(gfx::Range(0, pos)).length(); 788 pos -= render_text->selection().Intersect(gfx::Range(0, pos)).length();
853 model_->DeleteSelectionAndInsertTextAt(new_text, pos); 789 model_->DeleteSelectionAndInsertTextAt(new_text, pos);
854 } else { 790 } else {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 drag_utils::SetDragImageOnDataObject(*canvas, size(), 853 drag_utils::SetDragImageOnDataObject(*canvas, size(),
918 press_pt.OffsetFromOrigin(), 854 press_pt.OffsetFromOrigin(),
919 data); 855 data);
920 if (controller_) 856 if (controller_)
921 controller_->OnWriteDragData(data); 857 controller_->OnWriteDragData(data);
922 } 858 }
923 859
924 int Textfield::GetDragOperationsForView(views::View* sender, 860 int Textfield::GetDragOperationsForView(views::View* sender,
925 const gfx::Point& p) { 861 const gfx::Point& p) {
926 int drag_operations = ui::DragDropTypes::DRAG_COPY; 862 int drag_operations = ui::DragDropTypes::DRAG_COPY;
927 if (!enabled() || IsObscured() || !GetRenderText()->IsPointInSelection(p)) 863 if (!enabled() || text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD ||
864 !GetRenderText()->IsPointInSelection(p)) {
928 drag_operations = ui::DragDropTypes::DRAG_NONE; 865 drag_operations = ui::DragDropTypes::DRAG_NONE;
929 else if (sender == this && !read_only()) 866 } else if (sender == this && !read_only()) {
930 drag_operations = 867 drag_operations =
931 ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY; 868 ui::DragDropTypes::DRAG_MOVE | ui::DragDropTypes::DRAG_COPY;
869 }
932 if (controller_) 870 if (controller_)
933 controller_->OnGetDragOperationsForTextfield(&drag_operations); 871 controller_->OnGetDragOperationsForTextfield(&drag_operations);
934 return drag_operations; 872 return drag_operations;
935 } 873 }
936 874
937 bool Textfield::CanStartDragForView(View* sender, 875 bool Textfield::CanStartDragForView(View* sender,
938 const gfx::Point& press_pt, 876 const gfx::Point& press_pt,
939 const gfx::Point& p) { 877 const gfx::Point& p) {
940 return initiating_drag_ && GetRenderText()->IsPointInSelection(press_pt); 878 return initiating_drag_ && GetRenderText()->IsPointInSelection(press_pt);
941 } 879 }
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 //////////////////////////////////////////////////////////////////////////////// 939 ////////////////////////////////////////////////////////////////////////////////
1002 // Textfield, ui::SimpleMenuModel::Delegate overrides: 940 // Textfield, ui::SimpleMenuModel::Delegate overrides:
1003 941
1004 bool Textfield::IsCommandIdChecked(int command_id) const { 942 bool Textfield::IsCommandIdChecked(int command_id) const {
1005 return true; 943 return true;
1006 } 944 }
1007 945
1008 bool Textfield::IsCommandIdEnabled(int command_id) const { 946 bool Textfield::IsCommandIdEnabled(int command_id) const {
1009 base::string16 result; 947 base::string16 result;
1010 bool editable = !read_only(); 948 bool editable = !read_only();
949 bool readable = text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD;
1011 switch (command_id) { 950 switch (command_id) {
1012 case IDS_APP_UNDO: 951 case IDS_APP_UNDO:
1013 return editable && model_->CanUndo(); 952 return editable && model_->CanUndo();
1014 case IDS_APP_CUT: 953 case IDS_APP_CUT:
1015 return editable && model_->HasSelection() && !IsObscured(); 954 return editable && readable && model_->HasSelection();
1016 case IDS_APP_COPY: 955 case IDS_APP_COPY:
1017 return model_->HasSelection() && !IsObscured(); 956 return readable && model_->HasSelection();
1018 case IDS_APP_PASTE: 957 case IDS_APP_PASTE:
1019 ui::Clipboard::GetForCurrentThread()->ReadText( 958 ui::Clipboard::GetForCurrentThread()->ReadText(
1020 ui::CLIPBOARD_TYPE_COPY_PASTE, &result); 959 ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
1021 return editable && !result.empty(); 960 return editable && !result.empty();
1022 case IDS_APP_DELETE: 961 case IDS_APP_DELETE:
1023 return editable && model_->HasSelection(); 962 return editable && model_->HasSelection();
1024 case IDS_APP_SELECT_ALL: 963 case IDS_APP_SELECT_ALL:
1025 return !text().empty(); 964 return !text().empty();
1026 default: 965 default:
1027 return false; 966 return false;
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
1121 } 1060 }
1122 1061
1123 void Textfield::InsertText(const base::string16& new_text) { 1062 void Textfield::InsertText(const base::string16& new_text) {
1124 // TODO(suzhe): Filter invalid characters. 1063 // TODO(suzhe): Filter invalid characters.
1125 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || new_text.empty()) 1064 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || new_text.empty())
1126 return; 1065 return;
1127 1066
1128 OnBeforeUserAction(); 1067 OnBeforeUserAction();
1129 skip_input_method_cancel_composition_ = true; 1068 skip_input_method_cancel_composition_ = true;
1130 if (GetRenderText()->insert_mode()) 1069 if (GetRenderText()->insert_mode())
1131 model_->InsertText(GetTextForDisplay(new_text)); 1070 model_->InsertText(new_text);
1132 else 1071 else
1133 model_->ReplaceText(GetTextForDisplay(new_text)); 1072 model_->ReplaceText(new_text);
1134 skip_input_method_cancel_composition_ = false; 1073 skip_input_method_cancel_composition_ = false;
1135 UpdateAfterChange(true, true); 1074 UpdateAfterChange(true, true);
1136 OnAfterUserAction(); 1075 OnAfterUserAction();
1137 } 1076 }
1138 1077
1139 void Textfield::InsertChar(base::char16 ch, int flags) { 1078 void Textfield::InsertChar(base::char16 ch, int flags) {
1140 // Filter out all control characters, including tab and new line characters, 1079 // Filter out all control characters, including tab and new line characters,
1141 // and all characters with Alt modifier. But allow characters with the AltGr 1080 // and all characters with Alt modifier. But allow characters with the AltGr
1142 // modifier. On Windows AltGr is represented by Alt+Ctrl, and on Linux it's a 1081 // modifier. On Windows AltGr is represented by Alt+Ctrl, and on Linux it's a
1143 // different flag that we don't care about. 1082 // different flag that we don't care about.
1144 const bool should_insert_char = ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) && 1083 const bool should_insert_char = ((ch >= 0x20 && ch < 0x7F) || ch > 0x9F) &&
1145 (flags & ~(ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN)) != ui::EF_ALT_DOWN; 1084 (flags & ~(ui::EF_SHIFT_DOWN | ui::EF_CAPS_LOCK_DOWN)) != ui::EF_ALT_DOWN;
1146 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || !should_insert_char) 1085 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || !should_insert_char)
1147 return; 1086 return;
1148 1087
1149 OnBeforeUserAction(); 1088 OnBeforeUserAction();
1150 skip_input_method_cancel_composition_ = true; 1089 skip_input_method_cancel_composition_ = true;
1151 if (GetRenderText()->insert_mode()) 1090 if (GetRenderText()->insert_mode())
1152 model_->InsertChar(ch); 1091 model_->InsertChar(ch);
1153 else 1092 else
1154 model_->ReplaceChar(ch); 1093 model_->ReplaceChar(ch);
1155 skip_input_method_cancel_composition_ = false; 1094 skip_input_method_cancel_composition_ = false;
1156 1095
1157 model_->SetText(GetTextForDisplay(text()));
1158
1159 UpdateAfterChange(true, true); 1096 UpdateAfterChange(true, true);
1160 OnAfterUserAction(); 1097 OnAfterUserAction();
1161 1098
1162 if (IsObscured() && obscured_reveal_duration_ != base::TimeDelta()) { 1099 if (text_input_type_ == ui::TEXT_INPUT_TYPE_PASSWORD &&
1100 password_reveal_duration_ != base::TimeDelta()) {
1163 const size_t change_offset = model_->GetCursorPosition(); 1101 const size_t change_offset = model_->GetCursorPosition();
1164 DCHECK_GT(change_offset, 0u); 1102 DCHECK_GT(change_offset, 0u);
1165 RevealObscuredChar(change_offset - 1, obscured_reveal_duration_); 1103 RevealPasswordChar(change_offset - 1);
1166 } 1104 }
1167 } 1105 }
1168 1106
1169 gfx::NativeWindow Textfield::GetAttachedWindow() const { 1107 gfx::NativeWindow Textfield::GetAttachedWindow() const {
1170 // Imagine the following hierarchy. 1108 // Imagine the following hierarchy.
1171 // [NativeWidget A] - FocusManager 1109 // [NativeWidget A] - FocusManager
1172 // [View] 1110 // [View]
1173 // [NativeWidget B] 1111 // [NativeWidget B]
1174 // [View] 1112 // [View]
1175 // [View X] 1113 // [View X]
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
1328 //////////////////////////////////////////////////////////////////////////////// 1266 ////////////////////////////////////////////////////////////////////////////////
1329 // Textfield, protected: 1267 // Textfield, protected:
1330 1268
1331 gfx::RenderText* Textfield::GetRenderText() const { 1269 gfx::RenderText* Textfield::GetRenderText() const {
1332 return model_->render_text(); 1270 return model_->render_text();
1333 } 1271 }
1334 1272
1335 //////////////////////////////////////////////////////////////////////////////// 1273 ////////////////////////////////////////////////////////////////////////////////
1336 // Textfield, private: 1274 // Textfield, private:
1337 1275
1338 base::string16 Textfield::GetTextForDisplay(const base::string16& raw) {
1339 return style_ & Textfield::STYLE_LOWERCASE ? base::i18n::ToLower(raw) : raw;
1340 }
1341
1342 void Textfield::AccessibilitySetValue(const base::string16& new_value) { 1276 void Textfield::AccessibilitySetValue(const base::string16& new_value) {
1343 if (!read_only()) { 1277 if (!read_only()) {
1344 SetText(new_value); 1278 SetText(new_value);
1345 ClearSelection(); 1279 ClearSelection();
1346 } 1280 }
1347 } 1281 }
1348 1282
1349 void Textfield::UpdateBackgroundColor() { 1283 void Textfield::UpdateBackgroundColor() {
1350 const SkColor color = GetBackgroundColor(); 1284 const SkColor color = GetBackgroundColor();
1351 set_background(Background::CreateSolidBackground(color)); 1285 set_background(Background::CreateSolidBackground(color));
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1441 if (controller_) 1375 if (controller_)
1442 controller_->OnBeforeUserAction(this); 1376 controller_->OnBeforeUserAction(this);
1443 } 1377 }
1444 1378
1445 void Textfield::OnAfterUserAction() { 1379 void Textfield::OnAfterUserAction() {
1446 if (controller_) 1380 if (controller_)
1447 controller_->OnAfterUserAction(this); 1381 controller_->OnAfterUserAction(this);
1448 } 1382 }
1449 1383
1450 bool Textfield::Cut() { 1384 bool Textfield::Cut() {
1451 if (!read_only() && !IsObscured() && model_->Cut()) { 1385 if (!read_only() && text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD &&
1386 model_->Cut()) {
1452 if (controller_) 1387 if (controller_)
1453 controller_->OnAfterCutOrCopy(); 1388 controller_->OnAfterCutOrCopy();
1454 return true; 1389 return true;
1455 } 1390 }
1456 return false; 1391 return false;
1457 } 1392 }
1458 1393
1459 bool Textfield::Copy() { 1394 bool Textfield::Copy() {
1460 if (!IsObscured() && model_->Copy()) { 1395 if (text_input_type_ != ui::TEXT_INPUT_TYPE_PASSWORD && model_->Copy()) {
1461 if (controller_) 1396 if (controller_)
1462 controller_->OnAfterCutOrCopy(); 1397 controller_->OnAfterCutOrCopy();
1463 return true; 1398 return true;
1464 } 1399 }
1465 return false; 1400 return false;
1466 } 1401 }
1467 1402
1468 bool Textfield::Paste() { 1403 bool Textfield::Paste() {
1469 if (read_only()) 1404 if (!read_only() && model_->Paste()) {
1470 return false;
1471
1472 const base::string16 original_text = text();
1473 if (model_->Paste()) {
1474 // As Paste is handled in model_->Paste(), the RenderText may contain
1475 // upper case characters. This is not consistent with other places
1476 // which keeps RenderText only containing lower case characters.
1477 base::string16 new_text = GetTextForDisplay(text());
1478 model_->SetText(new_text);
1479 if (controller_) 1405 if (controller_)
1480 controller_->OnAfterPaste(); 1406 controller_->OnAfterPaste();
1481 return true; 1407 return true;
1482 } 1408 }
1483 return false; 1409 return false;
1484 } 1410 }
1485 1411
1486 void Textfield::UpdateContextMenu() { 1412 void Textfield::UpdateContextMenu() {
1487 if (!context_menu_contents_.get()) { 1413 if (!context_menu_contents_.get()) {
1488 context_menu_contents_.reset(new ui::SimpleMenuModel(this)); 1414 context_menu_contents_.reset(new ui::SimpleMenuModel(this));
(...skipping 28 matching lines...) Expand all
1517 last_click_location_ = event.location(); 1443 last_click_location_ = event.location();
1518 } 1444 }
1519 } 1445 }
1520 1446
1521 bool Textfield::ImeEditingAllowed() const { 1447 bool Textfield::ImeEditingAllowed() const {
1522 // Disallow input method editing of password fields. 1448 // Disallow input method editing of password fields.
1523 ui::TextInputType t = GetTextInputType(); 1449 ui::TextInputType t = GetTextInputType();
1524 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD); 1450 return (t != ui::TEXT_INPUT_TYPE_NONE && t != ui::TEXT_INPUT_TYPE_PASSWORD);
1525 } 1451 }
1526 1452
1527 void Textfield::RevealObscuredChar(int index, const base::TimeDelta& duration) { 1453 void Textfield::RevealPasswordChar(int index) {
1528 GetRenderText()->SetObscuredRevealIndex(index); 1454 GetRenderText()->SetObscuredRevealIndex(index);
1529 SchedulePaint(); 1455 SchedulePaint();
1530 1456
1531 if (index != -1) { 1457 if (index != -1) {
1532 obscured_reveal_timer_.Start(FROM_HERE, duration, 1458 password_reveal_timer_.Start(FROM_HERE, password_reveal_duration_,
1533 base::Bind(&Textfield::RevealObscuredChar, base::Unretained(this), 1459 base::Bind(&Textfield::RevealPasswordChar,
1534 -1, base::TimeDelta())); 1460 weak_ptr_factory_.GetWeakPtr(), -1));
1535 } 1461 }
1536 } 1462 }
1537 1463
1538 void Textfield::CreateTouchSelectionControllerAndNotifyIt() { 1464 void Textfield::CreateTouchSelectionControllerAndNotifyIt() {
1539 if (!touch_selection_controller_) { 1465 if (!touch_selection_controller_) {
1540 touch_selection_controller_.reset( 1466 touch_selection_controller_.reset(
1541 ui::TouchSelectionController::create(this)); 1467 ui::TouchSelectionController::create(this));
1542 } 1468 }
1543 if (touch_selection_controller_) 1469 if (touch_selection_controller_)
1544 touch_selection_controller_->SelectionChanged(); 1470 touch_selection_controller_->SelectionChanged();
1545 } 1471 }
1546 1472
1547 } // namespace views 1473 } // namespace views
OLDNEW
« no previous file with comments | « ui/views/controls/textfield/textfield.h ('k') | ui/views/controls/textfield/textfield_model_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698