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 "chrome/browser/ui/views/omnibox/omnibox_view_views.h" | 5 #include "chrome/browser/ui/views/omnibox/omnibox_view_views.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "chrome/app/chrome_command_ids.h" | 10 #include "chrome/app/chrome_command_ids.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
95 // kAutocompleteEditFontPixelSizeInPopup. They should be changed accordingly | 95 // kAutocompleteEditFontPixelSizeInPopup. They should be changed accordingly |
96 // if font size for autocomplete edit (in popup) change. | 96 // if font size for autocomplete edit (in popup) change. |
97 const int kAutocompleteVerticalMargin = 1; | 97 const int kAutocompleteVerticalMargin = 1; |
98 const int kAutocompleteVerticalMarginInPopup = 2; | 98 const int kAutocompleteVerticalMarginInPopup = 2; |
99 | 99 |
100 int GetEditFontPixelSize(bool popup_window_mode) { | 100 int GetEditFontPixelSize(bool popup_window_mode) { |
101 return popup_window_mode ? kAutocompleteEditFontPixelSizeInPopup : | 101 return popup_window_mode ? kAutocompleteEditFontPixelSizeInPopup : |
102 kAutocompleteEditFontPixelSize; | 102 kAutocompleteEditFontPixelSize; |
103 } | 103 } |
104 | 104 |
105 // Copies |selected_text| as text to the primary clipboard. | |
106 void DoCopyText(const string16& selected_text) { | |
107 ui::ScopedClipboardWriter scw(ui::Clipboard::GetForCurrentThread(), | |
108 ui::Clipboard::BUFFER_STANDARD); | |
109 scw.WriteText(selected_text); | |
110 } | |
111 | |
112 // This will write |url| and |text| to the clipboard as a well-formed URL. | 105 // This will write |url| and |text| to the clipboard as a well-formed URL. |
113 void DoCopyURL(const GURL& url, const string16& text) { | 106 void DoCopyURL(const GURL& url, const string16& text) { |
114 BookmarkNodeData data; | 107 BookmarkNodeData data; |
115 data.ReadFromTuple(url, text); | 108 data.ReadFromTuple(url, text); |
116 data.WriteToClipboard(NULL); | 109 data.WriteToClipboard(NULL); |
117 } | 110 } |
118 | 111 |
119 } // namespace | 112 } // namespace |
120 | 113 |
121 // Textfield for autocomplete that intercepts events that are necessary | |
122 // for OmniboxViewViews. | |
123 class OmniboxViewViews::AutocompleteTextfield : public views::Textfield { | |
124 public: | |
125 AutocompleteTextfield(OmniboxViewViews* omnibox_view, | |
126 LocationBarView* location_bar_view) | |
127 : views::Textfield(views::Textfield::STYLE_DEFAULT), | |
128 omnibox_view_(omnibox_view), | |
129 location_bar_view_(location_bar_view) { | |
130 DCHECK(omnibox_view_); | |
131 RemoveBorder(); | |
132 set_id(VIEW_ID_OMNIBOX); | |
133 } | |
134 | |
135 // views::View implementation | |
136 virtual void OnFocus() OVERRIDE { | |
137 views::Textfield::OnFocus(); | |
138 omnibox_view_->HandleFocusIn(); | |
139 } | |
140 | |
141 virtual void OnBlur() OVERRIDE { | |
142 views::Textfield::OnBlur(); | |
143 omnibox_view_->HandleFocusOut(); | |
144 } | |
145 | |
146 virtual bool OnKeyPressed(const ui::KeyEvent& event) OVERRIDE { | |
147 // Use our own implementation of paste. See OnPaste() for details. | |
148 if (!read_only() && event.IsControlDown() && | |
149 event.key_code() == ui::VKEY_V) { | |
150 omnibox_view_->OnBeforePossibleChange(); | |
151 omnibox_view_->OnPaste(); | |
152 omnibox_view_->OnAfterPossibleChange(); | |
153 return true; | |
154 } | |
155 bool handled = views::Textfield::OnKeyPressed(event); | |
156 return omnibox_view_->HandleAfterKeyEvent(event, handled) || handled; | |
157 } | |
158 | |
159 virtual bool OnKeyReleased(const ui::KeyEvent& event) OVERRIDE { | |
160 return omnibox_view_->HandleKeyReleaseEvent(event); | |
161 } | |
162 | |
163 virtual bool OnMousePressed(const ui::MouseEvent& event) OVERRIDE { | |
164 // Pass through the views::Textfield's return value; we don't need to | |
165 // override its behavior. | |
166 bool result = views::Textfield::OnMousePressed(event); | |
167 omnibox_view_->HandleMousePressEvent(event); | |
168 return result; | |
169 } | |
170 | |
171 virtual bool OnMouseDragged(const ui::MouseEvent& event) OVERRIDE { | |
172 bool result = views::Textfield::OnMouseDragged(event); | |
173 omnibox_view_->HandleMouseDragEvent(event); | |
174 return result; | |
175 } | |
176 | |
177 virtual void OnMouseReleased(const ui::MouseEvent& event) OVERRIDE { | |
178 views::Textfield::OnMouseReleased(event); | |
179 omnibox_view_->HandleMouseReleaseEvent(event); | |
180 } | |
181 | |
182 virtual void OnGestureEvent(ui::GestureEvent* event) OVERRIDE { | |
183 views::Textfield::OnGestureEvent(event); | |
184 omnibox_view_->HandleGestureEvent(*event); | |
185 } | |
186 | |
187 private: | |
188 OmniboxViewViews* omnibox_view_; | |
189 LocationBarView* location_bar_view_; | |
190 | |
191 DISALLOW_COPY_AND_ASSIGN(AutocompleteTextfield); | |
192 }; | |
193 | |
194 // static | 114 // static |
195 const char OmniboxViewViews::kViewClassName[] = "BrowserOmniboxViewViews"; | 115 const char OmniboxViewViews::kViewClassName[] = "BrowserOmniboxViewViews"; |
196 | 116 |
197 OmniboxViewViews::OmniboxViewViews(OmniboxEditController* controller, | 117 OmniboxViewViews::OmniboxViewViews(OmniboxEditController* controller, |
198 ToolbarModel* toolbar_model, | 118 ToolbarModel* toolbar_model, |
199 Profile* profile, | 119 Profile* profile, |
200 CommandUpdater* command_updater, | 120 CommandUpdater* command_updater, |
201 bool popup_window_mode, | 121 bool popup_window_mode, |
202 LocationBarView* location_bar) | 122 LocationBarView* location_bar) |
203 : OmniboxView(profile, controller, toolbar_model, command_updater), | 123 : OmniboxView(profile, controller, toolbar_model, command_updater), |
204 textfield_(NULL), | |
205 popup_window_mode_(popup_window_mode), | 124 popup_window_mode_(popup_window_mode), |
206 security_level_(ToolbarModel::NONE), | 125 security_level_(ToolbarModel::NONE), |
207 ime_composing_before_change_(false), | 126 ime_composing_before_change_(false), |
208 delete_at_end_pressed_(false), | 127 delete_at_end_pressed_(false), |
209 location_bar_view_(location_bar), | 128 location_bar_view_(location_bar), |
210 ime_candidate_window_open_(false), | 129 ime_candidate_window_open_(false), |
211 select_all_on_mouse_release_(false), | 130 select_all_on_mouse_release_(false), |
212 select_all_on_gesture_tap_(false) { | 131 select_all_on_gesture_tap_(false) { |
132 RemoveBorder(); | |
133 set_id(VIEW_ID_OMNIBOX); | |
213 } | 134 } |
214 | 135 |
215 OmniboxViewViews::~OmniboxViewViews() { | 136 OmniboxViewViews::~OmniboxViewViews() { |
216 #if defined(OS_CHROMEOS) | 137 #if defined(OS_CHROMEOS) |
217 chromeos::input_method::GetInputMethodManager()-> | 138 chromeos::input_method::GetInputMethodManager()-> |
218 RemoveCandidateWindowObserver(this); | 139 RemoveCandidateWindowObserver(this); |
219 #endif | 140 #endif |
220 | 141 |
221 // Explicitly teardown members which have a reference to us. Just to be safe | 142 // Explicitly teardown members which have a reference to us. Just to be safe |
222 // we want them to be destroyed before destroying any other internal state. | 143 // we want them to be destroyed before destroying any other internal state. |
223 popup_view_.reset(); | 144 popup_view_.reset(); |
224 } | 145 } |
225 | 146 |
226 //////////////////////////////////////////////////////////////////////////////// | 147 //////////////////////////////////////////////////////////////////////////////// |
227 // OmniboxViewViews public: | 148 // OmniboxViewViews public: |
228 | 149 |
229 void OmniboxViewViews::Init() { | 150 void OmniboxViewViews::Init() { |
230 // The height of the text view is going to change based on the font used. We | 151 // The height of the text view is going to change based on the font used. We |
231 // don't want to stretch the height, and we want it vertically centered. | 152 // don't want to stretch the height, and we want it vertically centered. |
232 // TODO(oshima): make sure the above happens with views. | 153 // TODO(oshima): make sure the above happens with views. |
233 textfield_ = new AutocompleteTextfield(this, location_bar_view_); | 154 SetController(this); |
234 textfield_->SetController(this); | 155 SetTextInputType(ui::TEXT_INPUT_TYPE_URL); |
235 textfield_->SetTextInputType(ui::TEXT_INPUT_TYPE_URL); | 156 SetBackgroundColor(location_bar_view_->GetColor( |
236 textfield_->SetBackgroundColor(location_bar_view_->GetColor( | |
237 ToolbarModel::NONE, LocationBarView::BACKGROUND)); | 157 ToolbarModel::NONE, LocationBarView::BACKGROUND)); |
238 | 158 |
239 if (popup_window_mode_) | 159 if (popup_window_mode_) |
240 textfield_->SetReadOnly(true); | 160 SetReadOnly(true); |
241 | 161 |
242 const int font_size = GetEditFontPixelSize(popup_window_mode_); | 162 const int font_size = GetEditFontPixelSize(popup_window_mode_); |
243 const int old_size = textfield_->font().GetFontSize(); | 163 if (font_size != font().GetFontSize()) |
244 if (font_size != old_size) | 164 SetFont(font().DeriveFont(font_size - font().GetFontSize())); |
245 textfield_->SetFont(textfield_->font().DeriveFont(font_size - old_size)); | |
246 | 165 |
247 // Create popup view using the same font as |textfield_|'s. | 166 // Initialize the popup view using the same font. |
248 popup_view_.reset( | 167 popup_view_.reset(OmniboxPopupContentsView::Create( |
249 OmniboxPopupContentsView::Create( | 168 font(), this, model(), location_bar_view_)); |
250 textfield_->font(), this, model(), location_bar_view_)); | |
251 | 169 |
252 // A null-border to zero out the focused border on textfield. | 170 // A null-border to zero out the focused border on textfield. |
253 const int vertical_margin = !popup_window_mode_ ? | 171 const int vertical_margin = !popup_window_mode_ ? |
254 kAutocompleteVerticalMargin : kAutocompleteVerticalMarginInPopup; | 172 kAutocompleteVerticalMargin : kAutocompleteVerticalMarginInPopup; |
255 set_border(views::Border::CreateEmptyBorder(vertical_margin, 0, | 173 set_border(views::Border::CreateEmptyBorder(vertical_margin, 0, |
256 vertical_margin, 0)); | 174 vertical_margin, 0)); |
257 #if defined(OS_CHROMEOS) | 175 #if defined(OS_CHROMEOS) |
258 chromeos::input_method::GetInputMethodManager()-> | 176 chromeos::input_method::GetInputMethodManager()-> |
259 AddCandidateWindowObserver(this); | 177 AddCandidateWindowObserver(this); |
260 #endif | 178 #endif |
261 } | 179 } |
262 | 180 |
263 gfx::Font OmniboxViewViews::GetFont() { | 181 gfx::Font OmniboxViewViews::GetFont() { |
264 return textfield_->font(); | 182 return font(); |
265 } | 183 } |
266 | 184 |
267 int OmniboxViewViews::WidthOfTextAfterCursor() { | 185 int OmniboxViewViews::WidthOfTextAfterCursor() { |
268 ui::Range sel; | 186 ui::Range sel; |
269 textfield_->GetSelectedRange(&sel); | 187 GetSelectedRange(&sel); |
270 // See comments in LocationBarView::Layout as to why this uses -1. | 188 // See comments in LocationBarView::Layout as to why this uses -1. |
271 const int start = std::max(0, static_cast<int>(sel.end()) - 1); | 189 const int start = std::max(0, static_cast<int>(sel.end()) - 1); |
272 // TODO: add horizontal margin. | 190 // TODO: add horizontal margin. |
273 return textfield_->font().GetStringWidth(GetText().substr(start)); | 191 return font().GetStringWidth(text().substr(start)); |
274 } | 192 } |
275 | 193 |
276 bool OmniboxViewViews::HandleAfterKeyEvent(const ui::KeyEvent& event, | 194 //////////////////////////////////////////////////////////////////////////////// |
277 bool handled) { | 195 // OmniboxViewViews, views::View implementation: |
Peter Kasting
2013/02/18 18:57:47
Nit: Again, we don't directly override View.
Pers
msw
2013/02/18 20:58:21
I'm not a big fan either, but I fixed it rather th
| |
196 | |
197 std::string OmniboxViewViews::GetClassName() const { | |
198 return kViewClassName; | |
199 } | |
200 | |
201 void OmniboxViewViews::OnGestureEvent(ui::GestureEvent* event) { | |
202 views::Textfield::OnGestureEvent(event); | |
203 if (!HasFocus() && event->type() == ui::ET_GESTURE_TAP_DOWN) { | |
204 select_all_on_gesture_tap_ = true; | |
205 return; | |
206 } | |
207 if (select_all_on_gesture_tap_ && event->type() == ui::ET_GESTURE_TAP) | |
208 SelectAll(false); | |
209 select_all_on_gesture_tap_ = false; | |
210 } | |
211 | |
212 void OmniboxViewViews::GetAccessibleState(ui::AccessibleViewState* state) { | |
213 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION); | |
214 } | |
215 | |
216 void OmniboxViewViews::OnBoundsChanged(const gfx::Rect& previous_bounds) { | |
217 if (popup_view_->IsOpen()) | |
218 popup_view_->UpdatePopupAppearance(); | |
219 } | |
220 | |
221 bool OmniboxViewViews::OnMousePressed(const ui::MouseEvent& event) { | |
222 const bool result = views::Textfield::OnMousePressed(event); | |
223 select_all_on_mouse_release_ = | |
224 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && | |
225 (!HasFocus() || (model()->focus_state() == OMNIBOX_FOCUS_INVISIBLE)); | |
226 // Restore caret visibility whenever the user clicks in the omnibox in a way | |
227 // that would give it focus. We must handle this case separately here because | |
228 // if the omnibox currently has invisible focus, the mouse event won't trigger | |
229 // either SetFocus() or OmniboxEditModel::OnSetFocus(). | |
230 if (select_all_on_mouse_release_) | |
231 model()->SetCaretVisibility(true); | |
232 return result; | |
233 } | |
234 | |
235 bool OmniboxViewViews::OnMouseDragged(const ui::MouseEvent& event) { | |
236 select_all_on_mouse_release_ = false; | |
237 return views::Textfield::OnMouseDragged(event); | |
238 } | |
239 | |
240 void OmniboxViewViews::OnMouseReleased(const ui::MouseEvent& event) { | |
241 views::Textfield::OnMouseReleased(event); | |
242 if ((event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && | |
243 select_all_on_mouse_release_) { | |
244 // Select all in the reverse direction so as not to scroll the caret | |
245 // into view and shift the contents jarringly. | |
246 SelectAll(true); | |
247 } | |
248 select_all_on_mouse_release_ = false; | |
249 } | |
250 | |
251 bool OmniboxViewViews::OnKeyPressed(const ui::KeyEvent& event) { | |
252 // Use our own implementation of paste. See OnPaste() for details. | |
253 if (!read_only() && event.IsControlDown() && | |
254 event.key_code() == ui::VKEY_V) { | |
255 OnBeforePossibleChange(); | |
256 OnPaste(); | |
257 OnAfterPossibleChange(); | |
258 return true; | |
259 } | |
260 bool handled = views::Textfield::OnKeyPressed(event); | |
261 | |
278 if (event.key_code() == ui::VKEY_RETURN) { | 262 if (event.key_code() == ui::VKEY_RETURN) { |
279 bool alt_held = event.IsAltDown(); | 263 bool alt_held = event.IsAltDown(); |
280 model()->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); | 264 model()->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); |
281 handled = true; | 265 handled = true; |
282 } else if (!handled && event.key_code() == ui::VKEY_ESCAPE) { | 266 } else if (!handled && event.key_code() == ui::VKEY_ESCAPE) { |
283 // We can handle the Escape key if textfield did not handle it. | 267 // Let the model handle the Escape key or continue its propagation. |
284 // If it's not handled by us, then we need to propagate it up to the parent | |
285 // widgets, so that Escape accelerator can still work. | |
286 handled = model()->OnEscapeKeyPressed(); | 268 handled = model()->OnEscapeKeyPressed(); |
287 } else if (event.key_code() == ui::VKEY_CONTROL) { | 269 } else if (event.key_code() == ui::VKEY_CONTROL) { |
288 // Omnibox2 can switch its contents while pressing a control key. To switch | 270 // Omnibox2 can switch its contents while pressing a control key. To switch |
289 // the contents of omnibox2, we notify the OmniboxEditModel class when the | 271 // the contents of omnibox2, we notify the OmniboxEditModel class when the |
290 // control-key state is changed. | 272 // control-key state is changed. |
291 model()->OnControlKeyChanged(true); | 273 model()->OnControlKeyChanged(true); |
292 } else if (!handled && event.key_code() == ui::VKEY_DELETE && | 274 } else if (!handled && event.key_code() == ui::VKEY_DELETE && |
293 event.IsShiftDown()) { | 275 event.IsShiftDown()) { |
294 // If shift+del didn't change the text, we let this delete an entry from | 276 // If shift+del didn't change the text, we let this delete an entry from |
295 // the popup. We can't check to see if the IME handled it because even if | 277 // the popup. We can't check to see if the IME handled it because even if |
296 // nothing is selected, the IME or the TextView still report handling it. | 278 // nothing is selected, the IME or the TextView still report handling it. |
297 if (model()->popup_model()->IsOpen()) | 279 if (model()->popup_model()->IsOpen()) |
298 model()->popup_model()->TryDeletingCurrentItem(); | 280 model()->popup_model()->TryDeletingCurrentItem(); |
299 } else if (!handled && event.key_code() == ui::VKEY_UP) { | 281 } else if (!handled && event.key_code() == ui::VKEY_UP) { |
300 model()->OnUpOrDownKeyPressed(-1); | 282 model()->OnUpOrDownKeyPressed(-1); |
301 handled = true; | 283 handled = true; |
302 } else if (!handled && event.key_code() == ui::VKEY_DOWN) { | 284 } else if (!handled && event.key_code() == ui::VKEY_DOWN) { |
303 model()->OnUpOrDownKeyPressed(1); | 285 model()->OnUpOrDownKeyPressed(1); |
304 handled = true; | 286 handled = true; |
305 } else if (!handled && | 287 } else if (!handled && |
306 event.key_code() == ui::VKEY_TAB && | 288 event.key_code() == ui::VKEY_TAB && |
307 !event.IsControlDown()) { | 289 !event.IsControlDown()) { |
308 if (model()->is_keyword_hint() && !event.IsShiftDown()) { | 290 if (model()->is_keyword_hint() && !event.IsShiftDown()) { |
309 handled = model()->AcceptKeyword(); | 291 handled = model()->AcceptKeyword(); |
310 } else if (model()->popup_model()->IsOpen()) { | 292 } else if (model()->popup_model()->IsOpen()) { |
311 if (event.IsShiftDown() && | 293 if (event.IsShiftDown() && |
312 model()->popup_model()->selected_line_state() == | 294 model()->popup_model()->selected_line_state() == |
313 OmniboxPopupModel::KEYWORD) { | 295 OmniboxPopupModel::KEYWORD) { |
314 model()->ClearKeyword(GetText()); | 296 model()->ClearKeyword(text()); |
315 } else { | 297 } else { |
316 model()->OnUpOrDownKeyPressed(event.IsShiftDown() ? -1 : 1); | 298 model()->OnUpOrDownKeyPressed(event.IsShiftDown() ? -1 : 1); |
317 } | 299 } |
318 handled = true; | 300 handled = true; |
319 } else { | 301 } else { |
320 string16::size_type start = 0; | 302 string16::size_type start = 0; |
321 string16::size_type end = 0; | 303 string16::size_type end = 0; |
322 size_t length = GetTextLength(); | 304 const size_t length = text().length(); |
323 GetSelectionBounds(&start, &end); | 305 GetSelectionBounds(&start, &end); |
324 if (start != end || start < length) { | 306 if (start != end || start < length) { |
325 OnBeforePossibleChange(); | 307 OnBeforePossibleChange(); |
326 textfield_->SelectRange(ui::Range(length, length)); | 308 SelectRange(ui::Range(length, length)); |
327 OnAfterPossibleChange(); | 309 OnAfterPossibleChange(); |
328 handled = true; | 310 handled = true; |
329 } | 311 } |
330 | 312 |
331 // TODO(Oshima): handle instant | 313 // TODO(msw|oshima): Handle Instant. |
332 } | 314 } |
333 } | 315 } |
334 // TODO(oshima): page up & down | 316 // TODO(msw|oshima): Handle page up and page down. |
335 | 317 |
336 return handled; | 318 return handled; |
337 } | 319 } |
338 | 320 |
339 bool OmniboxViewViews::HandleKeyReleaseEvent(const ui::KeyEvent& event) { | 321 bool OmniboxViewViews::OnKeyReleased(const ui::KeyEvent& event) { |
340 // Omnibox2 can switch its contents while pressing a control key. To switch | 322 // Omnibox2 can switch its contents while pressing a control key. To switch |
341 // the contents of omnibox2, we notify the OmniboxEditModel class when the | 323 // the contents of omnibox2, we notify the OmniboxEditModel class when the |
342 // control-key state is changed. | 324 // control-key state is changed. |
343 if (event.key_code() == ui::VKEY_CONTROL) { | 325 if (event.key_code() == ui::VKEY_CONTROL) { |
344 // TODO(oshima): investigate if we need to support keyboard with two | 326 // TODO(oshima): investigate if we need to support keyboard with two |
345 // controls. | 327 // controls. |
346 model()->OnControlKeyChanged(false); | 328 model()->OnControlKeyChanged(false); |
347 return true; | 329 return true; |
348 } | 330 } |
349 return false; | 331 return false; |
350 } | 332 } |
351 | 333 |
352 void OmniboxViewViews::HandleMousePressEvent(const ui::MouseEvent& event) { | 334 void OmniboxViewViews::OnFocus() { |
353 select_all_on_mouse_release_ = | 335 views::Textfield::OnFocus(); |
354 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && | |
355 (!textfield_->HasFocus() || | |
356 (model()->focus_state() == OMNIBOX_FOCUS_INVISIBLE)); | |
357 // Restore caret visibility whenever the user clicks in the omnibox in a way | |
358 // that would give it focus. We must handle this case separately here because | |
359 // if the omnibox currently has invisible focus, the mouse event won't trigger | |
360 // either SetFocus() or OmniboxEditModel::OnSetFocus(). | |
361 if (select_all_on_mouse_release_) | |
362 model()->SetCaretVisibility(true); | |
363 } | |
364 | |
365 void OmniboxViewViews::HandleMouseDragEvent(const ui::MouseEvent& event) { | |
366 select_all_on_mouse_release_ = false; | |
367 } | |
368 | |
369 void OmniboxViewViews::HandleMouseReleaseEvent(const ui::MouseEvent& event) { | |
370 if ((event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && | |
371 select_all_on_mouse_release_) { | |
372 // Select all in the reverse direction so as not to scroll the caret | |
373 // into view and shift the contents jarringly. | |
374 SelectAll(true); | |
375 } | |
376 select_all_on_mouse_release_ = false; | |
377 } | |
378 | |
379 void OmniboxViewViews::HandleGestureEvent(const ui::GestureEvent& event) { | |
380 if (!textfield_->HasFocus() && event.type() == ui::ET_GESTURE_TAP_DOWN) { | |
381 select_all_on_gesture_tap_ = true; | |
382 return; | |
383 } | |
384 if (select_all_on_gesture_tap_ && event.type() == ui::ET_GESTURE_TAP) | |
385 SelectAll(false); | |
386 select_all_on_gesture_tap_ = false; | |
387 } | |
388 | |
389 void OmniboxViewViews::HandleFocusIn() { | |
390 // TODO(oshima): Get control key state. | 336 // TODO(oshima): Get control key state. |
391 model()->OnSetFocus(false); | 337 model()->OnSetFocus(false); |
392 // Don't call controller()->OnSetFocus as this view has already | 338 // Don't call controller()->OnSetFocus as this view has already |
393 // acquired the focus. | 339 // acquired the focus. |
394 } | 340 } |
395 | 341 |
396 void OmniboxViewViews::HandleFocusOut() { | 342 void OmniboxViewViews::OnBlur() { |
343 views::Textfield::OnBlur(); | |
397 gfx::NativeView native_view = NULL; | 344 gfx::NativeView native_view = NULL; |
398 #if defined(USE_AURA) | 345 #if defined(USE_AURA) |
399 views::Widget* widget = GetWidget(); | 346 views::Widget* widget = GetWidget(); |
400 if (widget) { | 347 if (widget) { |
401 aura::client::FocusClient* client = | 348 aura::client::FocusClient* client = |
402 aura::client::GetFocusClient(widget->GetNativeView()); | 349 aura::client::GetFocusClient(widget->GetNativeView()); |
403 if (client) | 350 if (client) |
404 native_view = client->GetFocusedWindow(); | 351 native_view = client->GetFocusedWindow(); |
405 } | 352 } |
406 #endif | 353 #endif |
407 model()->OnWillKillFocus(native_view); | 354 model()->OnWillKillFocus(native_view); |
408 // Close the popup. | 355 // Close the popup. |
409 CloseOmniboxPopup(); | 356 CloseOmniboxPopup(); |
410 // Tell the model to reset itself. | 357 // Tell the model to reset itself. |
411 model()->OnKillFocus(); | 358 model()->OnKillFocus(); |
412 controller()->OnKillFocus(); | 359 controller()->OnKillFocus(); |
413 } | 360 } |
414 | 361 |
415 void OmniboxViewViews::SetLocationEntryFocusable(bool focusable) { | |
416 textfield_->set_focusable(focusable); | |
417 } | |
418 | |
419 bool OmniboxViewViews::IsLocationEntryFocusableInRootView() const { | |
420 return textfield_->IsFocusable(); | |
421 } | |
422 | |
423 //////////////////////////////////////////////////////////////////////////////// | |
424 // OmniboxViewViews, views::View implementation: | |
425 void OmniboxViewViews::Layout() { | |
426 gfx::Insets insets = GetInsets(); | |
427 textfield_->SetBounds(insets.left(), insets.top(), | |
428 width() - insets.width(), | |
429 height() - insets.height()); | |
430 } | |
431 | |
432 void OmniboxViewViews::GetAccessibleState(ui::AccessibleViewState* state) { | |
433 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION); | |
434 } | |
435 | |
436 std::string OmniboxViewViews::GetClassName() const { | |
437 return kViewClassName; | |
438 } | |
439 | |
440 void OmniboxViewViews::OnBoundsChanged(const gfx::Rect& previous_bounds) { | |
441 if (popup_view_->IsOpen()) | |
442 popup_view_->UpdatePopupAppearance(); | |
443 } | |
444 | |
445 //////////////////////////////////////////////////////////////////////////////// | 362 //////////////////////////////////////////////////////////////////////////////// |
446 // OmniboxViewViews, OmniboxView implementation: | 363 // OmniboxViewViews, OmniboxView implementation: |
447 | 364 |
448 void OmniboxViewViews::SaveStateToTab(WebContents* tab) { | 365 void OmniboxViewViews::SaveStateToTab(WebContents* tab) { |
449 DCHECK(tab); | 366 DCHECK(tab); |
450 | 367 |
451 // We don't want to keep the IME status, so force quit the current | 368 // We don't want to keep the IME status, so force quit the current |
452 // session here. It may affect the selection status, so order is | 369 // session here. It may affect the selection status, so order is |
453 // also important. | 370 // also important. |
454 if (textfield_->IsIMEComposing()) { | 371 if (IsIMEComposing()) { |
455 textfield_->GetTextInputClient()->ConfirmCompositionText(); | 372 GetTextInputClient()->ConfirmCompositionText(); |
456 textfield_->GetInputMethod()->CancelComposition(textfield_); | 373 GetInputMethod()->CancelComposition(this); |
457 } | 374 } |
458 | 375 |
459 // NOTE: GetStateForTabSwitch may affect GetSelection, so order is important. | 376 // NOTE: GetStateForTabSwitch may affect GetSelection, so order is important. |
460 OmniboxEditModel::State model_state = model()->GetStateForTabSwitch(); | 377 OmniboxEditModel::State model_state = model()->GetStateForTabSwitch(); |
461 gfx::SelectionModel selection; | 378 gfx::SelectionModel selection; |
462 textfield_->GetSelectionModel(&selection); | 379 GetSelectionModel(&selection); |
463 tab->SetUserData( | 380 tab->SetUserData( |
464 kAutocompleteEditStateKey, | 381 kAutocompleteEditStateKey, |
465 new AutocompleteEditState(model_state, ViewState(selection))); | 382 new AutocompleteEditState(model_state, ViewState(selection))); |
466 } | 383 } |
467 | 384 |
468 void OmniboxViewViews::Update(const WebContents* contents) { | 385 void OmniboxViewViews::Update(const WebContents* contents) { |
469 // NOTE: We're getting the URL text here from the ToolbarModel. | 386 // NOTE: We're getting the URL text here from the ToolbarModel. |
470 bool visibly_changed_permanent_text = | 387 bool visibly_changed_permanent_text = |
471 model()->UpdatePermanentText(toolbar_model()->GetText(true)); | 388 model()->UpdatePermanentText(toolbar_model()->GetText(true)); |
472 ToolbarModel::SecurityLevel security_level = | 389 ToolbarModel::SecurityLevel security_level = |
473 toolbar_model()->GetSecurityLevel(); | 390 toolbar_model()->GetSecurityLevel(); |
474 bool changed_security_level = (security_level != security_level_); | 391 bool changed_security_level = (security_level != security_level_); |
475 security_level_ = security_level; | 392 security_level_ = security_level; |
476 | 393 |
477 // TODO(oshima): Copied from gtk implementation which is | 394 // TODO(oshima): Copied from gtk implementation which is |
478 // slightly different from WIN impl. Find out the correct implementation | 395 // slightly different from WIN impl. Find out the correct implementation |
479 // for views-implementation. | 396 // for views-implementation. |
480 if (contents) { | 397 if (contents) { |
481 RevertAll(); | 398 RevertAll(); |
482 const AutocompleteEditState* state = static_cast<AutocompleteEditState*>( | 399 const AutocompleteEditState* state = static_cast<AutocompleteEditState*>( |
483 contents->GetUserData(&kAutocompleteEditStateKey)); | 400 contents->GetUserData(&kAutocompleteEditStateKey)); |
484 if (state) { | 401 if (state) { |
485 model()->RestoreState(state->model_state); | 402 model()->RestoreState(state->model_state); |
486 | 403 |
487 // Move the marks for the cursor and the other end of the selection to | 404 // Move the marks for the cursor and the other end of the selection to |
488 // the previously-saved offsets (but preserve PRIMARY). | 405 // the previously-saved offsets (but preserve PRIMARY). |
489 textfield_->SelectSelectionModel(state->view_state.selection_model); | 406 SelectSelectionModel(state->view_state.selection_model); |
490 // We do not carry over the current edit history to another tab. | 407 // We do not carry over the current edit history to another tab. |
491 // TODO(oshima): consider saving/restoring edit history. | 408 // TODO(oshima): consider saving/restoring edit history. |
492 textfield_->ClearEditHistory(); | 409 ClearEditHistory(); |
493 } | 410 } |
494 } else if (visibly_changed_permanent_text) { | 411 } else if (visibly_changed_permanent_text) { |
495 RevertAll(); | 412 RevertAll(); |
496 } else if (changed_security_level) { | 413 } else if (changed_security_level) { |
497 EmphasizeURLComponents(); | 414 EmphasizeURLComponents(); |
498 } | 415 } |
499 } | 416 } |
500 | 417 |
501 string16 OmniboxViewViews::GetText() const { | 418 string16 OmniboxViewViews::GetText() const { |
502 // TODO(oshima): IME support | 419 // TODO(oshima): IME support |
503 return textfield_->text(); | 420 return text(); |
504 } | 421 } |
505 | 422 |
506 void OmniboxViewViews::SetWindowTextAndCaretPos(const string16& text, | 423 void OmniboxViewViews::SetWindowTextAndCaretPos(const string16& text, |
507 size_t caret_pos, | 424 size_t caret_pos, |
508 bool update_popup, | 425 bool update_popup, |
509 bool notify_text_changed) { | 426 bool notify_text_changed) { |
510 const ui::Range range(caret_pos, caret_pos); | 427 const ui::Range range(caret_pos, caret_pos); |
511 SetTextAndSelectedRange(text, range); | 428 SetTextAndSelectedRange(text, range); |
512 | 429 |
513 if (update_popup) | 430 if (update_popup) |
514 UpdatePopup(); | 431 UpdatePopup(); |
515 | 432 |
516 if (notify_text_changed) | 433 if (notify_text_changed) |
517 TextChanged(); | 434 TextChanged(); |
518 } | 435 } |
519 | 436 |
520 void OmniboxViewViews::SetForcedQuery() { | 437 void OmniboxViewViews::SetForcedQuery() { |
521 const string16 current_text(GetText()); | 438 const string16 current_text(text()); |
522 const size_t start = current_text.find_first_not_of(kWhitespaceUTF16); | 439 const size_t start = current_text.find_first_not_of(kWhitespaceUTF16); |
523 if (start == string16::npos || (current_text[start] != '?')) | 440 if (start == string16::npos || (current_text[start] != '?')) |
524 SetUserText(ASCIIToUTF16("?")); | 441 SetUserText(ASCIIToUTF16("?")); |
525 else | 442 else |
526 textfield_->SelectRange(ui::Range(current_text.size(), start + 1)); | 443 SelectRange(ui::Range(current_text.size(), start + 1)); |
527 } | 444 } |
528 | 445 |
529 bool OmniboxViewViews::IsSelectAll() const { | 446 bool OmniboxViewViews::IsSelectAll() const { |
530 // TODO(oshima): IME support. | 447 // TODO(oshima): IME support. |
531 return textfield_->text() == textfield_->GetSelectedText(); | 448 return text() == GetSelectedText(); |
532 } | 449 } |
533 | 450 |
534 bool OmniboxViewViews::DeleteAtEndPressed() { | 451 bool OmniboxViewViews::DeleteAtEndPressed() { |
535 return delete_at_end_pressed_; | 452 return delete_at_end_pressed_; |
536 } | 453 } |
537 | 454 |
538 void OmniboxViewViews::GetSelectionBounds(string16::size_type* start, | 455 void OmniboxViewViews::GetSelectionBounds(string16::size_type* start, |
539 string16::size_type* end) const { | 456 string16::size_type* end) const { |
540 ui::Range range; | 457 ui::Range range; |
541 textfield_->GetSelectedRange(&range); | 458 GetSelectedRange(&range); |
542 if (range.is_empty()) { | 459 if (range.is_empty()) { |
543 // Omnibox API expects that selection bounds is at cursor position | 460 // Omnibox API expects that selection bounds is at cursor position |
544 // if there is no selection. | 461 // if there is no selection. |
545 *start = textfield_->GetCursorPosition(); | 462 *start = GetCursorPosition(); |
546 *end = textfield_->GetCursorPosition(); | 463 *end = GetCursorPosition(); |
547 } else { | 464 } else { |
548 *start = static_cast<size_t>(range.end()); | 465 *start = static_cast<size_t>(range.end()); |
549 *end = static_cast<size_t>(range.start()); | 466 *end = static_cast<size_t>(range.start()); |
550 } | 467 } |
551 } | 468 } |
552 | 469 |
553 void OmniboxViewViews::SelectAll(bool reversed) { | 470 void OmniboxViewViews::SelectAll(bool reversed) { |
554 textfield_->SelectAll(reversed); | 471 views::Textfield::SelectAll(reversed); |
555 } | 472 } |
556 | 473 |
557 void OmniboxViewViews::UpdatePopup() { | 474 void OmniboxViewViews::UpdatePopup() { |
558 model()->SetInputInProgress(true); | 475 model()->SetInputInProgress(true); |
559 if (ime_candidate_window_open_) | 476 if (ime_candidate_window_open_) |
560 return; | 477 return; |
561 if (!model()->has_focus()) | 478 if (!model()->has_focus()) |
562 return; | 479 return; |
563 | 480 |
564 // Don't inline autocomplete when the caret/selection isn't at the end of | 481 // Prevent inline autocomplete when the caret isn't at the end of the text, |
565 // the text, or in the middle of composition. | 482 // and during IME composition editing. |
566 ui::Range sel; | 483 ui::Range sel; |
567 textfield_->GetSelectedRange(&sel); | 484 GetSelectedRange(&sel); |
568 bool no_inline_autocomplete = | 485 model()->StartAutocomplete(!sel.is_empty(), |
Peter Kasting
2013/02/18 18:57:47
Nit: Each line with arguments should have the argu
msw
2013/02/18 20:58:21
Done.
| |
569 sel.GetMax() < GetTextLength() || textfield_->IsIMEComposing(); | 486 sel.GetMax() < text().length() || IsIMEComposing()); |
570 | |
571 model()->StartAutocomplete(!sel.is_empty(), no_inline_autocomplete); | |
572 } | 487 } |
573 | 488 |
574 void OmniboxViewViews::SetFocus() { | 489 void OmniboxViewViews::SetFocus() { |
575 // In views-implementation, the focus is on textfield rather than OmniboxView. | 490 RequestFocus(); |
576 textfield_->RequestFocus(); | |
577 // Restore caret visibility if focus is explicitly requested. This is | 491 // Restore caret visibility if focus is explicitly requested. This is |
578 // necessary because if we already have invisible focus, the RequestFocus() | 492 // necessary because if we already have invisible focus, the RequestFocus() |
579 // call above will short-circuit, preventing us from reaching | 493 // call above will short-circuit, preventing us from reaching |
580 // OmniboxEditModel::OnSetFocus(), which handles restoring visibility when the | 494 // OmniboxEditModel::OnSetFocus(), which handles restoring visibility when the |
581 // omnibox regains focus after losing focus. | 495 // omnibox regains focus after losing focus. |
582 model()->SetCaretVisibility(true); | 496 model()->SetCaretVisibility(true); |
583 } | 497 } |
584 | 498 |
585 void OmniboxViewViews::ApplyCaretVisibility() { | 499 void OmniboxViewViews::ApplyCaretVisibility() { |
586 textfield_->SetCursorEnabled(model()->is_caret_visible()); | 500 SetCursorEnabled(model()->is_caret_visible()); |
587 } | 501 } |
588 | 502 |
589 void OmniboxViewViews::OnTemporaryTextMaybeChanged( | 503 void OmniboxViewViews::OnTemporaryTextMaybeChanged( |
590 const string16& display_text, | 504 const string16& display_text, |
591 bool save_original_selection, | 505 bool save_original_selection, |
592 bool notify_text_changed) { | 506 bool notify_text_changed) { |
593 if (save_original_selection) | 507 if (save_original_selection) |
594 textfield_->GetSelectedRange(&saved_temporary_selection_); | 508 GetSelectedRange(&saved_temporary_selection_); |
595 | 509 |
596 SetWindowTextAndCaretPos(display_text, display_text.length(), false, | 510 SetWindowTextAndCaretPos(display_text, display_text.length(), false, |
597 notify_text_changed); | 511 notify_text_changed); |
598 } | 512 } |
599 | 513 |
600 bool OmniboxViewViews::OnInlineAutocompleteTextMaybeChanged( | 514 bool OmniboxViewViews::OnInlineAutocompleteTextMaybeChanged( |
601 const string16& display_text, | 515 const string16& display_text, |
602 size_t user_text_length) { | 516 size_t user_text_length) { |
603 if (display_text == GetText()) | 517 if (display_text == text()) |
604 return false; | 518 return false; |
605 ui::Range range(display_text.size(), user_text_length); | 519 ui::Range range(display_text.size(), user_text_length); |
606 SetTextAndSelectedRange(display_text, range); | 520 SetTextAndSelectedRange(display_text, range); |
607 TextChanged(); | 521 TextChanged(); |
608 return true; | 522 return true; |
609 } | 523 } |
610 | 524 |
611 void OmniboxViewViews::OnRevertTemporaryText() { | 525 void OmniboxViewViews::OnRevertTemporaryText() { |
612 textfield_->SelectRange(saved_temporary_selection_); | 526 SelectRange(saved_temporary_selection_); |
527 TextChanged(); | |
613 } | 528 } |
614 | 529 |
615 void OmniboxViewViews::OnBeforePossibleChange() { | 530 void OmniboxViewViews::OnBeforePossibleChange() { |
616 // Record our state. | 531 // Record our state. |
617 text_before_change_ = GetText(); | 532 text_before_change_ = text(); |
618 textfield_->GetSelectedRange(&sel_before_change_); | 533 GetSelectedRange(&sel_before_change_); |
619 ime_composing_before_change_ = textfield_->IsIMEComposing(); | 534 ime_composing_before_change_ = IsIMEComposing(); |
620 } | 535 } |
621 | 536 |
622 bool OmniboxViewViews::OnAfterPossibleChange() { | 537 bool OmniboxViewViews::OnAfterPossibleChange() { |
623 ui::Range new_sel; | 538 ui::Range new_sel; |
624 textfield_->GetSelectedRange(&new_sel); | 539 GetSelectedRange(&new_sel); |
625 | 540 |
626 // See if the text or selection have changed since OnBeforePossibleChange(). | 541 // See if the text or selection have changed since OnBeforePossibleChange(). |
627 const string16 new_text = GetText(); | 542 const string16 new_text = text(); |
628 const bool text_changed = (new_text != text_before_change_) || | 543 const bool text_changed = (new_text != text_before_change_) || |
629 (ime_composing_before_change_ != textfield_->IsIMEComposing()); | 544 (ime_composing_before_change_ != IsIMEComposing()); |
630 const bool selection_differs = | 545 const bool selection_differs = |
631 !((sel_before_change_.is_empty() && new_sel.is_empty()) || | 546 !((sel_before_change_.is_empty() && new_sel.is_empty()) || |
632 sel_before_change_.EqualsIgnoringDirection(new_sel)); | 547 sel_before_change_.EqualsIgnoringDirection(new_sel)); |
633 | 548 |
634 // When the user has deleted text, we don't allow inline autocomplete. Make | 549 // When the user has deleted text, we don't allow inline autocomplete. Make |
635 // sure to not flag cases like selecting part of the text and then pasting | 550 // sure to not flag cases like selecting part of the text and then pasting |
636 // (or typing) the prefix of that selection. (We detect these by making | 551 // (or typing) the prefix of that selection. (We detect these by making |
637 // sure the caret, which should be after any insertion, hasn't moved | 552 // sure the caret, which should be after any insertion, hasn't moved |
638 // forward of the old selection start.) | 553 // forward of the old selection start.) |
639 const bool just_deleted_text = | 554 const bool just_deleted_text = |
640 (text_before_change_.length() > new_text.length()) && | 555 (text_before_change_.length() > new_text.length()) && |
641 (new_sel.start() <= sel_before_change_.GetMin()); | 556 (new_sel.start() <= sel_before_change_.GetMin()); |
642 | 557 |
643 const bool something_changed = model()->OnAfterPossibleChange( | 558 const bool something_changed = model()->OnAfterPossibleChange( |
644 text_before_change_, new_text, new_sel.start(), new_sel.end(), | 559 text_before_change_, new_text, new_sel.start(), new_sel.end(), |
645 selection_differs, text_changed, just_deleted_text, | 560 selection_differs, text_changed, just_deleted_text, !IsIMEComposing()); |
646 !textfield_->IsIMEComposing()); | |
647 | 561 |
648 // If only selection was changed, we don't need to call model()'s | 562 // If only selection was changed, we don't need to call model()'s |
649 // OnChanged() method, which is called in TextChanged(). | 563 // OnChanged() method, which is called in TextChanged(). |
650 // But we still need to call EmphasizeURLComponents() to make sure the text | 564 // But we still need to call EmphasizeURLComponents() to make sure the text |
651 // attributes are updated correctly. | 565 // attributes are updated correctly. |
652 if (something_changed && text_changed) | 566 if (something_changed && text_changed) |
653 TextChanged(); | 567 TextChanged(); |
654 else if (selection_differs) | 568 else if (selection_differs) |
655 EmphasizeURLComponents(); | 569 EmphasizeURLComponents(); |
656 else if (delete_at_end_pressed_) | 570 else if (delete_at_end_pressed_) |
(...skipping 19 matching lines...) Expand all Loading... | |
676 string16 OmniboxViewViews::GetInstantSuggestion() const { | 590 string16 OmniboxViewViews::GetInstantSuggestion() const { |
677 #if defined(OS_WIN) || defined(USE_AURA) | 591 #if defined(OS_WIN) || defined(USE_AURA) |
678 return location_bar_view_->GetInstantSuggestion(); | 592 return location_bar_view_->GetInstantSuggestion(); |
679 #else | 593 #else |
680 return string16(); | 594 return string16(); |
681 #endif | 595 #endif |
682 } | 596 } |
683 | 597 |
684 int OmniboxViewViews::TextWidth() const { | 598 int OmniboxViewViews::TextWidth() const { |
685 // TODO(oshima): add horizontal margin. | 599 // TODO(oshima): add horizontal margin. |
686 return textfield_->font().GetStringWidth(textfield_->text()); | 600 return font().GetStringWidth(text()); |
687 } | 601 } |
688 | 602 |
689 bool OmniboxViewViews::IsImeComposing() const { | 603 bool OmniboxViewViews::IsImeComposing() const { |
690 return false; | 604 return false; |
691 } | 605 } |
692 | 606 |
693 int OmniboxViewViews::GetMaxEditWidth(int entry_width) const { | 607 int OmniboxViewViews::GetMaxEditWidth(int entry_width) const { |
694 return entry_width; | 608 return entry_width; |
695 } | 609 } |
696 | 610 |
697 views::View* OmniboxViewViews::AddToView(views::View* parent) { | 611 views::View* OmniboxViewViews::AddToView(views::View* parent) { |
698 parent->AddChildView(this); | 612 parent->AddChildView(this); |
Peter Kasting
2013/02/18 18:57:47
Can we nuke this function entirely now? Seems lik
msw
2013/02/18 20:58:21
I'll try this in a followup, OmniboxViewWin::AddTo
| |
699 AddChildView(textfield_); | |
700 return this; | 613 return this; |
701 } | 614 } |
702 | 615 |
703 int OmniboxViewViews::OnPerformDrop(const ui::DropTargetEvent& event) { | 616 int OmniboxViewViews::OnPerformDrop(const ui::DropTargetEvent& event) { |
704 NOTIMPLEMENTED(); | 617 NOTIMPLEMENTED(); |
705 return ui::DragDropTypes::DRAG_NONE; | 618 return ui::DragDropTypes::DRAG_NONE; |
706 } | 619 } |
707 | 620 |
708 //////////////////////////////////////////////////////////////////////////////// | 621 //////////////////////////////////////////////////////////////////////////////// |
709 // OmniboxViewViews, views::TextfieldController implementation: | 622 // OmniboxViewViews, views::TextfieldController implementation: |
710 | 623 |
711 void OmniboxViewViews::ContentsChanged(views::Textfield* sender, | 624 void OmniboxViewViews::ContentsChanged(views::Textfield* sender, |
712 const string16& new_contents) { | 625 const string16& new_contents) { |
713 } | 626 } |
714 | 627 |
715 bool OmniboxViewViews::HandleKeyEvent(views::Textfield* textfield, | 628 bool OmniboxViewViews::HandleKeyEvent(views::Textfield* textfield, |
716 const ui::KeyEvent& event) { | 629 const ui::KeyEvent& event) { |
717 delete_at_end_pressed_ = false; | 630 delete_at_end_pressed_ = false; |
718 | 631 |
719 if (event.key_code() == ui::VKEY_BACK) { | 632 if (event.key_code() == ui::VKEY_BACK) { |
720 // Checks if it's currently in keyword search mode. | 633 // Checks if it's currently in keyword search mode. |
721 if (model()->is_keyword_hint() || model()->keyword().empty()) | 634 if (model()->is_keyword_hint() || model()->keyword().empty()) |
Peter Kasting
2013/02/18 18:57:47
Nit: I wouldn't mind just combining these three co
msw
2013/02/18 20:58:21
Done.
| |
722 return false; | 635 return false; |
723 // If there is selection, let textfield handle the backspace. | 636 // No extra handling is needed if there is a selection. |
724 if (textfield_->HasSelection()) | 637 if (HasSelection()) |
725 return false; | 638 return false; |
726 // If not at the begining of the text, let textfield handle the backspace. | 639 // No extra handling is needed if the cursor is not leading the text. |
727 if (textfield_->GetCursorPosition()) | 640 if (GetCursorPosition()) |
728 return false; | 641 return false; |
729 model()->ClearKeyword(GetText()); | 642 model()->ClearKeyword(text()); |
730 return true; | 643 return true; |
731 } | 644 } |
732 | 645 |
733 if (event.key_code() == ui::VKEY_DELETE && !event.IsAltDown()) { | 646 if (event.key_code() == ui::VKEY_DELETE && !event.IsAltDown()) { |
734 delete_at_end_pressed_ = | 647 delete_at_end_pressed_ = |
735 (!textfield_->HasSelection() && | 648 (!HasSelection() && GetCursorPosition() == text().length()); |
736 textfield_->GetCursorPosition() == textfield_->text().length()); | |
737 } | 649 } |
738 | 650 |
739 // Though the Textfield usually handles the right-arrow key for LTR text or | 651 // Handle the right-arrow key for LTR text and the left-arrow key for RTL text |
740 // left-arrow key for RTL text, we need to handle it if we have gray text | 652 // if there is an Instant suggestion (gray text) that needs to be committed. |
741 // (Instant suggestion) that needs to be committed. | 653 if (GetCursorPosition() == text().length()) { |
742 if (textfield_->GetCursorPosition() == textfield_->text().length()) { | 654 base::i18n::TextDirection direction = GetTextDirection(); |
743 base::i18n::TextDirection direction = textfield_->GetTextDirection(); | |
744 if ((direction == base::i18n::LEFT_TO_RIGHT && | 655 if ((direction == base::i18n::LEFT_TO_RIGHT && |
745 event.key_code() == ui::VKEY_RIGHT) || | 656 event.key_code() == ui::VKEY_RIGHT) || |
746 (direction == base::i18n::RIGHT_TO_LEFT && | 657 (direction == base::i18n::RIGHT_TO_LEFT && |
747 event.key_code() == ui::VKEY_LEFT)) { | 658 event.key_code() == ui::VKEY_LEFT)) { |
748 return model()->CommitSuggestedText(true); | 659 return model()->CommitSuggestedText(true); |
749 } | 660 } |
750 } | 661 } |
751 | 662 |
752 return false; | 663 return false; |
753 } | 664 } |
754 | 665 |
755 void OmniboxViewViews::OnBeforeUserAction(views::Textfield* sender) { | 666 void OmniboxViewViews::OnBeforeUserAction(views::Textfield* sender) { |
756 OnBeforePossibleChange(); | 667 OnBeforePossibleChange(); |
757 } | 668 } |
758 | 669 |
759 void OmniboxViewViews::OnAfterUserAction(views::Textfield* sender) { | 670 void OmniboxViewViews::OnAfterUserAction(views::Textfield* sender) { |
760 OnAfterPossibleChange(); | 671 OnAfterPossibleChange(); |
761 } | 672 } |
762 | 673 |
763 void OmniboxViewViews::OnAfterCutOrCopy() { | 674 void OmniboxViewViews::OnAfterCutOrCopy() { |
764 ui::Range selection_range; | 675 ui::Range selection_range; |
765 textfield_->GetSelectedRange(&selection_range); | 676 GetSelectedRange(&selection_range); |
766 ui::Clipboard* cb = ui::Clipboard::GetForCurrentThread(); | 677 ui::Clipboard* cb = ui::Clipboard::GetForCurrentThread(); |
767 string16 selected_text; | 678 string16 selected_text; |
768 cb->ReadText(ui::Clipboard::BUFFER_STANDARD, &selected_text); | 679 cb->ReadText(ui::Clipboard::BUFFER_STANDARD, &selected_text); |
769 const string16 text = textfield_->text(); | |
770 GURL url; | 680 GURL url; |
771 bool write_url; | 681 bool write_url; |
772 model()->AdjustTextForCopy(selection_range.GetMin(), selected_text == text, | 682 model()->AdjustTextForCopy(selection_range.GetMin(), selected_text == text(), |
773 &selected_text, &url, &write_url); | 683 &selected_text, &url, &write_url); |
774 if (write_url) | 684 if (write_url) { |
775 DoCopyURL(url, selected_text); | 685 DoCopyURL(url, selected_text); |
776 else | 686 } else { |
777 DoCopyText(selected_text); | 687 ui::ScopedClipboardWriter scoped_clipboard_writer( |
688 ui::Clipboard::GetForCurrentThread(), ui::Clipboard::BUFFER_STANDARD); | |
689 scoped_clipboard_writer.WriteText(selected_text); | |
690 } | |
778 } | 691 } |
779 | 692 |
780 void OmniboxViewViews::OnWriteDragData(ui::OSExchangeData* data) { | 693 void OmniboxViewViews::OnWriteDragData(ui::OSExchangeData* data) { |
781 ui::Range selection_range; | 694 ui::Range selection_range; |
782 textfield_->GetSelectedRange(&selection_range); | 695 GetSelectedRange(&selection_range); |
783 string16 selected_text = textfield_->GetSelectedText(); | 696 string16 selected_text = GetSelectedText(); |
784 const string16 text = textfield_->text(); | |
785 GURL url; | 697 GURL url; |
786 bool write_url; | 698 bool write_url; |
787 model()->AdjustTextForCopy(selection_range.start(), selected_text == text, | 699 model()->AdjustTextForCopy(selection_range.start(), selected_text == text(), |
788 &selected_text, &url, &write_url); | 700 &selected_text, &url, &write_url); |
789 data->SetString(selected_text); | 701 data->SetString(selected_text); |
790 if (write_url) | 702 if (write_url) |
791 data->SetURL(url, selected_text); | 703 data->SetURL(url, selected_text); |
792 } | 704 } |
793 | 705 |
794 void OmniboxViewViews::AppendDropFormats( | 706 void OmniboxViewViews::AppendDropFormats( |
795 int* formats, | 707 int* formats, |
796 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { | 708 std::set<ui::OSExchangeData::CustomFormat>* custom_formats) { |
797 *formats = *formats | ui::OSExchangeData::URL; | 709 *formats = *formats | ui::OSExchangeData::URL; |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
888 void OmniboxViewViews::CandidateWindowClosed( | 800 void OmniboxViewViews::CandidateWindowClosed( |
889 chromeos::input_method::InputMethodManager* manager) { | 801 chromeos::input_method::InputMethodManager* manager) { |
890 ime_candidate_window_open_ = false; | 802 ime_candidate_window_open_ = false; |
891 UpdatePopup(); | 803 UpdatePopup(); |
892 } | 804 } |
893 #endif | 805 #endif |
894 | 806 |
895 //////////////////////////////////////////////////////////////////////////////// | 807 //////////////////////////////////////////////////////////////////////////////// |
896 // OmniboxViewViews, private: | 808 // OmniboxViewViews, private: |
897 | 809 |
898 size_t OmniboxViewViews::GetTextLength() const { | 810 int OmniboxViewViews::GetOmniboxTextLength() const { |
899 // TODO(oshima): Support instant, IME. | 811 // TODO(oshima): Support instant, IME. |
900 return textfield_->text().length(); | 812 return static_cast<int>(text().length()); |
901 } | |
902 | |
903 int OmniboxViewViews::GetOmniboxTextLength() const { | |
904 return static_cast<int>(GetTextLength()); | |
905 } | 813 } |
906 | 814 |
907 void OmniboxViewViews::EmphasizeURLComponents() { | 815 void OmniboxViewViews::EmphasizeURLComponents() { |
908 // See whether the contents are a URL with a non-empty host portion, which we | 816 // See whether the contents are a URL with a non-empty host portion, which we |
909 // should emphasize. To check for a URL, rather than using the type returned | 817 // should emphasize. To check for a URL, rather than using the type returned |
910 // by Parse(), ask the model, which will check the desired page transition for | 818 // by Parse(), ask the model, which will check the desired page transition for |
911 // this input. This can tell us whether an UNKNOWN input string is going to | 819 // this input. This can tell us whether an UNKNOWN input string is going to |
912 // be treated as a search or a navigation, and is the same method the Paste | 820 // be treated as a search or a navigation, and is the same method the Paste |
913 // And Go system uses. | 821 // And Go system uses. |
914 string16 text = GetText(); | |
915 url_parse::Component scheme, host; | 822 url_parse::Component scheme, host; |
916 AutocompleteInput::ParseForEmphasizeComponents(text, model()->GetDesiredTLD(), | 823 AutocompleteInput::ParseForEmphasizeComponents( |
917 &scheme, &host); | 824 text(), model()->GetDesiredTLD(), &scheme, &host); |
918 const bool emphasize = model()->CurrentTextIsURL() && (host.len > 0); | 825 const bool emphasize = model()->CurrentTextIsURL() && (host.len > 0); |
919 textfield_->SetColor(location_bar_view_->GetColor(security_level_, | 826 SetColor(location_bar_view_->GetColor(security_level_, |
920 emphasize ? LocationBarView::DEEMPHASIZED_TEXT : LocationBarView::TEXT)); | 827 emphasize ? LocationBarView::DEEMPHASIZED_TEXT : LocationBarView::TEXT)); |
921 if (emphasize) { | 828 if (emphasize) { |
922 textfield_->ApplyColor( | 829 ApplyColor( |
923 location_bar_view_->GetColor(security_level_, LocationBarView::TEXT), | 830 location_bar_view_->GetColor(security_level_, LocationBarView::TEXT), |
924 ui::Range(host.begin, host.end())); | 831 ui::Range(host.begin, host.end())); |
925 } | 832 } |
926 | 833 |
927 // Emphasize the scheme for security UI display purposes (if necessary). | 834 // Emphasize the scheme for security UI display purposes (if necessary). |
928 // Note that we check CurrentTextIsURL() because if we're replacing search | 835 // Note that we check CurrentTextIsURL() because if we're replacing search |
929 // URLs with search terms, we may have a non-URL even when the user is not | 836 // URLs with search terms, we may have a non-URL even when the user is not |
930 // editing; and in some cases, e.g. for "site:foo.com" searches, the parser | 837 // editing; and in some cases, e.g. for "site:foo.com" searches, the parser |
931 // may have incorrectly identified a qualifier as a scheme. | 838 // may have incorrectly identified a qualifier as a scheme. |
932 if (!model()->user_input_in_progress() && model()->CurrentTextIsURL() && | 839 if (!model()->user_input_in_progress() && model()->CurrentTextIsURL() && |
933 scheme.is_nonempty() && (security_level_ != ToolbarModel::NONE)) { | 840 scheme.is_nonempty() && (security_level_ != ToolbarModel::NONE)) { |
934 SkColor security_color = location_bar_view_->GetColor( | 841 SkColor security_color = location_bar_view_->GetColor( |
935 security_level_, LocationBarView::SECURITY_TEXT); | 842 security_level_, LocationBarView::SECURITY_TEXT); |
936 const bool strike = (security_level_ == ToolbarModel::SECURITY_ERROR); | 843 const bool strike = (security_level_ == ToolbarModel::SECURITY_ERROR); |
937 const ui::Range scheme_range(scheme.begin, scheme.end()); | 844 const ui::Range scheme_range(scheme.begin, scheme.end()); |
938 textfield_->ApplyColor(security_color, scheme_range); | 845 ApplyColor(security_color, scheme_range); |
939 textfield_->ApplyStyle(gfx::DIAGONAL_STRIKE, strike, scheme_range); | 846 ApplyStyle(gfx::DIAGONAL_STRIKE, strike, scheme_range); |
940 } | 847 } |
941 } | 848 } |
942 | 849 |
943 void OmniboxViewViews::SetTextAndSelectedRange(const string16& text, | 850 void OmniboxViewViews::SetTextAndSelectedRange(const string16& text, |
944 const ui::Range& range) { | 851 const ui::Range& range) { |
945 if (text != GetText()) | 852 SetText(text); |
946 textfield_->SetText(text); | 853 SelectRange(range); |
947 textfield_->SelectRange(range); | |
948 } | 854 } |
949 | 855 |
950 string16 OmniboxViewViews::GetSelectedText() const { | 856 string16 OmniboxViewViews::GetSelectedText() const { |
951 // TODO(oshima): Support instant, IME. | 857 // TODO(oshima): Support instant, IME. |
952 return textfield_->GetSelectedText(); | 858 return views::Textfield::GetSelectedText(); |
953 } | 859 } |
954 | 860 |
955 void OmniboxViewViews::CopyURL() { | 861 void OmniboxViewViews::CopyURL() { |
956 DoCopyURL(toolbar_model()->GetURL(), toolbar_model()->GetText(false)); | 862 DoCopyURL(toolbar_model()->GetURL(), toolbar_model()->GetText(false)); |
957 } | 863 } |
958 | 864 |
959 void OmniboxViewViews::OnPaste() { | 865 void OmniboxViewViews::OnPaste() { |
960 // Replace the selection if we have something to paste. | 866 // Replace the selection if we have something to paste. |
961 const string16 text(GetClipboardText()); | 867 const string16 text(GetClipboardText()); |
962 if (!text.empty()) { | 868 if (!text.empty()) { |
963 // Record this paste, so we can do different behavior. | 869 // Record this paste, so we can do different behavior. |
964 model()->on_paste(); | 870 model()->on_paste(); |
965 // Force a Paste operation to trigger the text_changed code in | 871 // Force a Paste operation to trigger the text_changed code in |
966 // OnAfterPossibleChange(), even if identical contents are pasted into the | 872 // OnAfterPossibleChange(), even if identical contents are pasted. |
967 // text box. | |
968 text_before_change_.clear(); | 873 text_before_change_.clear(); |
969 textfield_->ReplaceSelection(text); | 874 ReplaceSelection(text); |
970 } | 875 } |
971 } | 876 } |
OLD | NEW |