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

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

Issue 9358049: Implement STYLE_LOWERCASE style for Aura NativeTextfield. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Refine the patch. Created 8 years, 10 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/native_textfield_views.h" 5 #include "ui/views/controls/textfield/native_textfield_views.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/debug/trace_event.h" 11 #include "base/debug/trace_event.h"
12 #include "base/i18n/case_conversion.h"
12 #include "base/logging.h" 13 #include "base/logging.h"
13 #include "base/message_loop.h" 14 #include "base/message_loop.h"
14 #include "base/utf_string_conversions.h" 15 #include "base/utf_string_conversions.h"
15 #include "grit/app_locale_settings.h" 16 #include "grit/app_locale_settings.h"
16 #include "grit/ui_strings.h" 17 #include "grit/ui_strings.h"
17 #include "ui/base/clipboard/clipboard.h" 18 #include "ui/base/clipboard/clipboard.h"
18 #include "ui/base/dragdrop/drag_drop_types.h" 19 #include "ui/base/dragdrop/drag_drop_types.h"
19 #include "ui/base/l10n/l10n_util.h" 20 #include "ui/base/l10n/l10n_util.h"
20 #include "ui/base/range/range.h" 21 #include "ui/base/range/range.h"
21 #include "ui/gfx/canvas.h" 22 #include "ui/gfx/canvas.h"
22 #include "ui/gfx/insets.h" 23 #include "ui/gfx/insets.h"
23 #include "ui/gfx/render_text.h" 24 #include "ui/gfx/render_text.h"
24 #include "ui/views/background.h" 25 #include "ui/views/background.h"
25 #include "ui/views/border.h" 26 #include "ui/views/border.h"
26 #include "ui/views/controls/focusable_border.h" 27 #include "ui/views/controls/focusable_border.h"
27 #include "ui/views/controls/menu/menu_item_view.h" 28 #include "ui/views/controls/menu/menu_item_view.h"
28 #include "ui/views/controls/menu/menu_model_adapter.h" 29 #include "ui/views/controls/menu/menu_model_adapter.h"
29 #include "ui/views/controls/menu/menu_runner.h" 30 #include "ui/views/controls/menu/menu_runner.h"
30 #include "ui/views/controls/textfield/textfield.h" 31 #include "ui/views/controls/textfield/textfield.h"
31 #include "ui/views/controls/textfield/textfield_controller.h" 32 #include "ui/views/controls/textfield/textfield_controller.h"
32 #include "ui/views/controls/textfield/textfield_views_model.h" 33 #include "ui/views/controls/textfield/textfield_views_model.h"
33 #include "ui/views/events/event.h" 34 #include "ui/views/events/event.h"
34 #include "ui/views/ime/input_method.h" 35 #include "ui/views/ime/input_method.h"
35 #include "ui/views/metrics.h" 36 #include "ui/views/metrics.h"
36 #include "ui/views/views_delegate.h" 37 #include "ui/views/views_delegate.h"
37 #include "ui/views/widget/widget.h" 38 #include "ui/views/widget/widget.h"
39 #include "unicode/uchar.h"
38 40
39 #if defined(OS_LINUX) 41 #if defined(OS_LINUX)
40 #include "ui/gfx/gtk_util.h" 42 #include "ui/gfx/gtk_util.h"
41 #endif 43 #endif
42 44
43 #if defined(USE_AURA) 45 #if defined(USE_AURA)
44 #include "ui/aura/cursor.h" 46 #include "ui/aura/cursor.h"
45 #endif 47 #endif
46 48
47 namespace { 49 namespace {
(...skipping 21 matching lines...) Expand all
69 skip_input_method_cancel_composition_(false), 71 skip_input_method_cancel_composition_(false),
70 initiating_drag_(false), 72 initiating_drag_(false),
71 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)), 73 ALLOW_THIS_IN_INITIALIZER_LIST(cursor_timer_(this)),
72 aggregated_clicks_(0), 74 aggregated_clicks_(0),
73 last_click_time_(), 75 last_click_time_(),
74 last_click_location_(), 76 last_click_location_(),
75 ALLOW_THIS_IN_INITIALIZER_LIST(touch_selection_controller_( 77 ALLOW_THIS_IN_INITIALIZER_LIST(touch_selection_controller_(
76 TouchSelectionController::create(this))) { 78 TouchSelectionController::create(this))) {
77 set_border(text_border_); 79 set_border(text_border_);
78 80
79 // Lowercase is not supported.
80 DCHECK_NE(parent->style(), Textfield::STYLE_LOWERCASE);
81
82 #if defined(OS_CHROMEOS) 81 #if defined(OS_CHROMEOS)
83 GetRenderText()->SetFontList(gfx::FontList(l10n_util::GetStringUTF8( 82 GetRenderText()->SetFontList(gfx::FontList(l10n_util::GetStringUTF8(
84 IDS_UI_FONT_FAMILY_CROS))); 83 IDS_UI_FONT_FAMILY_CROS)));
85 #else 84 #else
86 GetRenderText()->SetFontList(gfx::FontList(textfield_->font())); 85 GetRenderText()->SetFontList(gfx::FontList(textfield_->font()));
87 #endif 86 #endif
88 // Set the default text style. 87 // Set the default text style.
89 gfx::StyleRange default_style; 88 gfx::StyleRange default_style;
90 default_style.foreground = textfield_->text_color(); 89 default_style.foreground = textfield_->text_color();
91 GetRenderText()->set_default_style(default_style); 90 GetRenderText()->set_default_style(default_style);
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 DCHECK(!initiating_drag_ || 183 DCHECK(!initiating_drag_ ||
185 !GetRenderText()->IsPointInSelection(event.location())); 184 !GetRenderText()->IsPointInSelection(event.location()));
186 OnBeforeUserAction(); 185 OnBeforeUserAction();
187 skip_input_method_cancel_composition_ = true; 186 skip_input_method_cancel_composition_ = true;
188 187
189 // TODO(msw): Remove final reference to FindCursorPosition. 188 // TODO(msw): Remove final reference to FindCursorPosition.
190 gfx::SelectionModel drop_destination = 189 gfx::SelectionModel drop_destination =
191 GetRenderText()->FindCursorPosition(event.location()); 190 GetRenderText()->FindCursorPosition(event.location());
192 string16 text; 191 string16 text;
193 event.data().GetString(&text); 192 event.data().GetString(&text);
193 if (textfield_->style() & Textfield::STYLE_LOWERCASE)
194 text = base::i18n::ToLower(text);
xji 2012/02/17 22:38:24 I think we should do language specific case mappin
kochi 2012/02/23 10:49:07 According to the header file, ToLower uses Unicode
xji 2012/02/23 21:59:17 You are right! sorry for the false alarm.
194 195
195 // We'll delete the current selection for a drag and drop within this view. 196 // We'll delete the current selection for a drag and drop within this view.
196 bool move = initiating_drag_ && !event.IsControlDown() && 197 bool move = initiating_drag_ && !event.IsControlDown() &&
197 event.source_operations() & ui::DragDropTypes::DRAG_MOVE; 198 event.source_operations() & ui::DragDropTypes::DRAG_MOVE;
198 if (move) { 199 if (move) {
199 gfx::SelectionModel selected; 200 gfx::SelectionModel selected;
200 model_->GetSelectionModel(&selected); 201 model_->GetSelectionModel(&selected);
201 // Adjust the drop destination if it is on or after the current selection. 202 // Adjust the drop destination if it is on or after the current selection.
202 size_t max_of_selected_range = std::max(selected.selection_start(), 203 size_t max_of_selected_range = std::max(selected.selection_start(),
203 selected.selection_end()); 204 selected.selection_end());
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
323 } 324 }
324 325
325 ///////////////////////////////////////////////////////////////// 326 /////////////////////////////////////////////////////////////////
326 // NativeTextfieldViews, NativeTextifieldWrapper overrides: 327 // NativeTextfieldViews, NativeTextifieldWrapper overrides:
327 328
328 string16 NativeTextfieldViews::GetText() const { 329 string16 NativeTextfieldViews::GetText() const {
329 return model_->GetText(); 330 return model_->GetText();
330 } 331 }
331 332
332 void NativeTextfieldViews::UpdateText() { 333 void NativeTextfieldViews::UpdateText() {
333 model_->SetText(textfield_->text()); 334 string16 text = textfield_->text();
335 if (textfield_->style() & Textfield::STYLE_LOWERCASE)
336 text = base::i18n::ToLower(text);
337 model_->SetText(text);
334 OnCaretBoundsChanged(); 338 OnCaretBoundsChanged();
335 SchedulePaint(); 339 SchedulePaint();
336 textfield_->GetWidget()->NotifyAccessibilityEvent( 340 textfield_->GetWidget()->NotifyAccessibilityEvent(
337 textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true); 341 textfield_, ui::AccessibilityTypes::EVENT_TEXT_CHANGED, true);
338 } 342 }
339 343
340 void NativeTextfieldViews::AppendText(const string16& text) { 344 void NativeTextfieldViews::AppendText(const string16& text) {
341 if (text.empty()) 345 if (text.empty())
342 return; 346 return;
343 model_->Append(text); 347 if (textfield_->style() & Textfield::STYLE_LOWERCASE)
348 model_->Append(base::i18n::ToLower(text));
349 else
350 model_->Append(text);
344 OnCaretBoundsChanged(); 351 OnCaretBoundsChanged();
345 SchedulePaint(); 352 SchedulePaint();
346 } 353 }
347 354
348 string16 NativeTextfieldViews::GetSelectedText() const { 355 string16 NativeTextfieldViews::GetSelectedText() const {
349 return model_->GetSelectedText(); 356 return model_->GetSelectedText();
350 } 357 }
351 358
352 void NativeTextfieldViews::SelectAll() { 359 void NativeTextfieldViews::SelectAll() {
353 OnBeforeUserAction(); 360 OnBeforeUserAction();
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 OnAfterUserAction(); 674 OnAfterUserAction();
668 } 675 }
669 676
670 void NativeTextfieldViews::InsertText(const string16& text) { 677 void NativeTextfieldViews::InsertText(const string16& text) {
671 // TODO(suzhe): Filter invalid characters. 678 // TODO(suzhe): Filter invalid characters.
672 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || text.empty()) 679 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || text.empty())
673 return; 680 return;
674 681
675 OnBeforeUserAction(); 682 OnBeforeUserAction();
676 skip_input_method_cancel_composition_ = true; 683 skip_input_method_cancel_composition_ = true;
684
685 string16 new_text = text;
686 if (textfield_->style() & Textfield::STYLE_LOWERCASE)
687 new_text = base::i18n::ToLower(new_text);
xji 2012/02/17 22:38:24 nit: string16 new_text = (textfield_->style() & Te
msw 2012/02/18 00:32:38 why not just reassign to text? new_text seems redu
xji 2012/02/18 01:33:38 |text| is a 'const'.
kochi 2012/02/23 10:49:07 Done.
kochi 2012/02/23 10:49:07 Yes, that's right. On 2012/02/18 01:33:38, xji wr
688
677 if (GetRenderText()->insert_mode()) 689 if (GetRenderText()->insert_mode())
678 model_->InsertText(text); 690 model_->InsertText(new_text);
679 else 691 else
680 model_->ReplaceText(text); 692 model_->ReplaceText(new_text);
681 skip_input_method_cancel_composition_ = false; 693 skip_input_method_cancel_composition_ = false;
682 UpdateAfterChange(true, true); 694 UpdateAfterChange(true, true);
683 OnAfterUserAction(); 695 OnAfterUserAction();
684 } 696 }
685 697
686 void NativeTextfieldViews::InsertChar(char16 ch, int flags) { 698 void NativeTextfieldViews::InsertChar(char16 ch, int flags) {
687 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE || 699 if (GetTextInputType() == ui::TEXT_INPUT_TYPE_NONE ||
688 !ShouldInsertChar(ch, flags)) { 700 !ShouldInsertChar(ch, flags)) {
689 return; 701 return;
690 } 702 }
691 703
704 if (textfield_->style() & Textfield::STYLE_LOWERCASE)
705 ch = u_tolower(ch);
msw 2012/02/18 00:32:38 You should ensure this does the language specific
kochi 2012/02/23 10:49:07 This one doesn't seem to handle language-specific
706
692 OnBeforeUserAction(); 707 OnBeforeUserAction();
693 skip_input_method_cancel_composition_ = true; 708 skip_input_method_cancel_composition_ = true;
694 if (GetRenderText()->insert_mode()) 709 if (GetRenderText()->insert_mode())
695 model_->InsertChar(ch); 710 model_->InsertChar(ch);
696 else 711 else
697 model_->ReplaceChar(ch); 712 model_->ReplaceChar(ch);
698 skip_input_method_cancel_composition_ = false; 713 skip_input_method_cancel_composition_ = false;
699 UpdateAfterChange(true, true); 714 UpdateAfterChange(true, true);
700 OnAfterUserAction(); 715 OnAfterUserAction();
701 } 716 }
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
1036 if (controller) 1051 if (controller)
1037 controller->OnAfterCutOrCopy(); 1052 controller->OnAfterCutOrCopy();
1038 return true; 1053 return true;
1039 } 1054 }
1040 return false; 1055 return false;
1041 } 1056 }
1042 1057
1043 bool NativeTextfieldViews::Paste() { 1058 bool NativeTextfieldViews::Paste() {
1044 const bool success = model_->Paste(); 1059 const bool success = model_->Paste();
1045 1060
1061 if (textfield_->style() & Textfield::STYLE_LOWERCASE) {
1062 string16 text = model_->GetText();
1063 text = base::i18n::ToLower(text);
1064 model_->SetText(text);
1065 }
xji 2012/02/17 22:38:24 this should not be needed since model_->GetText()
kochi 2012/02/23 10:49:07 The model directly gets the text from clipboard in
xji 2012/02/23 21:59:17 Ah, I see. I thought RenderText will always keep a
kochi 2012/04/09 06:34:20 OK, I agree this is not intuitive to understand. A
1066
1046 // Calls TextfieldController::ContentsChanged() explicitly if the paste action 1067 // Calls TextfieldController::ContentsChanged() explicitly if the paste action
1047 // did not change the content at all. See http://crbug.com/79002 1068 // did not change the content at all. See http://crbug.com/79002
1048 if (success && GetText() == textfield_->text()) { 1069 if (success && GetText() == textfield_->text()) {
xji 2012/02/17 22:38:24 In case of STYLE_LOWERCASE, GetText() is lower-cas
kochi 2012/02/23 10:49:07 Right, will fix this.
kochi 2012/04/09 06:34:20 Ah, no. GetText() in this class is just does mode
xji 2012/04/10 22:53:27 GetText() is lower-cased. But isn't textfield_->te
kochi 2012/04/11 01:56:41 I see, sorry for misunderstanding again. Done. On
1049 TextfieldController* controller = textfield_->GetController(); 1070 TextfieldController* controller = textfield_->GetController();
1050 if (controller) 1071 if (controller)
1051 controller->ContentsChanged(textfield_, textfield_->text()); 1072 controller->ContentsChanged(textfield_, textfield_->text());
1052 } 1073 }
1053 return success; 1074 return success;
1054 } 1075 }
1055 1076
1056 void NativeTextfieldViews::TrackMouseClicks(const MouseEvent& event) { 1077 void NativeTextfieldViews::TrackMouseClicks(const MouseEvent& event) {
1057 if (event.IsOnlyLeftMouseButton()) { 1078 if (event.IsOnlyLeftMouseButton()) {
1058 base::TimeDelta time_delta = event.time_stamp() - last_click_time_; 1079 base::TimeDelta time_delta = event.time_stamp() - last_click_time_;
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1117 1138
1118 #if defined(USE_AURA) 1139 #if defined(USE_AURA)
1119 // static 1140 // static
1120 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper( 1141 NativeTextfieldWrapper* NativeTextfieldWrapper::CreateWrapper(
1121 Textfield* field) { 1142 Textfield* field) {
1122 return new NativeTextfieldViews(field); 1143 return new NativeTextfieldViews(field);
1123 } 1144 }
1124 #endif 1145 #endif
1125 1146
1126 } // namespace views 1147 } // namespace views
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698