Chromium Code Reviews| 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 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 void OmniboxViewViews::GetAccessibleState(ui::AccessibleViewState* state) { | 212 void OmniboxViewViews::GetAccessibleState(ui::AccessibleViewState* state) { |
| 213 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION); | 213 state->name = l10n_util::GetStringUTF16(IDS_ACCNAME_LOCATION); |
| 214 } | 214 } |
| 215 | 215 |
| 216 void OmniboxViewViews::OnBoundsChanged(const gfx::Rect& previous_bounds) { | 216 void OmniboxViewViews::OnBoundsChanged(const gfx::Rect& previous_bounds) { |
| 217 if (popup_view_->IsOpen()) | 217 if (popup_view_->IsOpen()) |
| 218 popup_view_->UpdatePopupAppearance(); | 218 popup_view_->UpdatePopupAppearance(); |
| 219 } | 219 } |
| 220 | 220 |
| 221 bool OmniboxViewViews::OnMousePressed(const ui::MouseEvent& event) { | 221 bool OmniboxViewViews::OnMousePressed(const ui::MouseEvent& event) { |
| 222 const bool result = views::Textfield::OnMousePressed(event); | |
| 223 select_all_on_mouse_release_ = | 222 select_all_on_mouse_release_ = |
| 224 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && | 223 (event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && |
| 225 (!HasFocus() || (model()->focus_state() == OMNIBOX_FOCUS_INVISIBLE)); | 224 (!HasFocus() || (model()->focus_state() == OMNIBOX_FOCUS_INVISIBLE)); |
| 226 // Restore caret visibility whenever the user clicks in the omnibox in a way | 225 // 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 | 226 // 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 | 227 // if the omnibox currently has invisible focus, the mouse event won't trigger |
| 229 // either SetFocus() or OmniboxEditModel::OnSetFocus(). | 228 // either SetFocus() or OmniboxEditModel::OnSetFocus(). |
| 230 if (select_all_on_mouse_release_) | 229 if (select_all_on_mouse_release_) |
| 231 model()->SetCaretVisibility(true); | 230 model()->SetCaretVisibility(true); |
| 232 return result; | 231 return views::Textfield::OnMousePressed(event); |
|
Peter Kasting
2013/02/19 01:56:24
Does this need a comment about why it's important
msw
2013/02/19 02:14:11
AFAICT the order doesn't matter, I just switched i
| |
| 233 } | 232 } |
| 234 | 233 |
| 235 bool OmniboxViewViews::OnMouseDragged(const ui::MouseEvent& event) { | 234 bool OmniboxViewViews::OnMouseDragged(const ui::MouseEvent& event) { |
| 236 select_all_on_mouse_release_ = false; | 235 select_all_on_mouse_release_ = false; |
| 237 return views::Textfield::OnMouseDragged(event); | 236 return views::Textfield::OnMouseDragged(event); |
| 238 } | 237 } |
| 239 | 238 |
| 240 void OmniboxViewViews::OnMouseReleased(const ui::MouseEvent& event) { | 239 void OmniboxViewViews::OnMouseReleased(const ui::MouseEvent& event) { |
| 241 views::Textfield::OnMouseReleased(event); | 240 views::Textfield::OnMouseReleased(event); |
| 242 if ((event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && | 241 if ((event.IsOnlyLeftMouseButton() || event.IsOnlyRightMouseButton()) && |
| 243 select_all_on_mouse_release_) { | 242 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. | |
|
Peter Kasting
2013/02/19 01:56:24
Why delete this comment?
msw
2013/02/19 02:14:11
I restored it (I thought it might be unnecessary,
| |
| 246 SelectAll(true); | 243 SelectAll(true); |
| 247 } | 244 } |
| 248 select_all_on_mouse_release_ = false; | 245 select_all_on_mouse_release_ = false; |
| 249 } | 246 } |
| 250 | 247 |
| 251 bool OmniboxViewViews::OnKeyPressed(const ui::KeyEvent& event) { | 248 bool OmniboxViewViews::OnKeyPressed(const ui::KeyEvent& event) { |
| 252 // Use our own implementation of paste. See OnPaste() for details. | 249 // Use our own implementation of paste. See OnPaste() for details. |
| 253 if (!read_only() && event.IsControlDown() && | 250 if (!read_only() && event.IsControlDown() && |
| 254 event.key_code() == ui::VKEY_V) { | 251 event.key_code() == ui::VKEY_V) { |
| 255 OnBeforePossibleChange(); | 252 OnBeforePossibleChange(); |
| 256 OnPaste(); | 253 OnPaste(); |
| 257 OnAfterPossibleChange(); | 254 OnAfterPossibleChange(); |
| 258 return true; | 255 return true; |
| 259 } | 256 } |
| 257 | |
| 260 bool handled = views::Textfield::OnKeyPressed(event); | 258 bool handled = views::Textfield::OnKeyPressed(event); |
| 261 | |
| 262 if (event.key_code() == ui::VKEY_RETURN) { | 259 if (event.key_code() == ui::VKEY_RETURN) { |
| 263 bool alt_held = event.IsAltDown(); | 260 bool alt_held = event.IsAltDown(); |
| 264 model()->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); | 261 model()->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); |
| 265 handled = true; | 262 handled = true; |
| 266 } else if (!handled && event.key_code() == ui::VKEY_ESCAPE) { | 263 } else if (!handled && event.key_code() == ui::VKEY_ESCAPE) { |
| 267 // Let the model handle the Escape key or continue its propagation. | 264 // Let the model handle the Escape key or continue its propagation. |
| 268 handled = model()->OnEscapeKeyPressed(); | 265 handled = model()->OnEscapeKeyPressed(); |
| 269 } else if (event.key_code() == ui::VKEY_CONTROL) { | 266 } else if (event.key_code() == ui::VKEY_CONTROL) { |
| 270 // Omnibox2 can switch its contents while pressing a control key. To switch | 267 // Omnibox2 can switch its contents while pressing a control key. To switch |
| 271 // the contents of omnibox2, we notify the OmniboxEditModel class when the | 268 // the contents of omnibox2, we notify the OmniboxEditModel class when the |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 291 handled = model()->AcceptKeyword(); | 288 handled = model()->AcceptKeyword(); |
| 292 } else if (model()->popup_model()->IsOpen()) { | 289 } else if (model()->popup_model()->IsOpen()) { |
| 293 if (event.IsShiftDown() && | 290 if (event.IsShiftDown() && |
| 294 model()->popup_model()->selected_line_state() == | 291 model()->popup_model()->selected_line_state() == |
| 295 OmniboxPopupModel::KEYWORD) { | 292 OmniboxPopupModel::KEYWORD) { |
| 296 model()->ClearKeyword(text()); | 293 model()->ClearKeyword(text()); |
| 297 } else { | 294 } else { |
| 298 model()->OnUpOrDownKeyPressed(event.IsShiftDown() ? -1 : 1); | 295 model()->OnUpOrDownKeyPressed(event.IsShiftDown() ? -1 : 1); |
| 299 } | 296 } |
| 300 handled = true; | 297 handled = true; |
| 301 } else { | |
| 302 string16::size_type start = 0; | |
| 303 string16::size_type end = 0; | |
| 304 const size_t length = text().length(); | |
| 305 GetSelectionBounds(&start, &end); | |
| 306 if (start != end || start < length) { | |
| 307 OnBeforePossibleChange(); | |
| 308 SelectRange(ui::Range(length, length)); | |
| 309 OnAfterPossibleChange(); | |
| 310 handled = true; | |
| 311 } | |
| 312 | |
| 313 // TODO(msw|oshima): Handle Instant. | |
| 314 } | 298 } |
| 315 } | 299 } |
| 316 // TODO(msw|oshima): Handle page up and page down. | 300 // TODO(msw): Handle Instant, tab through popup, tab to search, page up/down. |
| 317 | |
| 318 return handled; | 301 return handled; |
| 319 } | 302 } |
| 320 | 303 |
| 321 bool OmniboxViewViews::OnKeyReleased(const ui::KeyEvent& event) { | 304 bool OmniboxViewViews::OnKeyReleased(const ui::KeyEvent& event) { |
| 322 // Omnibox2 can switch its contents while pressing a control key. To switch | 305 // Omnibox2 can switch its contents while pressing a control key. To switch |
| 323 // the contents of omnibox2, we notify the OmniboxEditModel class when the | 306 // the contents of omnibox2, we notify the OmniboxEditModel class when the |
| 324 // control-key state is changed. | 307 // control-key state is changed. |
| 325 if (event.key_code() == ui::VKEY_CONTROL) { | 308 if (event.key_code() == ui::VKEY_CONTROL) { |
| 326 // TODO(oshima): investigate if we need to support keyboard with two | 309 // TODO(oshima): investigate if we need to support keyboard with two |
| 327 // controls. | 310 // controls. |
| 328 model()->OnControlKeyChanged(false); | 311 model()->OnControlKeyChanged(false); |
| 329 return true; | 312 return true; |
| 330 } | 313 } |
| 331 return false; | 314 return false; |
| 332 } | 315 } |
| 333 | 316 |
| 334 void OmniboxViewViews::OnFocus() { | 317 void OmniboxViewViews::OnFocus() { |
| 335 views::Textfield::OnFocus(); | 318 views::Textfield::OnFocus(); |
| 336 // TODO(oshima): Get control key state. | 319 // TODO(oshima): Get control key state. |
| 337 model()->OnSetFocus(false); | 320 model()->OnSetFocus(false); |
| 338 // Don't call controller()->OnSetFocus as this view has already | 321 // Don't call controller()->OnSetFocus, this view has already acquired focus. |
| 339 // acquired the focus. | 322 |
| 323 // Restore a valid saved selection on tab-to-focus. | |
| 324 if (saved_temporary_selection_.IsValid() && !select_all_on_mouse_release_) | |
| 325 SelectRange(saved_temporary_selection_); | |
| 340 } | 326 } |
| 341 | 327 |
| 342 void OmniboxViewViews::OnBlur() { | 328 void OmniboxViewViews::OnBlur() { |
| 329 // Save the selection to restore on tab-to-focus. | |
| 330 GetSelectedRange(&saved_temporary_selection_); | |
| 331 | |
| 343 views::Textfield::OnBlur(); | 332 views::Textfield::OnBlur(); |
| 344 gfx::NativeView native_view = NULL; | 333 gfx::NativeView native_view = NULL; |
| 345 #if defined(USE_AURA) | 334 #if defined(USE_AURA) |
| 346 views::Widget* widget = GetWidget(); | 335 views::Widget* widget = GetWidget(); |
| 347 if (widget) { | 336 if (widget) { |
| 348 aura::client::FocusClient* client = | 337 aura::client::FocusClient* client = |
| 349 aura::client::GetFocusClient(widget->GetNativeView()); | 338 aura::client::GetFocusClient(widget->GetNativeView()); |
| 350 if (client) | 339 if (client) |
| 351 native_view = client->GetFocusedWindow(); | 340 native_view = client->GetFocusedWindow(); |
| 352 } | 341 } |
| (...skipping 511 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 864 const string16 text(GetClipboardText()); | 853 const string16 text(GetClipboardText()); |
| 865 if (!text.empty()) { | 854 if (!text.empty()) { |
| 866 // Record this paste, so we can do different behavior. | 855 // Record this paste, so we can do different behavior. |
| 867 model()->on_paste(); | 856 model()->on_paste(); |
| 868 // Force a Paste operation to trigger the text_changed code in | 857 // Force a Paste operation to trigger the text_changed code in |
| 869 // OnAfterPossibleChange(), even if identical contents are pasted. | 858 // OnAfterPossibleChange(), even if identical contents are pasted. |
| 870 text_before_change_.clear(); | 859 text_before_change_.clear(); |
| 871 ReplaceSelection(text); | 860 ReplaceSelection(text); |
| 872 } | 861 } |
| 873 } | 862 } |
| OLD | NEW |