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