OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |