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/gtk/omnibox/omnibox_view_gtk.h" | 5 #include "chrome/browser/ui/gtk/omnibox/omnibox_view_gtk.h" |
6 | 6 |
7 #include <gdk/gdkkeysyms.h> | 7 #include <gdk/gdkkeysyms.h> |
8 #include <gtk/gtk.h> | 8 #include <gtk/gtk.h> |
9 | 9 |
10 #include <algorithm> | 10 #include <algorithm> |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
153 } | 153 } |
154 | 154 |
155 } // namespace | 155 } // namespace |
156 | 156 |
157 OmniboxViewGtk::OmniboxViewGtk(OmniboxEditController* controller, | 157 OmniboxViewGtk::OmniboxViewGtk(OmniboxEditController* controller, |
158 ToolbarModel* toolbar_model, | 158 ToolbarModel* toolbar_model, |
159 Browser* browser, | 159 Browser* browser, |
160 CommandUpdater* command_updater, | 160 CommandUpdater* command_updater, |
161 bool popup_window_mode, | 161 bool popup_window_mode, |
162 GtkWidget* location_bar) | 162 GtkWidget* location_bar) |
163 : browser_(browser), | 163 : OmniboxView(browser->profile(), controller, toolbar_model, |
| 164 command_updater), |
| 165 browser_(browser), |
164 text_view_(NULL), | 166 text_view_(NULL), |
165 tag_table_(NULL), | 167 tag_table_(NULL), |
166 text_buffer_(NULL), | 168 text_buffer_(NULL), |
167 faded_text_tag_(NULL), | 169 faded_text_tag_(NULL), |
168 secure_scheme_tag_(NULL), | 170 secure_scheme_tag_(NULL), |
169 security_error_scheme_tag_(NULL), | 171 security_error_scheme_tag_(NULL), |
170 normal_text_tag_(NULL), | 172 normal_text_tag_(NULL), |
171 instant_anchor_tag_(NULL), | 173 instant_anchor_tag_(NULL), |
172 instant_view_(NULL), | 174 instant_view_(NULL), |
173 instant_mark_(NULL), | 175 instant_mark_(NULL), |
174 model_(new OmniboxEditModel(this, controller, browser->profile())), | |
175 controller_(controller), | |
176 toolbar_model_(toolbar_model), | |
177 command_updater_(command_updater), | |
178 popup_window_mode_(popup_window_mode), | 176 popup_window_mode_(popup_window_mode), |
179 security_level_(ToolbarModel::NONE), | 177 security_level_(ToolbarModel::NONE), |
180 mark_set_handler_id_(0), | 178 mark_set_handler_id_(0), |
181 button_1_pressed_(false), | 179 button_1_pressed_(false), |
182 theme_service_(GtkThemeService::GetFrom(browser->profile())), | 180 theme_service_(GtkThemeService::GetFrom(browser->profile())), |
183 enter_was_pressed_(false), | 181 enter_was_pressed_(false), |
184 tab_was_pressed_(false), | 182 tab_was_pressed_(false), |
185 paste_clipboard_requested_(false), | 183 paste_clipboard_requested_(false), |
186 enter_was_inserted_(false), | 184 enter_was_inserted_(false), |
187 selection_suggested_(false), | 185 selection_suggested_(false), |
188 delete_was_pressed_(false), | 186 delete_was_pressed_(false), |
189 delete_at_end_pressed_(false), | 187 delete_at_end_pressed_(false), |
190 handling_key_press_(false), | 188 handling_key_press_(false), |
191 content_maybe_changed_by_key_press_(false), | 189 content_maybe_changed_by_key_press_(false), |
192 update_popup_without_focus_(false), | 190 update_popup_without_focus_(false), |
193 supports_pre_edit_(!gtk_check_version(2, 20, 0)), | 191 supports_pre_edit_(!gtk_check_version(2, 20, 0)), |
194 pre_edit_size_before_change_(0), | 192 pre_edit_size_before_change_(0), |
195 going_to_focus_(NULL) { | 193 going_to_focus_(NULL) { |
196 popup_view_.reset( | 194 popup_view_.reset( |
197 new OmniboxPopupViewGtk | 195 new OmniboxPopupViewGtk |
198 (GetFont(), this, model_.get(), location_bar)); | 196 (GetFont(), this, model(), location_bar)); |
199 } | 197 } |
200 | 198 |
201 OmniboxViewGtk::~OmniboxViewGtk() { | 199 OmniboxViewGtk::~OmniboxViewGtk() { |
202 // Explicitly teardown members which have a reference to us. Just to be safe | 200 // Explicitly teardown members which have a reference to us. Just to be safe |
203 // we want them to be destroyed before destroying any other internal state. | 201 // we want them to be destroyed before destroying any other internal state. |
204 popup_view_.reset(); | 202 popup_view_.reset(); |
205 model_.reset(); | |
206 | 203 |
207 // We own our widget and TextView related objects. | 204 // We own our widget and TextView related objects. |
208 if (alignment_.get()) { // Init() has been called. | 205 if (alignment_.get()) { // Init() has been called. |
209 alignment_.Destroy(); | 206 alignment_.Destroy(); |
210 g_object_unref(text_buffer_); | 207 g_object_unref(text_buffer_); |
211 g_object_unref(tag_table_); | 208 g_object_unref(tag_table_); |
212 // The tags we created are owned by the tag_table, and should be destroyed | 209 // The tags we created are owned by the tag_table, and should be destroyed |
213 // along with it. We don't hold our own reference to them. | 210 // along with it. We don't hold our own reference to them. |
214 } | 211 } |
215 } | 212 } |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 void OmniboxViewGtk::SetFocus() { | 412 void OmniboxViewGtk::SetFocus() { |
416 DCHECK(text_view_); | 413 DCHECK(text_view_); |
417 gtk_widget_grab_focus(text_view_); | 414 gtk_widget_grab_focus(text_view_); |
418 } | 415 } |
419 | 416 |
420 int OmniboxViewGtk::WidthOfTextAfterCursor() { | 417 int OmniboxViewGtk::WidthOfTextAfterCursor() { |
421 // Not used. | 418 // Not used. |
422 return -1; | 419 return -1; |
423 } | 420 } |
424 | 421 |
425 OmniboxEditModel* OmniboxViewGtk::model() { | |
426 return model_.get(); | |
427 } | |
428 | |
429 const OmniboxEditModel* OmniboxViewGtk::model() const { | |
430 return model_.get(); | |
431 } | |
432 | |
433 void OmniboxViewGtk::SaveStateToTab(WebContents* tab) { | 422 void OmniboxViewGtk::SaveStateToTab(WebContents* tab) { |
434 DCHECK(tab); | 423 DCHECK(tab); |
435 // If any text has been selected, register it as the PRIMARY selection so it | 424 // If any text has been selected, register it as the PRIMARY selection so it |
436 // can still be pasted via middle-click after the text view is cleared. | 425 // can still be pasted via middle-click after the text view is cleared. |
437 if (!selected_text_.empty()) | 426 if (!selected_text_.empty()) |
438 SavePrimarySelection(selected_text_); | 427 SavePrimarySelection(selected_text_); |
439 // NOTE: GetStateForTabSwitch may affect GetSelection, so order is important. | 428 // NOTE: GetStateForTabSwitch may affect GetSelection, so order is important. |
440 OmniboxEditModel::State model_state = model_->GetStateForTabSwitch(); | 429 OmniboxEditModel::State model_state = model()->GetStateForTabSwitch(); |
441 GetStateAccessor()->SetProperty( | 430 GetStateAccessor()->SetProperty( |
442 tab->GetPropertyBag(), | 431 tab->GetPropertyBag(), |
443 AutocompleteEditState(model_state, ViewState(GetSelection()))); | 432 AutocompleteEditState(model_state, ViewState(GetSelection()))); |
444 } | 433 } |
445 | 434 |
446 void OmniboxViewGtk::Update(const WebContents* contents) { | 435 void OmniboxViewGtk::Update(const WebContents* contents) { |
447 // NOTE: We're getting the URL text here from the ToolbarModel. | 436 // NOTE: We're getting the URL text here from the ToolbarModel. |
448 bool visibly_changed_permanent_text = | 437 bool visibly_changed_permanent_text = |
449 model_->UpdatePermanentText(toolbar_model_->GetText()); | 438 model()->UpdatePermanentText(toolbar_model()->GetText()); |
450 | 439 |
451 ToolbarModel::SecurityLevel security_level = | 440 ToolbarModel::SecurityLevel security_level = |
452 toolbar_model_->GetSecurityLevel(); | 441 toolbar_model()->GetSecurityLevel(); |
453 bool changed_security_level = (security_level != security_level_); | 442 bool changed_security_level = (security_level != security_level_); |
454 security_level_ = security_level; | 443 security_level_ = security_level; |
455 | 444 |
456 if (contents) { | 445 if (contents) { |
457 selected_text_.clear(); | 446 selected_text_.clear(); |
458 RevertAll(); | 447 RevertAll(); |
459 const AutocompleteEditState* state = | 448 const AutocompleteEditState* state = |
460 GetStateAccessor()->GetProperty(contents->GetPropertyBag()); | 449 GetStateAccessor()->GetProperty(contents->GetPropertyBag()); |
461 if (state) { | 450 if (state) { |
462 model_->RestoreState(state->model_state); | 451 model()->RestoreState(state->model_state); |
463 | 452 |
464 // Move the marks for the cursor and the other end of the selection to | 453 // Move the marks for the cursor and the other end of the selection to |
465 // the previously-saved offsets (but preserve PRIMARY). | 454 // the previously-saved offsets (but preserve PRIMARY). |
466 StartUpdatingHighlightedText(); | 455 StartUpdatingHighlightedText(); |
467 SetSelectedRange(state->view_state.selection_range); | 456 SetSelectedRange(state->view_state.selection_range); |
468 FinishUpdatingHighlightedText(); | 457 FinishUpdatingHighlightedText(); |
469 } | 458 } |
470 } else if (visibly_changed_permanent_text) { | 459 } else if (visibly_changed_permanent_text) { |
471 RevertAll(); | 460 RevertAll(); |
472 // TODO(deanm): There should be code to restore select all here. | 461 // TODO(deanm): There should be code to restore select all here. |
473 } else if (changed_security_level) { | 462 } else if (changed_security_level) { |
474 EmphasizeURLComponents(); | 463 EmphasizeURLComponents(); |
475 } | 464 } |
476 } | 465 } |
477 | 466 |
478 void OmniboxViewGtk::OpenMatch(const AutocompleteMatch& match, | |
479 WindowOpenDisposition disposition, | |
480 const GURL& alternate_nav_url, | |
481 size_t selected_line) { | |
482 if (!match.destination_url.is_valid()) | |
483 return; | |
484 | |
485 model_->OpenMatch(match, disposition, alternate_nav_url, selected_line); | |
486 } | |
487 | |
488 string16 OmniboxViewGtk::GetText() const { | 467 string16 OmniboxViewGtk::GetText() const { |
489 GtkTextIter start, end; | 468 GtkTextIter start, end; |
490 GetTextBufferBounds(&start, &end); | 469 GetTextBufferBounds(&start, &end); |
491 gchar* utf8 = gtk_text_buffer_get_text(text_buffer_, &start, &end, false); | 470 gchar* utf8 = gtk_text_buffer_get_text(text_buffer_, &start, &end, false); |
492 string16 out(UTF8ToUTF16(utf8)); | 471 string16 out(UTF8ToUTF16(utf8)); |
493 g_free(utf8); | 472 g_free(utf8); |
494 | 473 |
495 if (supports_pre_edit_) { | 474 if (supports_pre_edit_) { |
496 // We need to treat the text currently being composed by the input method | 475 // We need to treat the text currently being composed by the input method |
497 // as part of the text content, so that omnibox can work correctly in the | 476 // as part of the text content, so that omnibox can work correctly in the |
498 // middle of composition. | 477 // middle of composition. |
499 if (pre_edit_.size()) { | 478 if (pre_edit_.size()) { |
500 GtkTextMark* mark = gtk_text_buffer_get_insert(text_buffer_); | 479 GtkTextMark* mark = gtk_text_buffer_get_insert(text_buffer_); |
501 gtk_text_buffer_get_iter_at_mark(text_buffer_, &start, mark); | 480 gtk_text_buffer_get_iter_at_mark(text_buffer_, &start, mark); |
502 out.insert(gtk_text_iter_get_offset(&start), pre_edit_); | 481 out.insert(gtk_text_iter_get_offset(&start), pre_edit_); |
503 } | 482 } |
504 } | 483 } |
505 return out; | 484 return out; |
506 } | 485 } |
507 | 486 |
508 bool OmniboxViewGtk::IsEditingOrEmpty() const { | |
509 return model_->user_input_in_progress() || (GetTextLength() == 0); | |
510 } | |
511 | |
512 int OmniboxViewGtk::GetIcon() const { | |
513 return IsEditingOrEmpty() ? | |
514 AutocompleteMatch::TypeToIcon(model_->CurrentTextType()) : | |
515 toolbar_model_->GetIcon(); | |
516 } | |
517 | |
518 void OmniboxViewGtk::SetUserText(const string16& text) { | |
519 SetUserText(text, text, true); | |
520 } | |
521 | |
522 void OmniboxViewGtk::SetUserText(const string16& text, | |
523 const string16& display_text, | |
524 bool update_popup) { | |
525 model_->SetUserText(text); | |
526 // TODO(deanm): something about selection / focus change here. | |
527 SetWindowTextAndCaretPos(display_text, display_text.length(), update_popup, | |
528 true); | |
529 } | |
530 | |
531 void OmniboxViewGtk::SetWindowTextAndCaretPos(const string16& text, | 487 void OmniboxViewGtk::SetWindowTextAndCaretPos(const string16& text, |
532 size_t caret_pos, | 488 size_t caret_pos, |
533 bool update_popup, | 489 bool update_popup, |
534 bool notify_text_changed) { | 490 bool notify_text_changed) { |
535 CharRange range(static_cast<int>(caret_pos), static_cast<int>(caret_pos)); | 491 CharRange range(static_cast<int>(caret_pos), static_cast<int>(caret_pos)); |
536 SetTextAndSelectedRange(text, range); | 492 SetTextAndSelectedRange(text, range); |
537 | 493 |
538 if (update_popup) | 494 if (update_popup) |
539 UpdatePopup(); | 495 UpdatePopup(); |
540 | 496 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 *end = static_cast<size_t>(selection.cp_max); | 533 *end = static_cast<size_t>(selection.cp_max); |
578 } | 534 } |
579 | 535 |
580 void OmniboxViewGtk::SelectAll(bool reversed) { | 536 void OmniboxViewGtk::SelectAll(bool reversed) { |
581 // SelectAll() is invoked as a side effect of other actions (e.g. switching | 537 // SelectAll() is invoked as a side effect of other actions (e.g. switching |
582 // tabs or hitting Escape) in autocomplete_edit.cc, so we don't update the | 538 // tabs or hitting Escape) in autocomplete_edit.cc, so we don't update the |
583 // PRIMARY selection here. | 539 // PRIMARY selection here. |
584 SelectAllInternal(reversed, false); | 540 SelectAllInternal(reversed, false); |
585 } | 541 } |
586 | 542 |
587 void OmniboxViewGtk::RevertAll() { | |
588 ClosePopup(); | |
589 model_->Revert(); | |
590 TextChanged(); | |
591 } | |
592 | |
593 void OmniboxViewGtk::UpdatePopup() { | 543 void OmniboxViewGtk::UpdatePopup() { |
594 model_->SetInputInProgress(true); | 544 model()->SetInputInProgress(true); |
595 if (!update_popup_without_focus_ && !model_->has_focus()) | 545 if (!update_popup_without_focus_ && !model()->has_focus()) |
596 return; | 546 return; |
597 | 547 |
598 // Don't inline autocomplete when the caret/selection isn't at the end of | 548 // Don't inline autocomplete when the caret/selection isn't at the end of |
599 // the text, or in the middle of composition. | 549 // the text, or in the middle of composition. |
600 CharRange sel = GetSelection(); | 550 CharRange sel = GetSelection(); |
601 bool no_inline_autocomplete = | 551 bool no_inline_autocomplete = |
602 std::max(sel.cp_max, sel.cp_min) < GetTextLength() || IsImeComposing(); | 552 std::max(sel.cp_max, sel.cp_min) < GetOmniboxTextLength() || |
603 model_->StartAutocomplete(sel.cp_min != sel.cp_max, no_inline_autocomplete); | 553 IsImeComposing(); |
604 } | 554 model()->StartAutocomplete(sel.cp_min != sel.cp_max, no_inline_autocomplete); |
605 | |
606 void OmniboxViewGtk::ClosePopup() { | |
607 model_->StopAutocomplete(); | |
608 } | 555 } |
609 | 556 |
610 void OmniboxViewGtk::OnTemporaryTextMaybeChanged( | 557 void OmniboxViewGtk::OnTemporaryTextMaybeChanged( |
611 const string16& display_text, | 558 const string16& display_text, |
612 bool save_original_selection) { | 559 bool save_original_selection) { |
613 if (save_original_selection) | 560 if (save_original_selection) |
614 saved_temporary_selection_ = GetSelection(); | 561 saved_temporary_selection_ = GetSelection(); |
615 | 562 |
616 StartUpdatingHighlightedText(); | 563 StartUpdatingHighlightedText(); |
617 SetWindowTextAndCaretPos(display_text, display_text.length(), false, false); | 564 SetWindowTextAndCaretPos(display_text, display_text.length(), false, false); |
(...skipping 19 matching lines...) Expand all Loading... |
637 StartUpdatingHighlightedText(); | 584 StartUpdatingHighlightedText(); |
638 SetSelectedRange(saved_temporary_selection_); | 585 SetSelectedRange(saved_temporary_selection_); |
639 FinishUpdatingHighlightedText(); | 586 FinishUpdatingHighlightedText(); |
640 TextChanged(); | 587 TextChanged(); |
641 } | 588 } |
642 | 589 |
643 void OmniboxViewGtk::OnBeforePossibleChange() { | 590 void OmniboxViewGtk::OnBeforePossibleChange() { |
644 // Record this paste, so we can do different behavior. | 591 // Record this paste, so we can do different behavior. |
645 if (paste_clipboard_requested_) { | 592 if (paste_clipboard_requested_) { |
646 paste_clipboard_requested_ = false; | 593 paste_clipboard_requested_ = false; |
647 model_->on_paste(); | 594 model()->on_paste(); |
648 } | 595 } |
649 | 596 |
650 // This method will be called in HandleKeyPress() method just before | 597 // This method will be called in HandleKeyPress() method just before |
651 // handling a key press event. So we should prevent it from being called | 598 // handling a key press event. So we should prevent it from being called |
652 // when handling the key press event. | 599 // when handling the key press event. |
653 if (handling_key_press_) | 600 if (handling_key_press_) |
654 return; | 601 return; |
655 | 602 |
656 // Record our state. | 603 // Record our state. |
657 text_before_change_ = GetText(); | 604 text_before_change_ = GetText(); |
(...skipping 17 matching lines...) Expand all Loading... |
675 // {Start|Finish}UpdatingHighlightedText() are called here to prevent the | 622 // {Start|Finish}UpdatingHighlightedText() are called here to prevent the |
676 // PRIMARY selection from being changed. | 623 // PRIMARY selection from being changed. |
677 if (enter_was_pressed_ && enter_was_inserted_) { | 624 if (enter_was_pressed_ && enter_was_inserted_) { |
678 StartUpdatingHighlightedText(); | 625 StartUpdatingHighlightedText(); |
679 SetTextAndSelectedRange(text_before_change_, sel_before_change_); | 626 SetTextAndSelectedRange(text_before_change_, sel_before_change_); |
680 FinishUpdatingHighlightedText(); | 627 FinishUpdatingHighlightedText(); |
681 return false; | 628 return false; |
682 } | 629 } |
683 | 630 |
684 const CharRange new_sel = GetSelection(); | 631 const CharRange new_sel = GetSelection(); |
685 const int length = GetTextLength(); | 632 const int length = GetOmniboxTextLength(); |
686 const bool selection_differs = | 633 const bool selection_differs = |
687 ((new_sel.cp_min != new_sel.cp_max) || | 634 ((new_sel.cp_min != new_sel.cp_max) || |
688 (sel_before_change_.cp_min != sel_before_change_.cp_max)) && | 635 (sel_before_change_.cp_min != sel_before_change_.cp_max)) && |
689 ((new_sel.cp_min != sel_before_change_.cp_min) || | 636 ((new_sel.cp_min != sel_before_change_.cp_min) || |
690 (new_sel.cp_max != sel_before_change_.cp_max)); | 637 (new_sel.cp_max != sel_before_change_.cp_max)); |
691 const bool at_end_of_edit = | 638 const bool at_end_of_edit = |
692 (new_sel.cp_min == length && new_sel.cp_max == length); | 639 (new_sel.cp_min == length && new_sel.cp_max == length); |
693 | 640 |
694 // See if the text or selection have changed since OnBeforePossibleChange(). | 641 // See if the text or selection have changed since OnBeforePossibleChange(). |
695 const string16 new_text(GetText()); | 642 const string16 new_text(GetText()); |
696 text_changed_ = (new_text != text_before_change_) || (supports_pre_edit_ && | 643 text_changed_ = (new_text != text_before_change_) || (supports_pre_edit_ && |
697 (pre_edit_.size() != pre_edit_size_before_change_)); | 644 (pre_edit_.size() != pre_edit_size_before_change_)); |
698 | 645 |
699 if (text_changed_) | 646 if (text_changed_) |
700 AdjustTextJustification(); | 647 AdjustTextJustification(); |
701 | 648 |
702 // When the user has deleted text, we don't allow inline autocomplete. Make | 649 // When the user has deleted text, we don't allow inline autocomplete. Make |
703 // sure to not flag cases like selecting part of the text and then pasting | 650 // sure to not flag cases like selecting part of the text and then pasting |
704 // (or typing) the prefix of that selection. (We detect these by making | 651 // (or typing) the prefix of that selection. (We detect these by making |
705 // sure the caret, which should be after any insertion, hasn't moved | 652 // sure the caret, which should be after any insertion, hasn't moved |
706 // forward of the old selection start.) | 653 // forward of the old selection start.) |
707 const bool just_deleted_text = | 654 const bool just_deleted_text = |
708 (text_before_change_.length() > new_text.length()) && | 655 (text_before_change_.length() > new_text.length()) && |
709 (new_sel.cp_min <= std::min(sel_before_change_.cp_min, | 656 (new_sel.cp_min <= std::min(sel_before_change_.cp_min, |
710 sel_before_change_.cp_max)); | 657 sel_before_change_.cp_max)); |
711 | 658 |
712 delete_at_end_pressed_ = false; | 659 delete_at_end_pressed_ = false; |
713 | 660 |
714 const bool something_changed = model_->OnAfterPossibleChange( | 661 const bool something_changed = model()->OnAfterPossibleChange( |
715 text_before_change_, new_text, new_sel.selection_min(), | 662 text_before_change_, new_text, new_sel.selection_min(), |
716 new_sel.selection_max(), selection_differs, text_changed_, | 663 new_sel.selection_max(), selection_differs, text_changed_, |
717 just_deleted_text, !IsImeComposing()); | 664 just_deleted_text, !IsImeComposing()); |
718 | 665 |
719 // If only selection was changed, we don't need to call |controller_|'s | 666 // If only selection was changed, we don't need to call the controller's |
720 // OnChanged() method, which is called in TextChanged(). | 667 // OnChanged() method, which is called in TextChanged(). |
721 // But we still need to call EmphasizeURLComponents() to make sure the text | 668 // But we still need to call EmphasizeURLComponents() to make sure the text |
722 // attributes are updated correctly. | 669 // attributes are updated correctly. |
723 if (something_changed && text_changed_) { | 670 if (something_changed && text_changed_) { |
724 TextChanged(); | 671 TextChanged(); |
725 } else if (selection_differs) { | 672 } else if (selection_differs) { |
726 EmphasizeURLComponents(); | 673 EmphasizeURLComponents(); |
727 } else if (delete_was_pressed_ && at_end_of_edit) { | 674 } else if (delete_was_pressed_ && at_end_of_edit) { |
728 delete_at_end_pressed_ = true; | 675 delete_at_end_pressed_ = true; |
729 model_->OnChanged(); | 676 model()->OnChanged(); |
730 } | 677 } |
731 delete_was_pressed_ = false; | 678 delete_was_pressed_ = false; |
732 | 679 |
733 return something_changed; | 680 return something_changed; |
734 } | 681 } |
735 | 682 |
736 gfx::NativeView OmniboxViewGtk::GetNativeView() const { | 683 gfx::NativeView OmniboxViewGtk::GetNativeView() const { |
737 return alignment_.get(); | 684 return alignment_.get(); |
738 } | 685 } |
739 | 686 |
740 gfx::NativeView OmniboxViewGtk::GetRelativeWindowForPopup() const { | 687 gfx::NativeView OmniboxViewGtk::GetRelativeWindowForPopup() const { |
741 GtkWidget* toplevel = gtk_widget_get_toplevel(GetNativeView()); | 688 GtkWidget* toplevel = gtk_widget_get_toplevel(GetNativeView()); |
742 DCHECK(gtk_widget_is_toplevel(toplevel)); | 689 DCHECK(gtk_widget_is_toplevel(toplevel)); |
743 return toplevel; | 690 return toplevel; |
744 } | 691 } |
745 | 692 |
746 CommandUpdater* OmniboxViewGtk::GetCommandUpdater() { | |
747 return command_updater_; | |
748 } | |
749 | |
750 void OmniboxViewGtk::SetInstantSuggestion(const string16& suggestion, | 693 void OmniboxViewGtk::SetInstantSuggestion(const string16& suggestion, |
751 bool animate_to_complete) { | 694 bool animate_to_complete) { |
752 std::string suggestion_utf8 = UTF16ToUTF8(suggestion); | 695 std::string suggestion_utf8 = UTF16ToUTF8(suggestion); |
753 | 696 |
754 gtk_label_set_text(GTK_LABEL(instant_view_), suggestion_utf8.c_str()); | 697 gtk_label_set_text(GTK_LABEL(instant_view_), suggestion_utf8.c_str()); |
755 | 698 |
756 StopAnimation(); | 699 StopAnimation(); |
757 | 700 |
758 if (suggestion.empty()) { | 701 if (suggestion.empty()) { |
759 gtk_widget_hide(instant_view_); | 702 gtk_widget_hide(instant_view_); |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
828 | 771 |
829 void OmniboxViewGtk::Observe(int type, | 772 void OmniboxViewGtk::Observe(int type, |
830 const content::NotificationSource& source, | 773 const content::NotificationSource& source, |
831 const content::NotificationDetails& details) { | 774 const content::NotificationDetails& details) { |
832 DCHECK(type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED); | 775 DCHECK(type == chrome::NOTIFICATION_BROWSER_THEME_CHANGED); |
833 | 776 |
834 SetBaseColor(); | 777 SetBaseColor(); |
835 } | 778 } |
836 | 779 |
837 void OmniboxViewGtk::AnimationEnded(const ui::Animation* animation) { | 780 void OmniboxViewGtk::AnimationEnded(const ui::Animation* animation) { |
838 model_->CommitSuggestedText(false); | 781 model()->CommitSuggestedText(false); |
839 } | 782 } |
840 | 783 |
841 void OmniboxViewGtk::AnimationProgressed(const ui::Animation* animation) { | 784 void OmniboxViewGtk::AnimationProgressed(const ui::Animation* animation) { |
842 UpdateInstantViewColors(); | 785 UpdateInstantViewColors(); |
843 } | 786 } |
844 | 787 |
845 void OmniboxViewGtk::AnimationCanceled(const ui::Animation* animation) { | 788 void OmniboxViewGtk::AnimationCanceled(const ui::Animation* animation) { |
846 UpdateInstantViewColors(); | 789 UpdateInstantViewColors(); |
847 } | 790 } |
848 | 791 |
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1060 handling_key_press_ = false; | 1003 handling_key_press_ = false; |
1061 if (content_maybe_changed_by_key_press_) | 1004 if (content_maybe_changed_by_key_press_) |
1062 OnAfterPossibleChange(); | 1005 OnAfterPossibleChange(); |
1063 | 1006 |
1064 // Set |tab_was_pressed_| to false, to make sure Tab to search behavior can | 1007 // Set |tab_was_pressed_| to false, to make sure Tab to search behavior can |
1065 // only be triggered by pressing Tab key. | 1008 // only be triggered by pressing Tab key. |
1066 tab_was_pressed_ = false; | 1009 tab_was_pressed_ = false; |
1067 | 1010 |
1068 if (enter_was_pressed_ && enter_was_inserted_) { | 1011 if (enter_was_pressed_ && enter_was_inserted_) { |
1069 bool alt_held = (event->state & GDK_MOD1_MASK); | 1012 bool alt_held = (event->state & GDK_MOD1_MASK); |
1070 model_->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); | 1013 model()->AcceptInput(alt_held ? NEW_FOREGROUND_TAB : CURRENT_TAB, false); |
1071 result = TRUE; | 1014 result = TRUE; |
1072 } else if (!result && event->keyval == GDK_Escape && | 1015 } else if (!result && event->keyval == GDK_Escape && |
1073 (event->state & gtk_accelerator_get_default_mod_mask()) == 0) { | 1016 (event->state & gtk_accelerator_get_default_mod_mask()) == 0) { |
1074 // We can handle the Escape key if |text_view_| did not handle it. | 1017 // We can handle the Escape key if |text_view_| did not handle it. |
1075 // If it's not handled by us, then we need to propagate it up to the parent | 1018 // If it's not handled by us, then we need to propagate it up to the parent |
1076 // widgets, so that Escape accelerator can still work. | 1019 // widgets, so that Escape accelerator can still work. |
1077 result = model_->OnEscapeKeyPressed(); | 1020 result = model()->OnEscapeKeyPressed(); |
1078 } else if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) { | 1021 } else if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) { |
1079 // Omnibox2 can switch its contents while pressing a control key. To switch | 1022 // Omnibox2 can switch its contents while pressing a control key. To switch |
1080 // the contents of omnibox2, we notify the OmniboxEditModel class when the | 1023 // the contents of omnibox2, we notify the OmniboxEditModel class when the |
1081 // control-key state is changed. | 1024 // control-key state is changed. |
1082 model_->OnControlKeyChanged(true); | 1025 model()->OnControlKeyChanged(true); |
1083 } else if (!text_changed_ && event->keyval == GDK_Delete && | 1026 } else if (!text_changed_ && event->keyval == GDK_Delete && |
1084 event->state & GDK_SHIFT_MASK) { | 1027 event->state & GDK_SHIFT_MASK) { |
1085 // If shift+del didn't change the text, we let this delete an entry from | 1028 // If shift+del didn't change the text, we let this delete an entry from |
1086 // the popup. We can't check to see if the IME handled it because even if | 1029 // the popup. We can't check to see if the IME handled it because even if |
1087 // nothing is selected, the IME or the TextView still report handling it. | 1030 // nothing is selected, the IME or the TextView still report handling it. |
1088 if (model_->popup_model()->IsOpen()) | 1031 if (model()->popup_model()->IsOpen()) |
1089 model_->popup_model()->TryDeletingCurrentItem(); | 1032 model()->popup_model()->TryDeletingCurrentItem(); |
1090 } | 1033 } |
1091 | 1034 |
1092 // Set |enter_was_pressed_| to false, to make sure OnAfterPossibleChange() can | 1035 // Set |enter_was_pressed_| to false, to make sure OnAfterPossibleChange() can |
1093 // act as normal for changes made by other events. | 1036 // act as normal for changes made by other events. |
1094 enter_was_pressed_ = false; | 1037 enter_was_pressed_ = false; |
1095 | 1038 |
1096 // If the key event is not handled by |text_view_| or us, then we need to | 1039 // If the key event is not handled by |text_view_| or us, then we need to |
1097 // propagate the key event up to parent widgets by returning FALSE. | 1040 // propagate the key event up to parent widgets by returning FALSE. |
1098 // In this case we need to stop the signal emission explicitly to prevent the | 1041 // In this case we need to stop the signal emission explicitly to prevent the |
1099 // default "key-press-event" handler of |text_view_| from being called again. | 1042 // default "key-press-event" handler of |text_view_| from being called again. |
(...skipping 11 matching lines...) Expand all Loading... |
1111 // Omnibox2 can switch its contents while pressing a control key. To switch | 1054 // Omnibox2 can switch its contents while pressing a control key. To switch |
1112 // the contents of omnibox2, we notify the OmniboxEditModel class when the | 1055 // the contents of omnibox2, we notify the OmniboxEditModel class when the |
1113 // control-key state is changed. | 1056 // control-key state is changed. |
1114 if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) { | 1057 if (event->keyval == GDK_Control_L || event->keyval == GDK_Control_R) { |
1115 // Round trip to query the control state after the release. This allows | 1058 // Round trip to query the control state after the release. This allows |
1116 // you to release one control key while still holding another control key. | 1059 // you to release one control key while still holding another control key. |
1117 GdkDisplay* display = gdk_window_get_display(event->window); | 1060 GdkDisplay* display = gdk_window_get_display(event->window); |
1118 GdkModifierType mod; | 1061 GdkModifierType mod; |
1119 gdk_display_get_pointer(display, NULL, NULL, NULL, &mod); | 1062 gdk_display_get_pointer(display, NULL, NULL, NULL, &mod); |
1120 if (!(mod & GDK_CONTROL_MASK)) | 1063 if (!(mod & GDK_CONTROL_MASK)) |
1121 model_->OnControlKeyChanged(false); | 1064 model()->OnControlKeyChanged(false); |
1122 } | 1065 } |
1123 | 1066 |
1124 // Even though we handled the press ourselves, let GtkTextView handle the | 1067 // Even though we handled the press ourselves, let GtkTextView handle the |
1125 // release. It shouldn't do anything particularly interesting, but it will | 1068 // release. It shouldn't do anything particularly interesting, but it will |
1126 // handle the IME work for us. | 1069 // handle the IME work for us. |
1127 return FALSE; // Propagate into GtkTextView. | 1070 return FALSE; // Propagate into GtkTextView. |
1128 } | 1071 } |
1129 | 1072 |
1130 gboolean OmniboxViewGtk::HandleViewButtonPress(GtkWidget* sender, | 1073 gboolean OmniboxViewGtk::HandleViewButtonPress(GtkWidget* sender, |
1131 GdkEventButton* event) { | 1074 GdkEventButton* event) { |
1132 // We don't need to care about double and triple clicks. | 1075 // We don't need to care about double and triple clicks. |
1133 if (event->type != GDK_BUTTON_PRESS) | 1076 if (event->type != GDK_BUTTON_PRESS) |
1134 return FALSE; | 1077 return FALSE; |
1135 | 1078 |
1136 DCHECK(text_view_); | 1079 DCHECK(text_view_); |
1137 | 1080 |
1138 if (event->button == 1) { | 1081 if (event->button == 1) { |
1139 button_1_pressed_ = true; | 1082 button_1_pressed_ = true; |
1140 | 1083 |
1141 // Button press event may change the selection, we need to record the change | 1084 // Button press event may change the selection, we need to record the change |
1142 // and report it to |model_| later when button is released. | 1085 // and report it to model() later when button is released. |
1143 OnBeforePossibleChange(); | 1086 OnBeforePossibleChange(); |
1144 } else if (event->button == 2) { | 1087 } else if (event->button == 2) { |
1145 // GtkTextView pastes PRIMARY selection with middle click. | 1088 // GtkTextView pastes PRIMARY selection with middle click. |
1146 // We can't call model_->on_paste_replacing_all() here, because the actual | 1089 // We can't call model()->on_paste_replacing_all() here, because the actual |
1147 // paste clipboard action may not be performed if the clipboard is empty. | 1090 // paste clipboard action may not be performed if the clipboard is empty. |
1148 paste_clipboard_requested_ = true; | 1091 paste_clipboard_requested_ = true; |
1149 } | 1092 } |
1150 return FALSE; | 1093 return FALSE; |
1151 } | 1094 } |
1152 | 1095 |
1153 gboolean OmniboxViewGtk::HandleViewButtonRelease(GtkWidget* sender, | 1096 gboolean OmniboxViewGtk::HandleViewButtonRelease(GtkWidget* sender, |
1154 GdkEventButton* event) { | 1097 GdkEventButton* event) { |
1155 if (event->button != 1) | 1098 if (event->button != 1) |
1156 return FALSE; | 1099 return FALSE; |
1157 | 1100 |
1158 bool button_1_was_pressed = button_1_pressed_; | 1101 bool button_1_was_pressed = button_1_pressed_; |
1159 button_1_pressed_ = false; | 1102 button_1_pressed_ = false; |
1160 | 1103 |
1161 DCHECK(text_view_); | 1104 DCHECK(text_view_); |
1162 | 1105 |
1163 // Call the GtkTextView default handler, ignoring the fact that it will | 1106 // Call the GtkTextView default handler, ignoring the fact that it will |
1164 // likely have told us to stop propagating. We want to handle selection. | 1107 // likely have told us to stop propagating. We want to handle selection. |
1165 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_); | 1108 GtkWidgetClass* klass = GTK_WIDGET_GET_CLASS(text_view_); |
1166 klass->button_release_event(text_view_, event); | 1109 klass->button_release_event(text_view_, event); |
1167 | 1110 |
1168 // Inform |model_| about possible text selection change. We may get a button | 1111 // Inform model() about possible text selection change. We may get a button |
1169 // release with no press (e.g. if the user clicks in the omnibox to dismiss a | 1112 // release with no press (e.g. if the user clicks in the omnibox to dismiss a |
1170 // bubble). | 1113 // bubble). |
1171 if (button_1_was_pressed) | 1114 if (button_1_was_pressed) |
1172 OnAfterPossibleChange(); | 1115 OnAfterPossibleChange(); |
1173 | 1116 |
1174 return TRUE; // Don't continue, we called the default handler already. | 1117 return TRUE; // Don't continue, we called the default handler already. |
1175 } | 1118 } |
1176 | 1119 |
1177 gboolean OmniboxViewGtk::HandleViewFocusIn(GtkWidget* sender, | 1120 gboolean OmniboxViewGtk::HandleViewFocusIn(GtkWidget* sender, |
1178 GdkEventFocus* event) { | 1121 GdkEventFocus* event) { |
1179 DCHECK(text_view_); | 1122 DCHECK(text_view_); |
1180 update_popup_without_focus_ = false; | 1123 update_popup_without_focus_ = false; |
1181 | 1124 |
1182 GdkModifierType modifiers; | 1125 GdkModifierType modifiers; |
1183 GdkWindow* gdk_window = gtk_widget_get_window(text_view_); | 1126 GdkWindow* gdk_window = gtk_widget_get_window(text_view_); |
1184 gdk_window_get_pointer(gdk_window, NULL, NULL, &modifiers); | 1127 gdk_window_get_pointer(gdk_window, NULL, NULL, &modifiers); |
1185 model_->OnSetFocus((modifiers & GDK_CONTROL_MASK) != 0); | 1128 model()->OnSetFocus((modifiers & GDK_CONTROL_MASK) != 0); |
1186 controller_->OnSetFocus(); | 1129 controller()->OnSetFocus(); |
1187 // TODO(deanm): Some keyword hit business, etc here. | 1130 // TODO(deanm): Some keyword hit business, etc here. |
1188 | 1131 |
1189 g_signal_connect( | 1132 g_signal_connect( |
1190 gdk_keymap_get_for_display(gtk_widget_get_display(text_view_)), | 1133 gdk_keymap_get_for_display(gtk_widget_get_display(text_view_)), |
1191 "direction-changed", | 1134 "direction-changed", |
1192 G_CALLBACK(&HandleKeymapDirectionChangedThunk), this); | 1135 G_CALLBACK(&HandleKeymapDirectionChangedThunk), this); |
1193 | 1136 |
1194 AdjustTextJustification(); | 1137 AdjustTextJustification(); |
1195 | 1138 |
1196 return FALSE; // Continue propagation. | 1139 return FALSE; // Continue propagation. |
1197 } | 1140 } |
1198 | 1141 |
1199 gboolean OmniboxViewGtk::HandleViewFocusOut(GtkWidget* sender, | 1142 gboolean OmniboxViewGtk::HandleViewFocusOut(GtkWidget* sender, |
1200 GdkEventFocus* event) { | 1143 GdkEventFocus* event) { |
1201 DCHECK(text_view_); | 1144 DCHECK(text_view_); |
1202 GtkWidget* view_getting_focus = NULL; | 1145 GtkWidget* view_getting_focus = NULL; |
1203 GtkWindow* toplevel = platform_util::GetTopLevel(sender); | 1146 GtkWindow* toplevel = platform_util::GetTopLevel(sender); |
1204 if (gtk_window_is_active(toplevel)) | 1147 if (gtk_window_is_active(toplevel)) |
1205 view_getting_focus = going_to_focus_; | 1148 view_getting_focus = going_to_focus_; |
1206 | 1149 |
1207 // This must be invoked before ClosePopup. | 1150 // This must be invoked before ClosePopup. |
1208 model_->OnWillKillFocus(view_getting_focus); | 1151 model()->OnWillKillFocus(view_getting_focus); |
1209 | 1152 |
1210 // Close the popup. | 1153 // Close the popup. |
1211 ClosePopup(); | 1154 CloseOmniboxPopup(); |
1212 // Tell the model to reset itself. | 1155 // Tell the model to reset itself. |
1213 model_->OnKillFocus(); | 1156 model()->OnKillFocus(); |
1214 controller_->OnKillFocus(); | 1157 controller()->OnKillFocus(); |
1215 | 1158 |
1216 g_signal_handlers_disconnect_by_func( | 1159 g_signal_handlers_disconnect_by_func( |
1217 gdk_keymap_get_for_display(gtk_widget_get_display(text_view_)), | 1160 gdk_keymap_get_for_display(gtk_widget_get_display(text_view_)), |
1218 reinterpret_cast<gpointer>(&HandleKeymapDirectionChangedThunk), this); | 1161 reinterpret_cast<gpointer>(&HandleKeymapDirectionChangedThunk), this); |
1219 | 1162 |
1220 return FALSE; // Pass the event on to the GtkTextView. | 1163 return FALSE; // Pass the event on to the GtkTextView. |
1221 } | 1164 } |
1222 | 1165 |
1223 void OmniboxViewGtk::HandleViewMoveCursor( | 1166 void OmniboxViewGtk::HandleViewMoveCursor( |
1224 GtkWidget* sender, | 1167 GtkWidget* sender, |
(...skipping 16 matching lines...) Expand all Loading... |
1241 PangoDirection content_dir = GetContentDirection(); | 1184 PangoDirection content_dir = GetContentDirection(); |
1242 gint count_towards_end = content_dir == PANGO_DIRECTION_RTL ? -1 : 1; | 1185 gint count_towards_end = content_dir == PANGO_DIRECTION_RTL ? -1 : 1; |
1243 | 1186 |
1244 // We want the GtkEntry behavior when you move the cursor while you have a | 1187 // We want the GtkEntry behavior when you move the cursor while you have a |
1245 // selection. GtkTextView just drops the selection and moves the cursor, | 1188 // selection. GtkTextView just drops the selection and moves the cursor, |
1246 // but instead we want to move the cursor to the appropiate end of the | 1189 // but instead we want to move the cursor to the appropiate end of the |
1247 // selection. | 1190 // selection. |
1248 if (has_selection) { | 1191 if (has_selection) { |
1249 // We have a selection and start / end are in ascending order. | 1192 // We have a selection and start / end are in ascending order. |
1250 // Cursor placement will remove the selection, so we need inform | 1193 // Cursor placement will remove the selection, so we need inform |
1251 // |model_| about this change by | 1194 // model() about this change by |
1252 // calling On{Before|After}PossibleChange() methods. | 1195 // calling On{Before|After}PossibleChange() methods. |
1253 OnBeforePossibleChange(); | 1196 OnBeforePossibleChange(); |
1254 gtk_text_buffer_place_cursor( | 1197 gtk_text_buffer_place_cursor( |
1255 text_buffer_, count == count_towards_end ? &sel_end : &sel_start); | 1198 text_buffer_, count == count_towards_end ? &sel_end : &sel_start); |
1256 OnAfterPossibleChange(); | 1199 OnAfterPossibleChange(); |
1257 handled = true; | 1200 handled = true; |
1258 } else if (count == count_towards_end && !IsCaretAtEnd()) { | 1201 } else if (count == count_towards_end && !IsCaretAtEnd()) { |
1259 handled = model_->CommitSuggestedText(true); | 1202 handled = model()->CommitSuggestedText(true); |
1260 } | 1203 } |
1261 } else if (step == GTK_MOVEMENT_PAGES) { // Page up and down. | 1204 } else if (step == GTK_MOVEMENT_PAGES) { // Page up and down. |
1262 // Multiply by count for the direction (if we move too much that's ok). | 1205 // Multiply by count for the direction (if we move too much that's ok). |
1263 model_->OnUpOrDownKeyPressed(model_->result().size() * count); | 1206 model()->OnUpOrDownKeyPressed(model()->result().size() * count); |
1264 handled = true; | 1207 handled = true; |
1265 } else if (step == GTK_MOVEMENT_DISPLAY_LINES) { // Arrow up and down. | 1208 } else if (step == GTK_MOVEMENT_DISPLAY_LINES) { // Arrow up and down. |
1266 model_->OnUpOrDownKeyPressed(count); | 1209 model()->OnUpOrDownKeyPressed(count); |
1267 handled = true; | 1210 handled = true; |
1268 } | 1211 } |
1269 | 1212 |
1270 if (!handled) { | 1213 if (!handled) { |
1271 // Cursor movement may change the selection, we need to record the change | 1214 // Cursor movement may change the selection, we need to record the change |
1272 // and report it to |model_|. | 1215 // and report it to model(). |
1273 if (has_selection || extend_selection) | 1216 if (has_selection || extend_selection) |
1274 OnBeforePossibleChange(); | 1217 OnBeforePossibleChange(); |
1275 | 1218 |
1276 // Propagate into GtkTextView | 1219 // Propagate into GtkTextView |
1277 GtkTextViewClass* klass = GTK_TEXT_VIEW_GET_CLASS(text_view_); | 1220 GtkTextViewClass* klass = GTK_TEXT_VIEW_GET_CLASS(text_view_); |
1278 klass->move_cursor(GTK_TEXT_VIEW(text_view_), step, count, | 1221 klass->move_cursor(GTK_TEXT_VIEW(text_view_), step, count, |
1279 extend_selection); | 1222 extend_selection); |
1280 | 1223 |
1281 if (has_selection || extend_selection) | 1224 if (has_selection || extend_selection) |
1282 OnAfterPossibleChange(); | 1225 OnAfterPossibleChange(); |
(...skipping 10 matching lines...) Expand all Loading... |
1293 // Don't force a minimum width, but use the font-relative height. This is a | 1236 // Don't force a minimum width, but use the font-relative height. This is a |
1294 // run-first handler, so the default handler was already called. | 1237 // run-first handler, so the default handler was already called. |
1295 req->width = 1; | 1238 req->width = 1; |
1296 } | 1239 } |
1297 | 1240 |
1298 void OmniboxViewGtk::HandlePopupMenuDeactivate(GtkWidget* sender) { | 1241 void OmniboxViewGtk::HandlePopupMenuDeactivate(GtkWidget* sender) { |
1299 // When the context menu appears, |text_view_|'s focus is lost. After an item | 1242 // When the context menu appears, |text_view_|'s focus is lost. After an item |
1300 // is activated, the focus comes back to |text_view_|, but only after the | 1243 // is activated, the focus comes back to |text_view_|, but only after the |
1301 // check in UpdatePopup(). We set this flag to make UpdatePopup() aware that | 1244 // check in UpdatePopup(). We set this flag to make UpdatePopup() aware that |
1302 // it will be receiving focus again. | 1245 // it will be receiving focus again. |
1303 if (!model_->has_focus()) | 1246 if (!model()->has_focus()) |
1304 update_popup_without_focus_ = true; | 1247 update_popup_without_focus_ = true; |
1305 } | 1248 } |
1306 | 1249 |
1307 void OmniboxViewGtk::HandlePopulatePopup(GtkWidget* sender, GtkMenu* menu) { | 1250 void OmniboxViewGtk::HandlePopulatePopup(GtkWidget* sender, GtkMenu* menu) { |
1308 GtkWidget* separator = gtk_separator_menu_item_new(); | 1251 GtkWidget* separator = gtk_separator_menu_item_new(); |
1309 gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator); | 1252 gtk_menu_shell_append(GTK_MENU_SHELL(menu), separator); |
1310 gtk_widget_show(separator); | 1253 gtk_widget_show(separator); |
1311 | 1254 |
1312 // Search Engine menu item. | 1255 // Search Engine menu item. |
1313 GtkWidget* search_engine_menuitem = gtk_menu_item_new_with_mnemonic( | 1256 GtkWidget* search_engine_menuitem = gtk_menu_item_new_with_mnemonic( |
1314 ui::ConvertAcceleratorsFromWindowsStyle( | 1257 ui::ConvertAcceleratorsFromWindowsStyle( |
1315 l10n_util::GetStringUTF8(IDS_EDIT_SEARCH_ENGINES)).c_str()); | 1258 l10n_util::GetStringUTF8(IDS_EDIT_SEARCH_ENGINES)).c_str()); |
1316 gtk_menu_shell_append(GTK_MENU_SHELL(menu), search_engine_menuitem); | 1259 gtk_menu_shell_append(GTK_MENU_SHELL(menu), search_engine_menuitem); |
1317 g_signal_connect(search_engine_menuitem, "activate", | 1260 g_signal_connect(search_engine_menuitem, "activate", |
1318 G_CALLBACK(HandleEditSearchEnginesThunk), this); | 1261 G_CALLBACK(HandleEditSearchEnginesThunk), this); |
1319 gtk_widget_set_sensitive(search_engine_menuitem, | 1262 gtk_widget_set_sensitive(search_engine_menuitem, |
1320 command_updater_->IsCommandEnabled(IDC_EDIT_SEARCH_ENGINES)); | 1263 command_updater()->IsCommandEnabled(IDC_EDIT_SEARCH_ENGINES)); |
1321 gtk_widget_show(search_engine_menuitem); | 1264 gtk_widget_show(search_engine_menuitem); |
1322 | 1265 |
1323 // Detect the Paste menu item by searching for the one that | 1266 // Detect the Paste menu item by searching for the one that |
1324 // uses the stock Paste label (i.e. gtk-paste). | 1267 // uses the stock Paste label (i.e. gtk-paste). |
1325 string16 stock_paste_label(UTF8ToUTF16(GTK_STOCK_PASTE)); | 1268 string16 stock_paste_label(UTF8ToUTF16(GTK_STOCK_PASTE)); |
1326 GList* list = gtk_container_get_children(GTK_CONTAINER(menu)); | 1269 GList* list = gtk_container_get_children(GTK_CONTAINER(menu)); |
1327 guint index = 1; | 1270 guint index = 1; |
1328 for (GList* item = list; item != NULL; item = item->next, ++index) { | 1271 for (GList* item = list; item != NULL; item = item->next, ++index) { |
1329 if (GTK_IS_IMAGE_MENU_ITEM(item->data)) { | 1272 if (GTK_IS_IMAGE_MENU_ITEM(item->data)) { |
1330 gboolean is_stock = gtk_image_menu_item_get_use_stock( | 1273 gboolean is_stock = gtk_image_menu_item_get_use_stock( |
(...skipping 12 matching lines...) Expand all Loading... |
1343 // If we don't find the stock Paste menu item, | 1286 // If we don't find the stock Paste menu item, |
1344 // the Paste and Go item will be appended at the end of the popup menu. | 1287 // the Paste and Go item will be appended at the end of the popup menu. |
1345 GtkClipboard* x_clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); | 1288 GtkClipboard* x_clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD); |
1346 gchar* text = gtk_clipboard_wait_for_text(x_clipboard); | 1289 gchar* text = gtk_clipboard_wait_for_text(x_clipboard); |
1347 sanitized_text_for_paste_and_go_ = text ? | 1290 sanitized_text_for_paste_and_go_ = text ? |
1348 StripJavascriptSchemas(CollapseWhitespace(UTF8ToUTF16(text), true)) : | 1291 StripJavascriptSchemas(CollapseWhitespace(UTF8ToUTF16(text), true)) : |
1349 string16(); | 1292 string16(); |
1350 g_free(text); | 1293 g_free(text); |
1351 GtkWidget* paste_go_menuitem = gtk_menu_item_new_with_mnemonic( | 1294 GtkWidget* paste_go_menuitem = gtk_menu_item_new_with_mnemonic( |
1352 ui::ConvertAcceleratorsFromWindowsStyle(l10n_util::GetStringUTF8( | 1295 ui::ConvertAcceleratorsFromWindowsStyle(l10n_util::GetStringUTF8( |
1353 model_->IsPasteAndSearch(sanitized_text_for_paste_and_go_) ? | 1296 model()->IsPasteAndSearch(sanitized_text_for_paste_and_go_) ? |
1354 IDS_PASTE_AND_SEARCH : IDS_PASTE_AND_GO)).c_str()); | 1297 IDS_PASTE_AND_SEARCH : IDS_PASTE_AND_GO)).c_str()); |
1355 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), paste_go_menuitem, index); | 1298 gtk_menu_shell_insert(GTK_MENU_SHELL(menu), paste_go_menuitem, index); |
1356 g_signal_connect(paste_go_menuitem, "activate", | 1299 g_signal_connect(paste_go_menuitem, "activate", |
1357 G_CALLBACK(HandlePasteAndGoThunk), this); | 1300 G_CALLBACK(HandlePasteAndGoThunk), this); |
1358 gtk_widget_set_sensitive(paste_go_menuitem, | 1301 gtk_widget_set_sensitive(paste_go_menuitem, |
1359 model_->CanPasteAndGo(sanitized_text_for_paste_and_go_)); | 1302 model()->CanPasteAndGo(sanitized_text_for_paste_and_go_)); |
1360 gtk_widget_show(paste_go_menuitem); | 1303 gtk_widget_show(paste_go_menuitem); |
1361 | 1304 |
1362 g_signal_connect(menu, "deactivate", | 1305 g_signal_connect(menu, "deactivate", |
1363 G_CALLBACK(HandlePopupMenuDeactivateThunk), this); | 1306 G_CALLBACK(HandlePopupMenuDeactivateThunk), this); |
1364 } | 1307 } |
1365 | 1308 |
1366 void OmniboxViewGtk::HandleEditSearchEngines(GtkWidget* sender) { | 1309 void OmniboxViewGtk::HandleEditSearchEngines(GtkWidget* sender) { |
1367 command_updater_->ExecuteCommand(IDC_EDIT_SEARCH_ENGINES); | 1310 command_updater()->ExecuteCommand(IDC_EDIT_SEARCH_ENGINES); |
1368 } | 1311 } |
1369 | 1312 |
1370 void OmniboxViewGtk::HandlePasteAndGo(GtkWidget* sender) { | 1313 void OmniboxViewGtk::HandlePasteAndGo(GtkWidget* sender) { |
1371 model_->PasteAndGo(sanitized_text_for_paste_and_go_); | 1314 model()->PasteAndGo(sanitized_text_for_paste_and_go_); |
1372 } | 1315 } |
1373 | 1316 |
1374 void OmniboxViewGtk::HandleMarkSet(GtkTextBuffer* buffer, | 1317 void OmniboxViewGtk::HandleMarkSet(GtkTextBuffer* buffer, |
1375 GtkTextIter* location, | 1318 GtkTextIter* location, |
1376 GtkTextMark* mark) { | 1319 GtkTextMark* mark) { |
1377 if (!text_buffer_ || buffer != text_buffer_) | 1320 if (!text_buffer_ || buffer != text_buffer_) |
1378 return; | 1321 return; |
1379 | 1322 |
1380 if (mark != gtk_text_buffer_get_insert(text_buffer_) && | 1323 if (mark != gtk_text_buffer_get_insert(text_buffer_) && |
1381 mark != gtk_text_buffer_get_selection_bound(text_buffer_)) { | 1324 mark != gtk_text_buffer_get_selection_bound(text_buffer_)) { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1491 GdkDragContext* context) { | 1434 GdkDragContext* context) { |
1492 string16 text = UTF8ToUTF16(GetSelectedText()); | 1435 string16 text = UTF8ToUTF16(GetSelectedText()); |
1493 | 1436 |
1494 if (text.empty()) | 1437 if (text.empty()) |
1495 return; | 1438 return; |
1496 | 1439 |
1497 // Use AdjustTextForCopy to make sure we prefix the text with 'http://'. | 1440 // Use AdjustTextForCopy to make sure we prefix the text with 'http://'. |
1498 CharRange selection = GetSelection(); | 1441 CharRange selection = GetSelection(); |
1499 GURL url; | 1442 GURL url; |
1500 bool write_url; | 1443 bool write_url; |
1501 model_->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text, | 1444 model()->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text, |
1502 &url, &write_url); | 1445 &url, &write_url); |
1503 if (write_url) { | 1446 if (write_url) { |
1504 selected_text_ = UTF16ToUTF8(text); | 1447 selected_text_ = UTF16ToUTF8(text); |
1505 GtkTargetList* copy_targets = | 1448 GtkTargetList* copy_targets = |
1506 gtk_text_buffer_get_copy_target_list(text_buffer_); | 1449 gtk_text_buffer_get_copy_target_list(text_buffer_); |
1507 gtk_target_list_add(copy_targets, | 1450 gtk_target_list_add(copy_targets, |
1508 ui::GetAtomForTarget(ui::CHROME_NAMED_URL), | 1451 ui::GetAtomForTarget(ui::CHROME_NAMED_URL), |
1509 GTK_TARGET_SAME_APP, ui::CHROME_NAMED_URL); | 1452 GTK_TARGET_SAME_APP, ui::CHROME_NAMED_URL); |
1510 } | 1453 } |
1511 dragged_text_ = selected_text_; | 1454 dragged_text_ = selected_text_; |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1543 gunichar c = g_utf8_get_char(p); | 1486 gunichar c = g_utf8_get_char(p); |
1544 | 1487 |
1545 // 0x200B is Zero Width Space, which is inserted just before the instant | 1488 // 0x200B is Zero Width Space, which is inserted just before the instant |
1546 // anchor for working around the GtkTextView's misalignment bug. | 1489 // anchor for working around the GtkTextView's misalignment bug. |
1547 // This character might be captured and inserted into the content by undo | 1490 // This character might be captured and inserted into the content by undo |
1548 // manager, so we need to filter it out here. | 1491 // manager, so we need to filter it out here. |
1549 if (c != 0x200B) | 1492 if (c != 0x200B) |
1550 base::WriteUnicodeCharacter(c, &filtered_text); | 1493 base::WriteUnicodeCharacter(c, &filtered_text); |
1551 } | 1494 } |
1552 | 1495 |
1553 if (model_->is_pasting()) | 1496 if (model()->is_pasting()) |
1554 filtered_text = StripJavascriptSchemas( | 1497 filtered_text = StripJavascriptSchemas( |
1555 CollapseWhitespace(filtered_text, true)); | 1498 CollapseWhitespace(filtered_text, true)); |
1556 | 1499 |
1557 if (!filtered_text.empty()) { | 1500 if (!filtered_text.empty()) { |
1558 // Avoid inserting the text after the instant anchor. | 1501 // Avoid inserting the text after the instant anchor. |
1559 ValidateTextBufferIter(location); | 1502 ValidateTextBufferIter(location); |
1560 | 1503 |
1561 // Call the default handler to insert filtered text. | 1504 // Call the default handler to insert filtered text. |
1562 GtkTextBufferClass* klass = GTK_TEXT_BUFFER_GET_CLASS(buffer); | 1505 GtkTextBufferClass* klass = GTK_TEXT_BUFFER_GET_CLASS(buffer); |
1563 std::string utf8_text = UTF16ToUTF8(filtered_text); | 1506 std::string utf8_text = UTF16ToUTF8(filtered_text); |
1564 klass->insert_text(buffer, location, utf8_text.data(), | 1507 klass->insert_text(buffer, location, utf8_text.data(), |
1565 static_cast<gint>(utf8_text.length())); | 1508 static_cast<gint>(utf8_text.length())); |
1566 } | 1509 } |
1567 | 1510 |
1568 // Stop propagating the signal emission to prevent the default handler from | 1511 // Stop propagating the signal emission to prevent the default handler from |
1569 // being called again. | 1512 // being called again. |
1570 static guint signal_id = g_signal_lookup("insert-text", GTK_TYPE_TEXT_BUFFER); | 1513 static guint signal_id = g_signal_lookup("insert-text", GTK_TYPE_TEXT_BUFFER); |
1571 g_signal_stop_emission(buffer, signal_id, 0); | 1514 g_signal_stop_emission(buffer, signal_id, 0); |
1572 } | 1515 } |
1573 | 1516 |
1574 void OmniboxViewGtk::HandleBackSpace(GtkWidget* sender) { | 1517 void OmniboxViewGtk::HandleBackSpace(GtkWidget* sender) { |
1575 // Checks if it's currently in keyword search mode. | 1518 // Checks if it's currently in keyword search mode. |
1576 if (model_->is_keyword_hint() || model_->keyword().empty()) | 1519 if (model()->is_keyword_hint() || model()->keyword().empty()) |
1577 return; // Propgate into GtkTextView. | 1520 return; // Propgate into GtkTextView. |
1578 | 1521 |
1579 DCHECK(text_view_); | 1522 DCHECK(text_view_); |
1580 | 1523 |
1581 GtkTextIter sel_start, sel_end; | 1524 GtkTextIter sel_start, sel_end; |
1582 // Checks if there is some text selected. | 1525 // Checks if there is some text selected. |
1583 if (gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end)) | 1526 if (gtk_text_buffer_get_selection_bounds(text_buffer_, &sel_start, &sel_end)) |
1584 return; // Propgate into GtkTextView. | 1527 return; // Propgate into GtkTextView. |
1585 | 1528 |
1586 GtkTextIter start; | 1529 GtkTextIter start; |
1587 gtk_text_buffer_get_start_iter(text_buffer_, &start); | 1530 gtk_text_buffer_get_start_iter(text_buffer_, &start); |
1588 | 1531 |
1589 if (!gtk_text_iter_equal(&start, &sel_start)) | 1532 if (!gtk_text_iter_equal(&start, &sel_start)) |
1590 return; // Propgate into GtkTextView. | 1533 return; // Propgate into GtkTextView. |
1591 | 1534 |
1592 // We're showing a keyword and the user pressed backspace at the beginning | 1535 // We're showing a keyword and the user pressed backspace at the beginning |
1593 // of the text. Delete the selected keyword. | 1536 // of the text. Delete the selected keyword. |
1594 model_->ClearKeyword(GetText()); | 1537 model()->ClearKeyword(GetText()); |
1595 | 1538 |
1596 // Stop propagating the signal emission into GtkTextView. | 1539 // Stop propagating the signal emission into GtkTextView. |
1597 static guint signal_id = g_signal_lookup("backspace", GTK_TYPE_TEXT_VIEW); | 1540 static guint signal_id = g_signal_lookup("backspace", GTK_TYPE_TEXT_VIEW); |
1598 g_signal_stop_emission(text_view_, signal_id, 0); | 1541 g_signal_stop_emission(text_view_, signal_id, 0); |
1599 } | 1542 } |
1600 | 1543 |
1601 void OmniboxViewGtk::HandleViewMoveFocus(GtkWidget* widget, | 1544 void OmniboxViewGtk::HandleViewMoveFocus(GtkWidget* widget, |
1602 GtkDirectionType direction) { | 1545 GtkDirectionType direction) { |
1603 if (!tab_was_pressed_) | 1546 if (!tab_was_pressed_) |
1604 return; | 1547 return; |
1605 | 1548 |
1606 // If special behavior is triggered, then stop the signal emission to | 1549 // If special behavior is triggered, then stop the signal emission to |
1607 // prevent the focus from being moved. | 1550 // prevent the focus from being moved. |
1608 bool handled = false; | 1551 bool handled = false; |
1609 | 1552 |
1610 // Trigger Tab to search behavior only when Tab key is pressed. | 1553 // Trigger Tab to search behavior only when Tab key is pressed. |
1611 if (model_->is_keyword_hint() && !shift_was_pressed_) { | 1554 if (model()->is_keyword_hint() && !shift_was_pressed_) { |
1612 handled = model_->AcceptKeyword(); | 1555 handled = model()->AcceptKeyword(); |
1613 } else if (model_->popup_model()->IsOpen()) { | 1556 } else if (model()->popup_model()->IsOpen()) { |
1614 if (shift_was_pressed_ && | 1557 if (shift_was_pressed_ && |
1615 model_->popup_model()->selected_line_state() == | 1558 model()->popup_model()->selected_line_state() == |
1616 OmniboxPopupModel::KEYWORD) | 1559 OmniboxPopupModel::KEYWORD) |
1617 model_->ClearKeyword(GetText()); | 1560 model()->ClearKeyword(GetText()); |
1618 else | 1561 else |
1619 model_->OnUpOrDownKeyPressed(shift_was_pressed_ ? -1 : 1); | 1562 model()->OnUpOrDownKeyPressed(shift_was_pressed_ ? -1 : 1); |
1620 | 1563 |
1621 handled = true; | 1564 handled = true; |
1622 } | 1565 } |
1623 | 1566 |
1624 if (supports_pre_edit_ && !handled && !pre_edit_.empty()) | 1567 if (supports_pre_edit_ && !handled && !pre_edit_.empty()) |
1625 handled = true; | 1568 handled = true; |
1626 | 1569 |
1627 if (!handled && gtk_widget_get_visible(instant_view_)) | 1570 if (!handled && gtk_widget_get_visible(instant_view_)) |
1628 handled = model_->CommitSuggestedText(true); | 1571 handled = model()->CommitSuggestedText(true); |
1629 | 1572 |
1630 if (!handled) | 1573 if (!handled) |
1631 handled = model_->AcceptCurrentInstantPreview(); | 1574 handled = model()->AcceptCurrentInstantPreview(); |
1632 | 1575 |
1633 if (handled) { | 1576 if (handled) { |
1634 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET); | 1577 static guint signal_id = g_signal_lookup("move-focus", GTK_TYPE_WIDGET); |
1635 g_signal_stop_emission(widget, signal_id, 0); | 1578 g_signal_stop_emission(widget, signal_id, 0); |
1636 } | 1579 } |
1637 } | 1580 } |
1638 | 1581 |
1639 void OmniboxViewGtk::HandleCopyClipboard(GtkWidget* sender) { | 1582 void OmniboxViewGtk::HandleCopyClipboard(GtkWidget* sender) { |
1640 HandleCopyOrCutClipboard(true); | 1583 HandleCopyOrCutClipboard(true); |
1641 } | 1584 } |
(...skipping 14 matching lines...) Expand all Loading... |
1656 | 1599 |
1657 GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); | 1600 GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); |
1658 DCHECK(clipboard); | 1601 DCHECK(clipboard); |
1659 if (!clipboard) | 1602 if (!clipboard) |
1660 return; | 1603 return; |
1661 | 1604 |
1662 CharRange selection = GetSelection(); | 1605 CharRange selection = GetSelection(); |
1663 GURL url; | 1606 GURL url; |
1664 string16 text(UTF8ToUTF16(GetSelectedText())); | 1607 string16 text(UTF8ToUTF16(GetSelectedText())); |
1665 bool write_url; | 1608 bool write_url; |
1666 model_->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text, | 1609 model()->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text, |
1667 &url, &write_url); | 1610 &url, &write_url); |
1668 | 1611 |
1669 if (write_url) { | 1612 if (write_url) { |
1670 BookmarkNodeData data; | 1613 BookmarkNodeData data; |
1671 data.ReadFromTuple(url, text); | 1614 data.ReadFromTuple(url, text); |
1672 data.WriteToClipboard(NULL); | 1615 data.WriteToClipboard(NULL); |
1673 | 1616 |
1674 // Stop propagating the signal. | 1617 // Stop propagating the signal. |
1675 static guint copy_signal_id = | 1618 static guint copy_signal_id = |
1676 g_signal_lookup("copy-clipboard", GTK_TYPE_TEXT_VIEW); | 1619 g_signal_lookup("copy-clipboard", GTK_TYPE_TEXT_VIEW); |
1677 static guint cut_signal_id = | 1620 static guint cut_signal_id = |
1678 g_signal_lookup("cut-clipboard", GTK_TYPE_TEXT_VIEW); | 1621 g_signal_lookup("cut-clipboard", GTK_TYPE_TEXT_VIEW); |
1679 g_signal_stop_emission(text_view_, | 1622 g_signal_stop_emission(text_view_, |
1680 copy ? copy_signal_id : cut_signal_id, | 1623 copy ? copy_signal_id : cut_signal_id, |
1681 0); | 1624 0); |
1682 | 1625 |
1683 if (!copy && gtk_text_view_get_editable(GTK_TEXT_VIEW(text_view_))) | 1626 if (!copy && gtk_text_view_get_editable(GTK_TEXT_VIEW(text_view_))) |
1684 gtk_text_buffer_delete_selection(text_buffer_, true, true); | 1627 gtk_text_buffer_delete_selection(text_buffer_, true, true); |
1685 } | 1628 } |
1686 | 1629 |
1687 OwnPrimarySelection(UTF16ToUTF8(text)); | 1630 OwnPrimarySelection(UTF16ToUTF8(text)); |
1688 } | 1631 } |
1689 | 1632 |
| 1633 int OmniboxViewGtk::GetOmniboxTextLength() const { |
| 1634 GtkTextIter end; |
| 1635 gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_); |
| 1636 if (supports_pre_edit_) { |
| 1637 // We need to count the length of the text being composed, because we treat |
| 1638 // it as part of the content in GetText(). |
| 1639 return gtk_text_iter_get_offset(&end) + pre_edit_.size(); |
| 1640 } |
| 1641 return gtk_text_iter_get_offset(&end); |
| 1642 } |
| 1643 |
| 1644 void OmniboxViewGtk::EmphasizeURLComponents() { |
| 1645 if (supports_pre_edit_) { |
| 1646 // We can't change the text style easily, if the pre-edit string (the text |
| 1647 // being composed by the input method) is not empty, which is not treated as |
| 1648 // a part of the text content inside GtkTextView. And it's ok to simply |
| 1649 // return in this case, as this method will be called again when the |
| 1650 // pre-edit string gets committed. |
| 1651 if (pre_edit_.size()) { |
| 1652 strikethrough_ = CharRange(); |
| 1653 return; |
| 1654 } |
| 1655 } |
| 1656 // See whether the contents are a URL with a non-empty host portion, which we |
| 1657 // should emphasize. To check for a URL, rather than using the type returned |
| 1658 // by Parse(), ask the model, which will check the desired page transition for |
| 1659 // this input. This can tell us whether an UNKNOWN input string is going to |
| 1660 // be treated as a search or a navigation, and is the same method the Paste |
| 1661 // And Go system uses. |
| 1662 url_parse::Component scheme, host; |
| 1663 string16 text(GetText()); |
| 1664 AutocompleteInput::ParseForEmphasizeComponents( |
| 1665 text, model()->GetDesiredTLD(), &scheme, &host); |
| 1666 const bool emphasize = model()->CurrentTextIsURL() && (host.len > 0); |
| 1667 |
| 1668 // Set the baseline emphasis. |
| 1669 GtkTextIter start, end; |
| 1670 GetTextBufferBounds(&start, &end); |
| 1671 gtk_text_buffer_remove_all_tags(text_buffer_, &start, &end); |
| 1672 if (emphasize) { |
| 1673 gtk_text_buffer_apply_tag(text_buffer_, faded_text_tag_, &start, &end); |
| 1674 |
| 1675 // We've found a host name, give it more emphasis. |
| 1676 gtk_text_buffer_get_iter_at_line_index(text_buffer_, &start, 0, |
| 1677 GetUTF8Offset(text, |
| 1678 host.begin)); |
| 1679 gtk_text_buffer_get_iter_at_line_index(text_buffer_, &end, 0, |
| 1680 GetUTF8Offset(text, |
| 1681 host.end())); |
| 1682 |
| 1683 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); |
| 1684 } else { |
| 1685 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); |
| 1686 } |
| 1687 |
| 1688 strikethrough_ = CharRange(); |
| 1689 // Emphasize the scheme for security UI display purposes (if necessary). |
| 1690 if (!model()->user_input_in_progress() && scheme.is_nonempty() && |
| 1691 (security_level_ != ToolbarModel::NONE)) { |
| 1692 CharRange scheme_range = CharRange(GetUTF8Offset(text, scheme.begin), |
| 1693 GetUTF8Offset(text, scheme.end())); |
| 1694 ItersFromCharRange(scheme_range, &start, &end); |
| 1695 |
| 1696 if (security_level_ == ToolbarModel::SECURITY_ERROR) { |
| 1697 strikethrough_ = scheme_range; |
| 1698 // When we draw the strikethrough, we don't want to include the ':' at the |
| 1699 // end of the scheme. |
| 1700 strikethrough_.cp_max--; |
| 1701 |
| 1702 gtk_text_buffer_apply_tag(text_buffer_, security_error_scheme_tag_, |
| 1703 &start, &end); |
| 1704 } else if (security_level_ == ToolbarModel::SECURITY_WARNING) { |
| 1705 gtk_text_buffer_apply_tag(text_buffer_, faded_text_tag_, &start, &end); |
| 1706 } else { |
| 1707 gtk_text_buffer_apply_tag(text_buffer_, secure_scheme_tag_, &start, &end); |
| 1708 } |
| 1709 } |
| 1710 } |
| 1711 |
1690 bool OmniboxViewGtk::OnPerformDropImpl(const string16& text) { | 1712 bool OmniboxViewGtk::OnPerformDropImpl(const string16& text) { |
1691 string16 sanitized_string(StripJavascriptSchemas( | 1713 string16 sanitized_string(StripJavascriptSchemas( |
1692 CollapseWhitespace(text, true))); | 1714 CollapseWhitespace(text, true))); |
1693 if (model_->CanPasteAndGo(sanitized_string)) { | 1715 if (model()->CanPasteAndGo(sanitized_string)) { |
1694 model_->PasteAndGo(sanitized_string); | 1716 model()->PasteAndGo(sanitized_string); |
1695 return true; | 1717 return true; |
1696 } | 1718 } |
1697 | 1719 |
1698 return false; | 1720 return false; |
1699 } | 1721 } |
1700 | 1722 |
1701 gfx::Font OmniboxViewGtk::GetFont() { | 1723 gfx::Font OmniboxViewGtk::GetFont() { |
1702 bool use_gtk = theme_service_->UsingNativeTheme(); | 1724 bool use_gtk = theme_service_->UsingNativeTheme(); |
1703 if (use_gtk) { | 1725 if (use_gtk) { |
1704 // If we haven't initialized the text view yet, just create a temporary one | 1726 // If we haven't initialized the text view yet, just create a temporary one |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 entries, len, | 1761 entries, len, |
1740 ClipboardGetSelectionThunk, | 1762 ClipboardGetSelectionThunk, |
1741 ClipboardSelectionCleared, | 1763 ClipboardSelectionCleared, |
1742 G_OBJECT(text_buffer_)); | 1764 G_OBJECT(text_buffer_)); |
1743 | 1765 |
1744 gtk_target_list_unref(list); | 1766 gtk_target_list_unref(list); |
1745 gtk_target_table_free(entries, len); | 1767 gtk_target_table_free(entries, len); |
1746 } | 1768 } |
1747 | 1769 |
1748 void OmniboxViewGtk::HandlePasteClipboard(GtkWidget* sender) { | 1770 void OmniboxViewGtk::HandlePasteClipboard(GtkWidget* sender) { |
1749 // We can't call model_->on_paste_replacing_all() here, because the actual | 1771 // We can't call model()->on_paste_replacing_all() here, because the actual |
1750 // paste clipboard action may not be performed if the clipboard is empty. | 1772 // paste clipboard action may not be performed if the clipboard is empty. |
1751 paste_clipboard_requested_ = true; | 1773 paste_clipboard_requested_ = true; |
1752 } | 1774 } |
1753 | 1775 |
1754 gfx::Rect OmniboxViewGtk::WindowBoundsFromIters(GtkTextIter* iter1, | 1776 gfx::Rect OmniboxViewGtk::WindowBoundsFromIters(GtkTextIter* iter1, |
1755 GtkTextIter* iter2) { | 1777 GtkTextIter* iter2) { |
1756 GdkRectangle start_location, end_location; | 1778 GdkRectangle start_location, end_location; |
1757 GtkTextView* text_view = GTK_TEXT_VIEW(text_view_); | 1779 GtkTextView* text_view = GTK_TEXT_VIEW(text_view_); |
1758 gtk_text_view_get_iter_location(text_view, iter1, &start_location); | 1780 gtk_text_view_get_iter_location(text_view, iter1, &start_location); |
1759 gtk_text_view_get_iter_location(text_view, iter2, &end_location); | 1781 gtk_text_view_get_iter_location(text_view, iter2, &end_location); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1876 } | 1898 } |
1877 | 1899 |
1878 void OmniboxViewGtk::ItersFromCharRange(const CharRange& range, | 1900 void OmniboxViewGtk::ItersFromCharRange(const CharRange& range, |
1879 GtkTextIter* iter_min, | 1901 GtkTextIter* iter_min, |
1880 GtkTextIter* iter_max) { | 1902 GtkTextIter* iter_max) { |
1881 DCHECK(!IsImeComposing()); | 1903 DCHECK(!IsImeComposing()); |
1882 gtk_text_buffer_get_iter_at_offset(text_buffer_, iter_min, range.cp_min); | 1904 gtk_text_buffer_get_iter_at_offset(text_buffer_, iter_min, range.cp_min); |
1883 gtk_text_buffer_get_iter_at_offset(text_buffer_, iter_max, range.cp_max); | 1905 gtk_text_buffer_get_iter_at_offset(text_buffer_, iter_max, range.cp_max); |
1884 } | 1906 } |
1885 | 1907 |
1886 int OmniboxViewGtk::GetTextLength() const { | |
1887 GtkTextIter end; | |
1888 gtk_text_buffer_get_iter_at_mark(text_buffer_, &end, instant_mark_); | |
1889 if (supports_pre_edit_) { | |
1890 // We need to count the length of the text being composed, because we treat | |
1891 // it as part of the content in GetText(). | |
1892 return gtk_text_iter_get_offset(&end) + pre_edit_.size(); | |
1893 } | |
1894 return gtk_text_iter_get_offset(&end); | |
1895 } | |
1896 | |
1897 void OmniboxViewGtk::PlaceCaretAt(int pos) { | |
1898 GtkTextIter cursor; | |
1899 gtk_text_buffer_get_iter_at_offset(text_buffer_, &cursor, pos); | |
1900 gtk_text_buffer_place_cursor(text_buffer_, &cursor); | |
1901 } | |
1902 | |
1903 bool OmniboxViewGtk::IsCaretAtEnd() const { | 1908 bool OmniboxViewGtk::IsCaretAtEnd() const { |
1904 const CharRange selection = GetSelection(); | 1909 const CharRange selection = GetSelection(); |
1905 return selection.cp_min == selection.cp_max && | 1910 return selection.cp_min == selection.cp_max && |
1906 selection.cp_min == GetTextLength(); | 1911 selection.cp_min == GetOmniboxTextLength(); |
1907 } | |
1908 | |
1909 void OmniboxViewGtk::EmphasizeURLComponents() { | |
1910 if (supports_pre_edit_) { | |
1911 // We can't change the text style easily, if the pre-edit string (the text | |
1912 // being composed by the input method) is not empty, which is not treated as | |
1913 // a part of the text content inside GtkTextView. And it's ok to simply | |
1914 // return in this case, as this method will be called again when the | |
1915 // pre-edit string gets committed. | |
1916 if (pre_edit_.size()) { | |
1917 strikethrough_ = CharRange(); | |
1918 return; | |
1919 } | |
1920 } | |
1921 // See whether the contents are a URL with a non-empty host portion, which we | |
1922 // should emphasize. To check for a URL, rather than using the type returned | |
1923 // by Parse(), ask the model, which will check the desired page transition for | |
1924 // this input. This can tell us whether an UNKNOWN input string is going to | |
1925 // be treated as a search or a navigation, and is the same method the Paste | |
1926 // And Go system uses. | |
1927 url_parse::Component scheme, host; | |
1928 string16 text(GetText()); | |
1929 AutocompleteInput::ParseForEmphasizeComponents( | |
1930 text, model_->GetDesiredTLD(), &scheme, &host); | |
1931 const bool emphasize = model_->CurrentTextIsURL() && (host.len > 0); | |
1932 | |
1933 // Set the baseline emphasis. | |
1934 GtkTextIter start, end; | |
1935 GetTextBufferBounds(&start, &end); | |
1936 gtk_text_buffer_remove_all_tags(text_buffer_, &start, &end); | |
1937 if (emphasize) { | |
1938 gtk_text_buffer_apply_tag(text_buffer_, faded_text_tag_, &start, &end); | |
1939 | |
1940 // We've found a host name, give it more emphasis. | |
1941 gtk_text_buffer_get_iter_at_line_index(text_buffer_, &start, 0, | |
1942 GetUTF8Offset(text, | |
1943 host.begin)); | |
1944 gtk_text_buffer_get_iter_at_line_index(text_buffer_, &end, 0, | |
1945 GetUTF8Offset(text, | |
1946 host.end())); | |
1947 | |
1948 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); | |
1949 } else { | |
1950 gtk_text_buffer_apply_tag(text_buffer_, normal_text_tag_, &start, &end); | |
1951 } | |
1952 | |
1953 strikethrough_ = CharRange(); | |
1954 // Emphasize the scheme for security UI display purposes (if necessary). | |
1955 if (!model_->user_input_in_progress() && scheme.is_nonempty() && | |
1956 (security_level_ != ToolbarModel::NONE)) { | |
1957 CharRange scheme_range = CharRange(GetUTF8Offset(text, scheme.begin), | |
1958 GetUTF8Offset(text, scheme.end())); | |
1959 ItersFromCharRange(scheme_range, &start, &end); | |
1960 | |
1961 if (security_level_ == ToolbarModel::SECURITY_ERROR) { | |
1962 strikethrough_ = scheme_range; | |
1963 // When we draw the strikethrough, we don't want to include the ':' at the | |
1964 // end of the scheme. | |
1965 strikethrough_.cp_max--; | |
1966 | |
1967 gtk_text_buffer_apply_tag(text_buffer_, security_error_scheme_tag_, | |
1968 &start, &end); | |
1969 } else if (security_level_ == ToolbarModel::SECURITY_WARNING) { | |
1970 gtk_text_buffer_apply_tag(text_buffer_, faded_text_tag_, &start, &end); | |
1971 } else { | |
1972 gtk_text_buffer_apply_tag(text_buffer_, secure_scheme_tag_, &start, &end); | |
1973 } | |
1974 } | |
1975 } | 1912 } |
1976 | 1913 |
1977 void OmniboxViewGtk::StopAnimation() { | 1914 void OmniboxViewGtk::StopAnimation() { |
1978 // Clear the animation delegate so we don't get an AnimationEnded() callback. | 1915 // Clear the animation delegate so we don't get an AnimationEnded() callback. |
1979 instant_animation_->set_delegate(NULL); | 1916 instant_animation_->set_delegate(NULL); |
1980 instant_animation_->Stop(); | 1917 instant_animation_->Stop(); |
1981 UpdateInstantViewColors(); | 1918 UpdateInstantViewColors(); |
1982 } | 1919 } |
1983 | 1920 |
1984 void OmniboxViewGtk::TextChanged() { | |
1985 EmphasizeURLComponents(); | |
1986 model_->OnChanged(); | |
1987 } | |
1988 | |
1989 void OmniboxViewGtk::SavePrimarySelection(const std::string& selected_text) { | 1921 void OmniboxViewGtk::SavePrimarySelection(const std::string& selected_text) { |
1990 DCHECK(text_view_); | 1922 DCHECK(text_view_); |
1991 | 1923 |
1992 GtkClipboard* clipboard = | 1924 GtkClipboard* clipboard = |
1993 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); | 1925 gtk_widget_get_clipboard(text_view_, GDK_SELECTION_PRIMARY); |
1994 DCHECK(clipboard); | 1926 DCHECK(clipboard); |
1995 if (!clipboard) | 1927 if (!clipboard) |
1996 return; | 1928 return; |
1997 | 1929 |
1998 gtk_clipboard_set_text( | 1930 gtk_clipboard_set_text( |
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2173 void OmniboxViewGtk::UpdatePrimarySelectionIfValidURL() { | 2105 void OmniboxViewGtk::UpdatePrimarySelectionIfValidURL() { |
2174 string16 text = UTF8ToUTF16(GetSelectedText()); | 2106 string16 text = UTF8ToUTF16(GetSelectedText()); |
2175 | 2107 |
2176 if (text.empty()) | 2108 if (text.empty()) |
2177 return; | 2109 return; |
2178 | 2110 |
2179 // Use AdjustTextForCopy to make sure we prefix the text with 'http://'. | 2111 // Use AdjustTextForCopy to make sure we prefix the text with 'http://'. |
2180 CharRange selection = GetSelection(); | 2112 CharRange selection = GetSelection(); |
2181 GURL url; | 2113 GURL url; |
2182 bool write_url; | 2114 bool write_url; |
2183 model_->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text, | 2115 model()->AdjustTextForCopy(selection.selection_min(), IsSelectAll(), &text, |
2184 &url, &write_url); | 2116 &url, &write_url); |
2185 if (write_url) { | 2117 if (write_url) { |
2186 selected_text_ = UTF16ToUTF8(text); | 2118 selected_text_ = UTF16ToUTF8(text); |
2187 OwnPrimarySelection(selected_text_); | 2119 OwnPrimarySelection(selected_text_); |
2188 } | 2120 } |
2189 } | 2121 } |
2190 | 2122 |
2191 void OmniboxViewGtk::HandlePreEditChanged(GtkWidget* sender, | 2123 void OmniboxViewGtk::HandlePreEditChanged(GtkWidget* sender, |
2192 const gchar* pre_edit) { | 2124 const gchar* pre_edit) { |
2193 // GtkTextView won't fire "begin-user-action" and "end-user-action" signals | 2125 // GtkTextView won't fire "begin-user-action" and "end-user-action" signals |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2242 void OmniboxViewGtk::AdjustVerticalAlignmentOfInstantView() { | 2174 void OmniboxViewGtk::AdjustVerticalAlignmentOfInstantView() { |
2243 // By default, GtkTextView layouts an anchored child widget just above the | 2175 // By default, GtkTextView layouts an anchored child widget just above the |
2244 // baseline, so we need to move the |instant_view_| down to make sure it | 2176 // baseline, so we need to move the |instant_view_| down to make sure it |
2245 // has the same baseline as the |text_view_|. | 2177 // has the same baseline as the |text_view_|. |
2246 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_)); | 2178 PangoLayout* layout = gtk_label_get_layout(GTK_LABEL(instant_view_)); |
2247 int height; | 2179 int height; |
2248 pango_layout_get_size(layout, NULL, &height); | 2180 pango_layout_get_size(layout, NULL, &height); |
2249 int baseline = pango_layout_get_baseline(layout); | 2181 int baseline = pango_layout_get_baseline(layout); |
2250 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL); | 2182 g_object_set(instant_anchor_tag_, "rise", baseline - height, NULL); |
2251 } | 2183 } |
OLD | NEW |