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

Side by Side Diff: chrome/browser/autocomplete/autocomplete_edit_view_views.cc

Issue 6245003: Views-implementation of AutocompleteEditView (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: " Created 9 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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/autocomplete/autocomplete_edit_view_views.h"
6
7 #include "app/l10n_util.h"
8 #include "base/logging.h"
9 #include "base/string_util.h"
10 #include "base/utf_string_conversions.h"
11 #include "chrome/app/chrome_command_ids.h"
12 #include "chrome/browser/autocomplete/autocomplete_edit.h"
13 #include "chrome/browser/autocomplete/autocomplete_match.h"
14 #include "chrome/browser/autocomplete/autocomplete_popup_model.h"
15 #include "chrome/browser/command_updater.h"
16 #include "chrome/browser/tab_contents/tab_contents.h"
17 #include "chrome/browser/ui/views/autocomplete/autocomplete_popup_contents_view. h"
18 #include "chrome/browser/ui/views/location_bar/location_bar_view.h"
19 #include "chrome/common/notification_service.h"
20 #include "gfx/font.h"
21 #include "googleurl/src/gurl.h"
22 #include "grit/generated_resources.h"
23 #include "net/base/escape.h"
24 #include "views/border.h"
25 #include "views/fill_layout.h"
26
27 namespace {
28
29 // Textfield for autocomplete that intercepts events that are necessary
30 // for AutocompleteEditViewViews.
31 class AutocompleteTextfield : public views::Textfield {
32 public:
33 explicit AutocompleteTextfield(
34 AutocompleteEditViewViews* autocomplete_edit_view)
35 : views::Textfield(views::Textfield::STYLE_DEFAULT),
36 autocomplete_edit_view_(autocomplete_edit_view) {
37 DCHECK(autocomplete_edit_view_);
38 RemoveBorder();
39 }
40
41 // views::View implementation
42 virtual void DidGainFocus() {
43 views::Textfield::DidGainFocus();
44 autocomplete_edit_view_->HandleFocusIn();
45 }
46
47 virtual void WillLoseFocus() {
48 views::Textfield::WillLoseFocus();
49 autocomplete_edit_view_->HandleFocusOut();
50 }
51
52 virtual bool OnKeyPressed(const views::KeyEvent& e) {
53 bool handled = views::Textfield::OnKeyPressed(e);
54 return autocomplete_edit_view_->HandleAfterKeyEvent(e, handled) || handled;
55 }
56
57 virtual bool OnKeyReleased(const views::KeyEvent& e) {
58 return autocomplete_edit_view_->HandleKeyReleaseEvent(e);
59 }
60
61 virtual bool IsFocusable() const {
62 // Bypass Textfield::IsFocusable. The omnibox in popup window requires
63 // focus in order for text selection to work.
64 return views::View::IsFocusable();
65 }
66
67 private:
68 AutocompleteEditViewViews* autocomplete_edit_view_;
69
70 DISALLOW_COPY_AND_ASSIGN(AutocompleteTextfield);
71 };
72
73 // Stores omnibox state for each tab.
74 struct ViewState {
75 explicit ViewState(const views::TextRange& selection_range)
76 : selection_range(selection_range) {
77 }
78
79 // Range of selected text.
80 views::TextRange selection_range;
81 };
82
83 struct AutocompleteEditState {
84 AutocompleteEditState(const AutocompleteEditModel::State& model_state,
85 const ViewState& view_state)
86 : model_state(model_state),
87 view_state(view_state) {
88 }
89
90 const AutocompleteEditModel::State model_state;
91 const ViewState view_state;
92 };
93
94 // Returns a lazily initialized property bag accessor for saving our state in a
95 // TabContents.
96 PropertyAccessor<AutocompleteEditState>* GetStateAccessor() {
97 static PropertyAccessor<AutocompleteEditState> state;
98 return &state;
99 }
100
101 const int kAutocompleteVerticalMargin = 4;
102
103 } // namespace
104
105 AutocompleteEditViewViews::AutocompleteEditViewViews(
106 AutocompleteEditController* controller,
107 ToolbarModel* toolbar_model,
108 Profile* profile,
109 CommandUpdater* command_updater,
110 bool popup_window_mode,
111 const views::View* location_bar)
112 : model_(new AutocompleteEditModel(this, controller, profile)),
113 popup_view_(new AutocompletePopupContentsView(
114 gfx::Font(), this, model_.get(), profile, location_bar)),
115 controller_(controller),
116 toolbar_model_(toolbar_model),
117 command_updater_(command_updater),
118 popup_window_mode_(popup_window_mode),
119 security_level_(ToolbarModel::NONE),
120 delete_was_pressed_(false),
121 delete_at_end_pressed_(false) {
122 model_->SetPopupModel(popup_view_->GetModel());
123 set_border(views::Border::CreateEmptyBorder(kAutocompleteVerticalMargin,
Peter Kasting 2011/01/20 19:44:37 Nit: Just put the zeros on the ends of the other t
oshima 2011/01/20 21:35:48 Done.
124 0,
125 kAutocompleteVerticalMargin,
126 0));
127 }
128
129 AutocompleteEditViewViews::~AutocompleteEditViewViews() {
130 NotificationService::current()->Notify(
131 NotificationType::AUTOCOMPLETE_EDIT_DESTROYED,
132 Source<AutocompleteEditViewViews>(this),
133 NotificationService::NoDetails());
134 // Explicitly teardown members which have a reference to us. Just to be safe
135 // we want them to be destroyed before destroying any other internal state.
136 popup_view_.reset();
137 model_.reset();
138 }
139
140 ////////////////////////////////////////////////////////////////////////////////
141 // AutocompleteEditViewViews public:
142
143 void AutocompleteEditViewViews::Init() {
144 // The height of the text view is going to change based on the font used. We
145 // don't want to stretch the height, and we want it vertically centered.
146 // TODO(oshima): make sure the above happens with views.
147 textfield_ = new AutocompleteTextfield(this);
148 textfield_->SetController(this);
149
150 if (popup_window_mode_)
151 textfield_->SetReadOnly(true);
152
153 // Manually invoke SetBaseColor() because TOOLKIT_VIEWS doesn't observe
154 // themes.
155 SetBaseColor();
156 }
157
158 void AutocompleteEditViewViews::SetBaseColor() {
159 // TODO(oshima): Implment style change.
160 NOTIMPLEMENTED();
161 }
162
163 bool AutocompleteEditViewViews::HandleAfterKeyEvent(
164 const views::KeyEvent& event,
165 bool handled) {
166 handling_key_press_ = false;
167 if (content_maybe_changed_by_key_press_)
168 OnAfterPossibleChange();
169
170 if (event.GetKeyCode() == ui::VKEY_RETURN) {
171 bool alt_held = event.IsAltDown();
172 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false);
173 handled = true;
174 } else if (!handled && event.GetKeyCode() == ui::VKEY_ESCAPE) {
175 // We can handle the Escape key if textfield did not handle it.
176 // If it's not handled by us, then we need to propagate it up to the parent
177 // widgets, so that Escape accelerator can still work.
178 handled = model_->OnEscapeKeyPressed();
179 } else if (event.GetKeyCode() == ui::VKEY_CONTROL) {
180 // Omnibox2 can switch its contents while pressing a control key. To switch
181 // the contents of omnibox2, we notify the AutocompleteEditModel class when
182 // the control-key state is changed.
183 model_->OnControlKeyChanged(true);
184 } else if (!text_changed_ && event.GetKeyCode() == ui::VKEY_DELETE &&
185 event.IsShiftDown()) {
186 // If shift+del didn't change the text, we let this delete an entry from
187 // the popup. We can't check to see if the IME handled it because even if
188 // nothing is selected, the IME or the TextView still report handling it.
189 AutocompletePopupModel* popup_model = popup_view_->GetModel();
190 if (popup_model->IsOpen())
191 popup_model->TryDeletingCurrentItem();
192 } else if (!handled && event.GetKeyCode() == ui::VKEY_UP) {
193 model_->OnUpOrDownKeyPressed(-1);
194 handled = true;
195 } else if (!handled && event.GetKeyCode() == ui::VKEY_DOWN) {
196 model_->OnUpOrDownKeyPressed(1);
197 handled = true;
198 } else if (!handled &&
199 event.GetKeyCode() == ui::VKEY_TAB &&
200 !event.IsShiftDown() &&
201 !event.IsControlDown()) {
202 if (model_->is_keyword_hint() && !model_->keyword().empty()) {
203 model_->AcceptKeyword();
204 handled = true;
205 } else {
206 // TODO(Oshima): handle instant
207 }
208 }
209 // TODO(oshima): page up & down
210
211 return handled;
212 }
213
214 bool AutocompleteEditViewViews::HandleKeyReleaseEvent(
215 const views::KeyEvent& event) {
216 // Omnibox2 can switch its contents while pressing a control key. To switch
217 // the contents of omnibox2, we notify the AutocompleteEditModel class when
218 // the control-key state is changed.
219 if (event.GetKeyCode() == ui::VKEY_CONTROL) {
220 // TODO(oshima): investigate if we need to support keyboard with two
221 // controls. See autocomplete_edit_view_gtk.cc.
222 model_->OnControlKeyChanged(false);
223 return true;
224 }
225 return false;
226 }
227
228 void AutocompleteEditViewViews::HandleFocusIn() {
229 // TODO(oshima): Get control key state.
230 model_->OnSetFocus(false);
231 // Don't call controller_->OnSetFocus as this view has already
232 // acquired the focus.
233 }
234
235 void AutocompleteEditViewViews::HandleFocusOut() {
236 // TODO(oshima): we don't have native view. This requires
237 // further refactoring.
238 controller_->OnAutocompleteLosingFocus(NULL);
239 // Close the popup.
240 ClosePopup();
241 // Tell the model to reset itself.
242 model_->OnKillFocus();
243 controller_->OnKillFocus();
244 }
245
246 ////////////////////////////////////////////////////////////////////////////////
247 // AutocompleteEditViewViews, views::View implementation:
248
249 bool AutocompleteEditViewViews::OnMousePressed(
250 const views::MouseEvent& event) {
251 if (event.IsLeftMouseButton()) {
252 // Button press event may change the selection, we need to record the change
253 // and report it to |model_| later when button is released.
254 OnBeforePossibleChange();
255 }
256 // pass the event through to TextfieldViews.
Peter Kasting 2011/01/20 19:44:37 Nit: pass -> Pass
oshima 2011/01/20 21:35:48 Done.
257 return false;
258 }
259
260 ////////////////////////////////////////////////////////////////////////////////
261 // AutocompleteEditViewViews, AutocopmleteEditView implementation:
262
263 AutocompleteEditModel* AutocompleteEditViewViews::model() {
264 return model_.get();
265 }
266
267 const AutocompleteEditModel* AutocompleteEditViewViews::model() const {
268 return model_.get();
269 }
270
271 void AutocompleteEditViewViews::SaveStateToTab(TabContents* tab) {
272 DCHECK(tab);
273
274 // NOTE: GetStateForTabSwitch may affect GetSelection, so order is important.
275 AutocompleteEditModel::State model_state = model_->GetStateForTabSwitch();
276 views::TextRange selection;
277 textfield_->GetSelectedRange(&selection);
278 GetStateAccessor()->SetProperty(
279 tab->property_bag(),
280 AutocompleteEditState(model_state, ViewState(selection)));
281 }
282
283 void AutocompleteEditViewViews::Update(const TabContents* contents) {
284 // NOTE: We're getting the URL text here from the ToolbarModel.
285 bool visibly_changed_permanent_text =
286 model_->UpdatePermanentText(toolbar_model_->GetText());
287
288 ToolbarModel::SecurityLevel security_level =
289 toolbar_model_->GetSecurityLevel();
290 bool changed_security_level = (security_level != security_level_);
291 security_level_ = security_level;
292
293 // TODO(oshima): Copied from gtk implementation which is
294 // slightly different from WIN impl. Find out the correct implementation
295 // for views-implementation.
296 if (contents) {
297 RevertAll();
298 const AutocompleteEditState* state =
299 GetStateAccessor()->GetProperty(contents->property_bag());
300 if (state) {
301 model_->RestoreState(state->model_state);
302
303 // Move the marks for the cursor and the other end of the selection to
304 // the previously-saved offsets (but preserve PRIMARY).
305 textfield_->SelectRange(state->view_state.selection_range);
306 }
307 } else if (visibly_changed_permanent_text) {
308 RevertAll();
309 } else if (changed_security_level) {
310 EmphasizeURLComponents();
311 }
312 }
313
314 void AutocompleteEditViewViews::OpenURL(const GURL& url,
315 WindowOpenDisposition disposition,
316 PageTransition::Type transition,
317 const GURL& alternate_nav_url,
318 size_t selected_line,
319 const std::wstring& keyword) {
320 if (!url.is_valid())
321 return;
322
323 model_->OpenURL(url, disposition, transition, alternate_nav_url,
324 selected_line, keyword);
325 }
326
327 std::wstring AutocompleteEditViewViews::GetText() const {
328 // TODO(oshima): IME support
329 return UTF16ToWide(textfield_->text());
330 }
331
332 bool AutocompleteEditViewViews::IsEditingOrEmpty() const {
333 return model_->user_input_in_progress() || (GetTextLength() == 0);
334 }
335
336 int AutocompleteEditViewViews::GetIcon() const {
337 return IsEditingOrEmpty() ?
338 AutocompleteMatch::TypeToIcon(model_->CurrentTextType()) :
339 toolbar_model_->GetIcon();
340 }
341
342 void AutocompleteEditViewViews::SetUserText(const std::wstring& text) {
343 SetUserText(text, text, true);
344 }
345
346 void AutocompleteEditViewViews::SetUserText(const std::wstring& text,
347 const std::wstring& display_text,
348 bool update_popup) {
349 model_->SetUserText(text);
350 SetWindowTextAndCaretPos(display_text, display_text.length());
351 if (update_popup)
352 UpdatePopup();
353 TextChanged();
354 }
355
356 void AutocompleteEditViewViews::SetWindowTextAndCaretPos(
357 const std::wstring& text,
358 size_t caret_pos) {
359 const views::TextRange range(caret_pos, caret_pos);
360 SetTextAndSelectedRange(text, range);
361 }
362
363 void AutocompleteEditViewViews::SetForcedQuery() {
364 const std::wstring current_text(GetText());
365 const size_t start = current_text.find_first_not_of(kWhitespaceWide);
366 if (start == std::wstring::npos || (current_text[start] != '?')) {
367 SetUserText(L"?");
368 } else {
369 SelectRange(current_text.size(), start + 1);
370 }
371 }
372
373 bool AutocompleteEditViewViews::IsSelectAll() {
374 // TODO(oshima): IME support.
375 return textfield_->text() == textfield_->GetSelectedText();
376 }
377
378 bool AutocompleteEditViewViews::DeleteAtEndPressed() {
379 return delete_at_end_pressed_;
380 }
381
382 void AutocompleteEditViewViews::GetSelectionBounds(
383 std::wstring::size_type* start,
384 std::wstring::size_type* end) {
385 views::TextRange range;
386 textfield_->GetSelectedRange(&range);
387 // TODO(oshima):
388 // gtk imlp uses bounds (end) as start and caret (start) as end and
Peter Kasting 2011/01/20 19:44:37 Nit: This comment can go away now, right?
oshima 2011/01/20 21:35:48 Done.
389 // win's behavior seem to be the same. Figure out why and fix if necessary.
390 *start = static_cast<size_t>(range.end());
391 *end = static_cast<size_t>(range.start());
392 }
393
394 void AutocompleteEditViewViews::SelectAll(bool reversed) {
395 if (reversed) {
Peter Kasting 2011/01/20 19:44:37 Nit: No {}
oshima 2011/01/20 21:35:48 Done.
396 SelectRange(GetTextLength(), 0);
397 } else {
398 SelectRange(0, GetTextLength());
399 }
400 }
401
402 void AutocompleteEditViewViews::RevertAll() {
403 ClosePopup();
404 model_->Revert();
405 TextChanged();
406 }
407
408 void AutocompleteEditViewViews::UpdatePopup() {
409 model_->SetInputInProgress(true);
410 if (!model_->has_focus())
411 return;
412
413 // Don't inline autocomplete when the caret/selection isn't at the end of
414 // the text, or in the middle of composition.
415 views::TextRange sel;
416 textfield_->GetSelectedRange(&sel);
417 bool no_inline_autocomplete = sel.GetMax() < GetTextLength();
418
419 // TODO(oshima): Support IME. Don't show autocomplete if IME has some text.
420 model_->StartAutocomplete(!sel.is_empty(), no_inline_autocomplete);
421 }
422
423 void AutocompleteEditViewViews::ClosePopup() {
424 if (popup_view_->GetModel()->IsOpen())
425 controller_->OnAutocompleteWillClosePopup();
426
427 popup_view_->GetModel()->StopAutocomplete();
428 }
429
430 void AutocompleteEditViewViews::SetFocus() {
431 // In views-implementation, the focus is on textfield rather than
432 // AutocompleteEditView.
433 textfield_->RequestFocus();
434 }
435
436 void AutocompleteEditViewViews::OnTemporaryTextMaybeChanged(
437 const std::wstring& display_text,
438 bool save_original_selection) {
439 if (save_original_selection)
440 textfield_->GetSelectedRange(&saved_temporary_selection_);
441
442 SetWindowTextAndCaretPos(display_text, display_text.length());
443 TextChanged();
444 }
445
446 bool AutocompleteEditViewViews::OnInlineAutocompleteTextMaybeChanged(
447 const std::wstring& display_text,
448 size_t user_text_length) {
449 if (display_text == GetText())
450 return false;
451 views::TextRange range(display_text.size(), user_text_length);
452 SetTextAndSelectedRange(display_text, range);
453 TextChanged();
454 return true;
455 }
456
457 void AutocompleteEditViewViews::OnRevertTemporaryText() {
458 textfield_->SelectRange(saved_temporary_selection_);
459 TextChanged();
460 }
461
462 void AutocompleteEditViewViews::OnBeforePossibleChange() {
463 // Record our state.
464 text_before_change_ = GetText();
465 textfield_->GetSelectedRange(&sel_before_change_);
466 }
467
468 bool AutocompleteEditViewViews::OnAfterPossibleChange() {
469 // OnAfterPossibleChange should be called once per modification,
470 // and we should ignore if this is called while a key event is being handled
471 // because OnAfterPossibleChagne will be called after the key event is
472 // actually handled.
473 if (handling_key_press_) {
474 content_maybe_changed_by_key_press_ = true;
475 return false;
476 }
477 views::TextRange new_sel;
478 textfield_->GetSelectedRange(&new_sel);
479
480 size_t length = GetTextLength();
481 bool at_end_of_edit = (new_sel.start() == length && new_sel.end() == length);
482
483 // See if the text or selection have changed since OnBeforePossibleChange().
484 std::wstring new_text = GetText();
485 text_changed_ = (new_text != text_before_change_);
486 bool selection_differs = !sel_before_change_.Equals(new_sel);
487
488 // When the user has deleted text, we don't allow inline autocomplete. Make
489 // sure to not flag cases like selecting part of the text and then pasting
490 // (or typing) the prefix of that selection. (We detect these by making
491 // sure the caret, which should be after any insertion, hasn't moved
492 // forward of the old selection start.)
493 bool just_deleted_text =
494 (text_before_change_.length() > new_text.length()) &&
495 (new_sel.start() <= sel_before_change_.GetMin());
496
497 delete_at_end_pressed_ = false;
498
499 bool something_changed = model_->OnAfterPossibleChange(new_text,
500 selection_differs, text_changed_, just_deleted_text, at_end_of_edit);
501
502 // If only selection was changed, we don't need to call |controller_|'s
503 // OnChanged() method, which is called in TextChanged().
504 // But we still need to call EmphasizeURLComponents() to make sure the text
505 // attributes are updated correctly.
506 if (something_changed && text_changed_) {
507 TextChanged();
508 } else if (selection_differs) {
509 EmphasizeURLComponents();
510 } else if (delete_was_pressed_ && at_end_of_edit) {
511 delete_at_end_pressed_ = true;
512 controller_->OnChanged();
513 }
514 delete_was_pressed_ = false;
515
516 return something_changed;
517 }
518
519 gfx::NativeView AutocompleteEditViewViews::GetNativeView() const {
520 return GetWidget()->GetNativeView();
521 }
522
523 CommandUpdater* AutocompleteEditViewViews::GetCommandUpdater() {
524 return command_updater_;
525 }
526
527 views::View* AutocompleteEditViewViews::AddToView(views::View* parent) {
528 parent->AddChildView(this);
529 AddChildView(textfield_);
530 SetLayoutManager(new views::FillLayout(true /* exlucde insets*/));
531 return this;
532 }
533
534 int AutocompleteEditViewViews::TextWidth() const {
535 // TODO(oshima): add horizontal margin.
536 return textfield_->font().GetStringWidth(textfield_->text());
537 }
538
539 bool AutocompleteEditViewViews::IsImeComposing() const {
540 return false;
541 }
542
543 bool AutocompleteEditViewViews::CommitInstantSuggestion(
544 const std::wstring& typed_text,
545 const std::wstring& suggested_text) {
546 model_->FinalizeInstantQuery(typed_text, suggested_text);
547 return true;
548 }
549
550 void AutocompleteEditViewViews::SetInstantSuggestion(const string16& input) {
551 NOTIMPLEMENTED();
552 }
553
554 ////////////////////////////////////////////////////////////////////////////////
555 // AutocompleteEditViewViews, NotificationObserver implementation:
556
557 void AutocompleteEditViewViews::Observe(NotificationType type,
558 const NotificationSource& source,
559 const NotificationDetails& details) {
560 DCHECK(type == NotificationType::BROWSER_THEME_CHANGED);
561 SetBaseColor();
562 }
563
564 ////////////////////////////////////////////////////////////////////////////////
565 // AutocompleteEditViewViews, Textfield::Controller implementation:
566
567 void AutocompleteEditViewViews::ContentsChanged(views::Textfield* sender,
568 const string16& new_contents) {
569 if (handling_key_press_)
570 content_maybe_changed_by_key_press_ = true;
571 }
572
573 bool AutocompleteEditViewViews::HandleKeyEvent(
574 views::Textfield* textfield,
575 const views::KeyEvent& event) {
576 delete_was_pressed_ = event.GetKeyCode() == ui::VKEY_DELETE;
577
578 // Reset |text_changed_| before passing the key event on to the text view.
579 text_changed_ = false;
580 OnBeforePossibleChange();
581 handling_key_press_ = true;
582 content_maybe_changed_by_key_press_ = false;
583
584 if (event.GetKeyCode() == ui::VKEY_BACK) {
585 // Checks if it's currently in keyword search mode.
586 if (model_->is_keyword_hint() || model_->keyword().empty())
Peter Kasting 2011/01/20 19:44:37 Nit: Could simplify all this to if (!model_->is
587 return false;
588 // If there is selection, let textfield handle the backspace.
589 if (!textfield_->GetSelectedText().empty())
590 return false;
591 // If not at the begining of the text, let textfield handle the backspace.
592 if (textfield_->GetCursorPosition())
593 return false;
594 model_->ClearKeyword(GetText());
595 return true;
596 }
597
598 return false;
599 }
600
601 ////////////////////////////////////////////////////////////////////////////////
602 // AutocompleteEditViewViews, private:
603
604 size_t AutocompleteEditViewViews::GetTextLength() const {
605 // TODO(oshima): Support instant, IME.
606 return textfield_->text().length();
607 }
608
609 void AutocompleteEditViewViews::EmphasizeURLComponents() {
610 // TODO(oshima): Update URL visual style
611 NOTIMPLEMENTED();
612 }
613
614 void AutocompleteEditViewViews::TextChanged() {
615 EmphasizeURLComponents();
616 controller_->OnChanged();
617 }
618
619 void AutocompleteEditViewViews::SetTextAndSelectedRange(
620 const std::wstring& text,
621 const views::TextRange& range) {
622 if (text != GetText()) {
Peter Kasting 2011/01/20 19:44:37 Nit: No {}
oshima 2011/01/20 21:35:48 Done.
623 textfield_->SetText(WideToUTF16(text));
624 }
625 textfield_->SelectRange(range);
626 }
627
628 string16 AutocompleteEditViewViews::GetSelectedText() const {
629 // TODO(oshima): Support instant, IME.
630 return textfield_->GetSelectedText();
631 }
632
633 void AutocompleteEditViewViews::SelectRange(size_t caret, size_t end) {
634 const views::TextRange range(caret, end);
635 textfield_->SelectRange(range);
636 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698