diff options
author | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-23 20:01:00 +0000 |
---|---|---|
committer | shess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-04-23 20:01:00 +0000 |
commit | 69c579e522c4493c15c93ebf33b28a35b1e7213b (patch) | |
tree | 5dde3cc78e0de04bb87613c09be12b47b80d8307 /chrome/browser/autocomplete | |
parent | 12f144239468f206dc82c3f3481fef477f636798 (diff) | |
download | chromium_src-69c579e522c4493c15c93ebf33b28a35b1e7213b.zip chromium_src-69c579e522c4493c15c93ebf33b28a35b1e7213b.tar.gz chromium_src-69c579e522c4493c15c93ebf33b28a35b1e7213b.tar.bz2 |
Re-instate the temporary revert from r45267. That reverted certain
Omnibox, toolbar, tab animations, and other UI changes for purposes of
testing and merging into mstone-5.
Additionally reverts these CLs to fix the earlier revert:
r45271: [Mac] Image references missing from Omnibox revert.
r45268: GTK fix merge failure in uber-revert.
Additional revert which fixed a bug for the branch:
r45381: [Mac] Omnibox popup icons and text lined up under toolbar.
Slight merge conflict which should be good:
r45322: GTK: Implement OnDragCanceled() for autocomplete...
Also ++kThemePackVersion and regenerate the cached theme pak.
Re-instated changes:
r45213: GTK: Override cursor colors in chrome-theme mode.
r45103: Support drawing nano tabs in the tabstrip.
r45084: GTK: Position the EV certificate stuff inside a green bubble.
r44979: Subclassing the InfoBubble to handle anchoring bubbles basedon...
r44957: GTK: Tint the geolocation icons in gtk mode.
r44943: Changes FormatURL to not strip http if the host starts with ft...
r44930: Remove an icon that is no longer used.
r44929: SSL UI changes, Windows, code side (images are separate).
r44859: SSL UI changes (icons). TBRed since trybots hate binary patches.
r44822: GTK: Select better greens in the native omnibox popup.
r44814: GTK: navigate to URL on PRIMARY when middle-clicking the locat...
r44789: [Mac] Bookmark star missing on NTP and BMM.
r44775: [Mac] Centralize hack to make tests work with AutocompleteClas...
r44678: Display the SECURITY_WARNING status in the location bar for the
r44648: [Mac] Add an arrow cursor rect for the location image.
r44615: Revert r44611 because it may have broken "unit_tests" on "Vist...
r44611: Display the SECURITY_WARNING status in the location bar for the
r44577: Revert 44572 - [Mac] Update locationbar icon as user types.
r44572: [Mac] Update location-bar icon as user types.
r44555: GTK: Use correct button mask on reload button.
r44545: [Mac] Omnibox text drag drag URL when select-all.
r44523: GTK: Prevent inappropriate drag of location bar location icon.
r44519: GTK: make the primary selection include the url's scheme when ...
r44492: [Mac] Fix search icon in keyword search to be right-side-up.
r44415: GTK: Update top padding on icons in the autocomplete popup.
r44401: GTK: Tint omnibox icons in GTK mode differently.
r44380: GTK: Move reload in gtk mode and fix omnibox popup location.
r44282: Fixes crash in autocomplete when typing some URLs. The problem
r44273: [Mac] PDF icons for omnibox nits.
r44269: Fix build break due to bad merge resolve
r44268: Shift omnibox dropdown in and up on Windows, and square off th...
r44178: GTK: fix TTS padding.
r44177: Round the top left and right edges of the toolbar.
r44171: Images only checkin for try server goodness.
r44163: GTK: fix padding of autocomplete popup.
r44152: [Mac] PDF icons for omnibox.
r44145: GTK: Theme the icons in the location bar and use GTK colors fo...
r44140: Strips http from the omnibox
r44131: Fixes bugs in new tab strip animations where they weren't doin...
r44116: Change the default theme colors.
r44117: Add newline to EOF to fix CrOS builder.
r44115: Make the bottom edges of the opaque frame rounded.
r44091: [Mac] No star icon or page actions in omnibox on popups.
r44087: Don't allow drag or click on location icon when editing in omn...
r44021: [GTK] Add TTS lens graphic to linux TTS box.
r44008: [Mac] Tweak location icon spacing in omnibox.
r43977: GTK: don't show the star or page actions in ShouldOnlyShowLoca...
r43972: Make the firstrun bubble point at a better spot now that the l...
r43971: [Mac] Location icon in omnibox as drag source.
r43970: Make the star and page action icons not appear on popup windows.
r43954: Fixes bug in TabStrip where dragging tab out then back in rapidly
r43864: Tweaks to BoundsAnimator/SlideAnimation and TabStrip:
r43787: Allow location icon to be dragged & dropped. This also fixes ...
r43759: Changes end cap of tab-to-search images.
r43740: Change bookmark bar toggle to ctrl-shift-b.
r43723: Show Page Info dialog on mouse up, not mouse down.
r43677: Fix Mac build failure.
r43676: Replace omnibox icons with new set that are all the same size ...
r43596: Fix browser test TestStarButtonAccObj.
r43593: Disables TestStarButtonAccObj.
r43582: Changes tab strip to use BoundsAnimator for tab strip animatio...
r43563: GTK: don't show reload button for popup/app windows.
r43562: Star/reload shuffle, Windows version.
r43540: [Mac] Magnifying glass in keyword-search bubble.
r43482: Adds images needed for new tab animation. I'm separating this ...
r43422: Add reload mask resource.
r43392: GTK: make the location icon a drag source.
r43376: [Mac] Move star button into page-actions area of omnibox.
r43357: [Mac] Line up omnibox popup under field.
r43290: gtk: fix display of icons in omnibox popup
r43269: GTK: fix reload button.
r43249: [Mac] Rearrange SSL status icon/label in omnibox.
r43248: BrowserThemePack: Adds persistant ids for the reload endcaps.
r43241: GTK: more location bar updates.
r43191: Fix memory leak in BrowserThemePack.
r43154: GTK: set the new star button's ID
r43151: Fix bad conflict resolution for r43146.
r43146: GTK: toolbar reload/star shuffle.
r43025: Show the location bar icon (almost) all the time, and have its...
r43023: Add new images for new reload button. No code change.
r42782: Remove this icon, now that it's no longer used (due to my secu...
r42502: Omnibox M5 work, part 1: Security changes
r42245: Check in new icons for omnibox security changes alone, so that...
BUG=none
TEST=People go back to complaining about missing http://.
R=pkasting@chromium.org,beng@chromium.org
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45474 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/autocomplete')
23 files changed, 861 insertions, 550 deletions
diff --git a/chrome/browser/autocomplete/autocomplete.cc b/chrome/browser/autocomplete/autocomplete.cc index 9c7e942..ba37681 100644 --- a/chrome/browser/autocomplete/autocomplete.cc +++ b/chrome/browser/autocomplete/autocomplete.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -27,6 +27,7 @@ #include "googleurl/src/url_canon_ip.h" #include "googleurl/src/url_util.h" #include "grit/generated_resources.h" +#include "grit/theme_resources.h" #include "net/base/net_util.h" #include "net/base/registry_controlled_domain.h" #include "net/url_request/url_request.h" @@ -367,6 +368,18 @@ void AutocompleteInput::Clear() { // AutocompleteMatch ---------------------------------------------------------- +AutocompleteMatch::AutocompleteMatch() + : provider(NULL), + relevance(0), + deletable(false), + inline_autocomplete_offset(std::wstring::npos), + transition(PageTransition::GENERATED), + is_history_what_you_typed_match(false), + type(SEARCH_WHAT_YOU_TYPED), + template_url(NULL), + starred(false) { +} + AutocompleteMatch::AutocompleteMatch(AutocompleteProvider* provider, int relevance, bool deletable, @@ -384,23 +397,40 @@ AutocompleteMatch::AutocompleteMatch(AutocompleteProvider* provider, // static std::string AutocompleteMatch::TypeToString(Type type) { - switch (type) { - case URL_WHAT_YOU_TYPED: return "url-what-you-typed"; - case HISTORY_URL: return "history-url"; - case HISTORY_TITLE: return "history-title"; - case HISTORY_BODY: return "history-body"; - case HISTORY_KEYWORD: return "history-keyword"; - case NAVSUGGEST: return "navsuggest"; - case SEARCH_WHAT_YOU_TYPED: return "search-what-you-typed"; - case SEARCH_HISTORY: return "search-history"; - case SEARCH_SUGGEST: return "search-suggest"; - case SEARCH_OTHER_ENGINE: return "search-other-engine"; - case OPEN_HISTORY_PAGE: return "open-history-page"; + const char* strings[NUM_TYPES] = { + "url-what-you-typed", + "history-url", + "history-title", + "history-body", + "history-keyword", + "navsuggest", + "search-what-you-typed", + "search-history", + "search-suggest", + "search-other-engine", + "open-history-page", + }; + DCHECK(arraysize(strings) == NUM_TYPES); + return strings[type]; +} - default: - NOTREACHED(); - return std::string(); - } +// static +int AutocompleteMatch::TypeToIcon(Type type) { + int icons[NUM_TYPES] = { + IDR_OMNIBOX_HTTP, + IDR_OMNIBOX_HTTP, + IDR_OMNIBOX_HISTORY, + IDR_OMNIBOX_HISTORY, + IDR_OMNIBOX_HISTORY, + IDR_OMNIBOX_HTTP, + IDR_OMNIBOX_SEARCH, + IDR_OMNIBOX_SEARCH, + IDR_OMNIBOX_SEARCH, + IDR_OMNIBOX_SEARCH, + IDR_OMNIBOX_MORE, + }; + DCHECK(arraysize(icons) == NUM_TYPES); + return icons[type]; } // static @@ -565,10 +595,14 @@ void AutocompleteProvider::UpdateStarredStateOfMatches() { std::wstring AutocompleteProvider::StringForURLDisplay( const GURL& url, - bool check_accept_lang) const { + bool check_accept_lang, + bool trim_http) const { std::wstring languages = (check_accept_lang && profile_) ? profile_->GetPrefs()->GetString(prefs::kAcceptLanguages) : std::wstring(); - return net::FormatUrl(url, languages); + const net::FormatUrlTypes format_types = trim_http ? + net::kFormatUrlOmitAll : net::kFormatUrlOmitUsernamePassword; + return net::FormatUrl(url, languages, format_types, UnescapeRule::SPACES, + NULL, NULL, NULL); } // AutocompleteResult --------------------------------------------------------- diff --git a/chrome/browser/autocomplete/autocomplete.h b/chrome/browser/autocomplete/autocomplete.h index d64fd6c..54bd9ff 100644 --- a/chrome/browser/autocomplete/autocomplete.h +++ b/chrome/browser/autocomplete/autocomplete.h @@ -314,22 +314,24 @@ struct AutocompleteMatch { // The type of this match. enum Type { - URL_WHAT_YOU_TYPED, // The input as a URL. - HISTORY_URL, // A past page whose URL contains the input. - HISTORY_TITLE, // A past page whose title contains the input. - HISTORY_BODY, // A past page whose body contains the input. - HISTORY_KEYWORD, // A past page whose keyword contains the input. - NAVSUGGEST, // A suggested URL. - SEARCH_WHAT_YOU_TYPED, // The input as a search query (with the default - // engine). - SEARCH_HISTORY, // A past search (with the default engine) - // containing the input. - SEARCH_SUGGEST, // A suggested search (with the default engine). - SEARCH_OTHER_ENGINE, // A search with a non-default engine. - OPEN_HISTORY_PAGE, // A synthetic result that opens the history page to - // search for the input. + URL_WHAT_YOU_TYPED = 0, // The input as a URL. + HISTORY_URL, // A past page whose URL contains the input. + HISTORY_TITLE, // A past page whose title contains the input. + HISTORY_BODY, // A past page whose body contains the input. + HISTORY_KEYWORD, // A past page whose keyword contains the input. + NAVSUGGEST, // A suggested URL. + SEARCH_WHAT_YOU_TYPED, // The input as a search query (with the default + // engine). + SEARCH_HISTORY, // A past search (with the default engine) + // containing the input. + SEARCH_SUGGEST, // A suggested search (with the default engine). + SEARCH_OTHER_ENGINE, // A search with a non-default engine. + OPEN_HISTORY_PAGE, // A synthetic result that opens the history page + // to search for the input. + NUM_TYPES, }; + AutocompleteMatch(); AutocompleteMatch(AutocompleteProvider* provider, int relevance, bool deletable, @@ -338,6 +340,10 @@ struct AutocompleteMatch { // Converts |type| to a string representation. Used in logging. static std::string TypeToString(Type type); + // Converts |type| to a resource identifier for the appropriate icon for this + // type. + static int TypeToIcon(Type type); + // Comparison function for determining when one match is better than another. static bool MoreRelevant(const AutocompleteMatch& elem1, const AutocompleteMatch& elem2); @@ -555,7 +561,8 @@ class AutocompleteProvider // "Accept Languages" when check_accept_lang is true. Otherwise, it's called // with an empty list. std::wstring StringForURLDisplay(const GURL& url, - bool check_accept_lang) const; + bool check_accept_lang, + bool trim_http) const; // The profile associated with the AutocompleteProvider. Reference is not // owned by us. @@ -776,7 +783,7 @@ class AutocompleteController : public ACProviderListener { const AutocompleteInput& input() const { return input_; } const AutocompleteResult& result() const { return result_; } // This next is temporary and should go away when - // AutocompletePopup::URLsForCurrentSelection() moves to the controller. + // AutocompletePopup::InfoForCurrentSelection() moves to the controller. const AutocompleteResult& latest_result() const { return latest_result_; } bool done() const { return done_ && !update_delay_timer_.IsRunning(); } diff --git a/chrome/browser/autocomplete/autocomplete_classifier.cc b/chrome/browser/autocomplete/autocomplete_classifier.cc new file mode 100644 index 0000000..3e96ff5 --- /dev/null +++ b/chrome/browser/autocomplete/autocomplete_classifier.cc @@ -0,0 +1,34 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/autocomplete/autocomplete_classifier.h" + +#include "chrome/browser/autocomplete/autocomplete.h" +#include "googleurl/src/gurl.h" + +AutocompleteClassifier::AutocompleteClassifier(Profile* profile) + : controller_(new AutocompleteController(profile)) { +} + +AutocompleteClassifier::~AutocompleteClassifier() { +} + +void AutocompleteClassifier::Classify(const std::wstring& text, + const std::wstring& desired_tld, + AutocompleteMatch* match, + GURL* alternate_nav_url) { + controller_->Start(text, desired_tld, true, false, true); + DCHECK(controller_->done()); + const AutocompleteResult& result = controller_->result(); + if (result.empty()) { + if (alternate_nav_url) + *alternate_nav_url = GURL(); + return; + } + + DCHECK(result.default_match() != result.end()); + *match = *result.default_match(); + if (alternate_nav_url) + *alternate_nav_url = result.alternate_nav_url(); +} diff --git a/chrome/browser/autocomplete/autocomplete_classifier.h b/chrome/browser/autocomplete/autocomplete_classifier.h new file mode 100644 index 0000000..3588c27 --- /dev/null +++ b/chrome/browser/autocomplete/autocomplete_classifier.h @@ -0,0 +1,43 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CLASSIFIER_H_ +#define CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CLASSIFIER_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/scoped_ptr.h" + +class AutocompleteController; +struct AutocompleteMatch; +class GURL; +class Profile; + +class AutocompleteClassifier { + public: + explicit AutocompleteClassifier(Profile* profile); + virtual ~AutocompleteClassifier(); + + // Given some string |text| that the user wants to use for navigation, + // determines how it should be interpreted. |desired_tld| is the user's + // desired TLD, if any; see AutocompleteInput::desired_tld(). |match| should + // be a non-NULL outparam that will be set to the default match for this + // input, if any (for invalid input, there will be no default match, and + // |match| will be left unchanged). |alternate_nav_url| is a possibly-NULL + // outparam that, if non-NULL, will be set to the navigational URL (if any) in + // case of an accidental search; see comments on + // AutocompleteResult::alternate_nav_url_ in autocomplete.h. + void Classify(const std::wstring& text, + const std::wstring& desired_tld, + AutocompleteMatch* match, + GURL* alternate_nav_url); + + private: + scoped_ptr<AutocompleteController> controller_; + + DISALLOW_IMPLICIT_CONSTRUCTORS(AutocompleteClassifier); +}; + +#endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_CLASSIFIER_H_ diff --git a/chrome/browser/autocomplete/autocomplete_edit.cc b/chrome/browser/autocomplete/autocomplete_edit.cc index f4c2583..9b0aefb 100644 --- a/chrome/browser/autocomplete/autocomplete_edit.cc +++ b/chrome/browser/autocomplete/autocomplete_edit.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -9,6 +9,7 @@ #include "base/basictypes.h" #include "base/utf_string_conversions.h" #include "chrome/app/chrome_dll_resource.h" +#include "chrome/browser/autocomplete/autocomplete_classifier.h" #include "chrome/browser/autocomplete/autocomplete_edit_view.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" #include "chrome/browser/autocomplete/keyword_provider.h" @@ -19,7 +20,6 @@ #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" -#include "chrome/browser/search_versus_navigate_classifier.h" #include "chrome/common/notification_service.h" #include "googleurl/src/gurl.h" #include "googleurl/src/url_util.h" @@ -44,7 +44,6 @@ AutocompleteEditModel::AutocompleteEditModel( control_key_state_(UP), is_keyword_hint_(false), keyword_ui_state_(NORMAL), - show_search_hint_(true), paste_and_go_transition_(PageTransition::TYPED), profile_(profile) { } @@ -81,7 +80,7 @@ const AutocompleteEditModel::State } return State(user_input_in_progress_, user_text_, keyword_, is_keyword_hint_, - keyword_ui_state_, show_search_hint_); + keyword_ui_state_); } void AutocompleteEditModel::RestoreState(const State& state) { @@ -92,7 +91,6 @@ void AutocompleteEditModel::RestoreState(const State& state) { keyword_ = state.keyword; is_keyword_hint_ = state.is_keyword_hint; keyword_ui_state_ = state.keyword_ui_state; - show_search_hint_ = state.show_search_hint; view_->SetUserText(state.user_text, DisplayTextFromUserText(state.user_text), false); } @@ -122,7 +120,9 @@ void AutocompleteEditModel::SetUserText(const std::wstring& text) { void AutocompleteEditModel::GetDataForURLExport(GURL* url, std::wstring* title, SkBitmap* favicon) { - *url = GetURLForCurrentText(NULL, NULL, NULL); + AutocompleteMatch match; + GetInfoForCurrentText(&match, NULL); + *url = match.destination_url; if (UTF8ToWide(url->possibly_invalid_spec()) == permanent_text_) { *title = controller_->GetTitle(); *favicon = controller_->GetFavIcon(); @@ -134,7 +134,7 @@ std::wstring AutocompleteEditModel::GetDesiredTLD() const { std::wstring(L"com") : std::wstring(); } -bool AutocompleteEditModel::CurrentTextIsURL() { +bool AutocompleteEditModel::CurrentTextIsURL() const { // If !user_input_in_progress_, the permanent text is showing, which should // always be a URL, so no further checking is needed. By avoiding checking in // this case, we avoid calling into the autocomplete providers, and thus @@ -142,9 +142,15 @@ bool AutocompleteEditModel::CurrentTextIsURL() { if (!user_input_in_progress_) return true; - PageTransition::Type transition = PageTransition::LINK; - GetURLForCurrentText(&transition, NULL, NULL); - return transition == PageTransition::TYPED; + AutocompleteMatch match; + GetInfoForCurrentText(&match, NULL); + return match.transition == PageTransition::TYPED; +} + +AutocompleteMatch::Type AutocompleteEditModel::CurrentTextType() const { + AutocompleteMatch match; + GetInfoForCurrentText(&match, NULL); + return match.type; } bool AutocompleteEditModel::GetURLForText(const std::wstring& text, @@ -174,7 +180,6 @@ void AutocompleteEditModel::Revert() { keyword_.clear(); is_keyword_hint_ = false; keyword_ui_state_ = NORMAL; - show_search_hint_ = permanent_text_.empty(); has_temporary_text_ = false; view_->SetWindowTextAndCaretPos(permanent_text_, has_focus_ ? permanent_text_.length() : 0); @@ -191,14 +196,11 @@ bool AutocompleteEditModel::CanPasteAndGo(const std::wstring& text) const { if (!view_->GetCommandUpdater()->IsCommandEnabled(IDC_OPEN_CURRENT_URL)) return false; - paste_and_go_url_ = GURL(); - paste_and_go_transition_ = PageTransition::TYPED; - paste_and_go_alternate_nav_url_ = GURL(); - - profile_->GetSearchVersusNavigateClassifier()->Classify(text, std::wstring(), - NULL, &paste_and_go_url_, &paste_and_go_transition_, NULL, - &paste_and_go_alternate_nav_url_); - + AutocompleteMatch match; + profile_->GetAutocompleteClassifier()->Classify(text, std::wstring(), + &match, &paste_and_go_alternate_nav_url_); + paste_and_go_url_ = match.destination_url; + paste_and_go_transition_ = match.transition; return paste_and_go_url_.is_valid(); } @@ -215,33 +217,30 @@ void AutocompleteEditModel::PasteAndGo() { void AutocompleteEditModel::AcceptInput(WindowOpenDisposition disposition, bool for_drop) { // Get the URL and transition type for the selected entry. - PageTransition::Type transition; - bool is_history_what_you_typed_match; + AutocompleteMatch match; GURL alternate_nav_url; - const GURL url(GetURLForCurrentText(&transition, - &is_history_what_you_typed_match, - &alternate_nav_url)); - if (!url.is_valid()) + GetInfoForCurrentText(&match, &alternate_nav_url); + if (!match.destination_url.is_valid()) return; - if (UTF8ToWide(url.spec()) == permanent_text_) { + if (UTF8ToWide(match.destination_url.spec()) == permanent_text_) { // When the user hit enter on the existing permanent URL, treat it like a // reload for scoring purposes. We could detect this by just checking // user_input_in_progress_, but it seems better to treat "edits" that end // up leaving the URL unchanged (e.g. deleting the last character and then // retyping it) as reloads too. - transition = PageTransition::RELOAD; + match.transition = PageTransition::RELOAD; } else if (for_drop || ((paste_state_ != NONE) && - is_history_what_you_typed_match)) { + match.is_history_what_you_typed_match)) { // When the user pasted in a URL and hit enter, score it like a link click // rather than a normal typed URL, so it doesn't get inline autocompleted // as aggressively later. - transition = PageTransition::LINK; + match.transition = PageTransition::LINK; } - view_->OpenURL(url, disposition, transition, alternate_nav_url, - AutocompletePopupModel::kNoMatch, - is_keyword_hint_ ? std::wstring() : keyword_); + view_->OpenURL(match.destination_url, disposition, match.transition, + alternate_nav_url, AutocompletePopupModel::kNoMatch, + is_keyword_hint_ ? std::wstring() : keyword_); } void AutocompleteEditModel::SendOpenNotification(size_t selected_line, @@ -325,17 +324,20 @@ void AutocompleteEditModel::OnKillFocus() { } bool AutocompleteEditModel::OnEscapeKeyPressed() { - if (has_temporary_text_ && - (popup_->URLsForCurrentSelection(NULL, NULL, NULL) != original_url_)) { - // The user typed something, then selected a different item. Restore the - // text they typed and change back to the default item. - // NOTE: This purposefully does not reset paste_state_. - just_deleted_text_ = false; - has_temporary_text_ = false; - keyword_ui_state_ = original_keyword_ui_state_; - popup_->ResetToDefaultMatch(); - view_->OnRevertTemporaryText(); - return true; + if (has_temporary_text_) { + AutocompleteMatch match; + popup_->InfoForCurrentSelection(&match, NULL); + if (match.destination_url != original_url_) { + // The user typed something, then selected a different item. Restore the + // text they typed and change back to the default item. + // NOTE: This purposefully does not reset paste_state_. + just_deleted_text_ = false; + has_temporary_text_ = false; + keyword_ui_state_ = original_keyword_ui_state_; + popup_->ResetToDefaultMatch(); + view_->OnRevertTemporaryText(); + return true; + } } // If the user wasn't editing, but merely had focus in the edit, allow <esc> @@ -405,35 +407,24 @@ void AutocompleteEditModel::OnUpOrDownKeyPressed(int count) { void AutocompleteEditModel::OnPopupDataChanged( const std::wstring& text, - bool is_temporary_text, + GURL* destination_for_temporary_text_change, const std::wstring& keyword, - bool is_keyword_hint, - AutocompleteMatch::Type type) { - // We don't want to show the search hint if we're showing a keyword hint or - // selected keyword, or (subtle!) if we would be showing a selected keyword - // but for keyword_ui_state_ == NO_KEYWORD. - const bool show_search_hint = keyword.empty() && - ((type == AutocompleteMatch::SEARCH_WHAT_YOU_TYPED) || - (type == AutocompleteMatch::SEARCH_HISTORY) || - (type == AutocompleteMatch::SEARCH_SUGGEST)); - + bool is_keyword_hint) { // Update keyword/hint-related local state. bool keyword_state_changed = (keyword_ != keyword) || - ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()) || - (show_search_hint_ != show_search_hint); + ((is_keyword_hint_ != is_keyword_hint) && !keyword.empty()); if (keyword_state_changed) { keyword_ = keyword; is_keyword_hint_ = is_keyword_hint; - show_search_hint_ = show_search_hint; } // Handle changes to temporary text. - if (is_temporary_text) { + if (destination_for_temporary_text_change != NULL) { const bool save_original_selection = !has_temporary_text_; if (save_original_selection) { // Save the original selection and URL so it can be reverted later. has_temporary_text_ = true; - original_url_ = popup_->URLsForCurrentSelection(NULL, NULL, NULL); + original_url_ = *destination_for_temporary_text_change; original_keyword_ui_state_ = keyword_ui_state_; } if (control_key_state_ == DOWN_WITHOUT_CHANGE) { @@ -542,7 +533,6 @@ void AutocompleteEditModel::Observe(NotificationType type, std::wstring inline_autocomplete_text; std::wstring keyword; bool is_keyword_hint = false; - AutocompleteMatch::Type match_type = AutocompleteMatch::SEARCH_WHAT_YOU_TYPED; const AutocompleteResult* result = Details<const AutocompleteResult>(details).ptr(); const AutocompleteResult::const_iterator match(result->default_match()); @@ -559,11 +549,9 @@ void AutocompleteEditModel::Observe(NotificationType type, // the OS DNS cache could suffer eviction problems for minimal gain. is_keyword_hint = popup_->GetKeywordForMatch(*match, &keyword); - match_type = match->type; } - OnPopupDataChanged(inline_autocomplete_text, false, keyword, is_keyword_hint, - match_type); + OnPopupDataChanged(inline_autocomplete_text, NULL, keyword, is_keyword_hint); } void AutocompleteEditModel::InternalSetUserText(const std::wstring& text) { @@ -586,20 +574,14 @@ std::wstring AutocompleteEditModel::UserTextFromDisplayText( text : (keyword_ + L" " + text); } -GURL AutocompleteEditModel::GetURLForCurrentText( - PageTransition::Type* transition, - bool* is_history_what_you_typed_match, +void AutocompleteEditModel::GetInfoForCurrentText( + AutocompleteMatch* match, GURL* alternate_nav_url) const { if (popup_->IsOpen() || query_in_progress()) { - return popup_->URLsForCurrentSelection(transition, - is_history_what_you_typed_match, - alternate_nav_url); + popup_->InfoForCurrentSelection(match, alternate_nav_url); + } else { + profile_->GetAutocompleteClassifier()->Classify( + UserTextFromDisplayText(view_->GetText()), GetDesiredTLD(), match, + alternate_nav_url); } - - GURL destination_url; - profile_->GetSearchVersusNavigateClassifier()->Classify( - UserTextFromDisplayText(view_->GetText()), GetDesiredTLD(), NULL, - &destination_url, transition, is_history_what_you_typed_match, - alternate_nav_url); - return destination_url; } diff --git a/chrome/browser/autocomplete/autocomplete_edit.h b/chrome/browser/autocomplete/autocomplete_edit.h index 1a0386c..9f4e973 100644 --- a/chrome/browser/autocomplete/autocomplete_edit.h +++ b/chrome/browser/autocomplete/autocomplete_edit.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -83,14 +83,12 @@ class AutocompleteEditModel : public NotificationObserver { const std::wstring& user_text, const std::wstring& keyword, bool is_keyword_hint, - KeywordUIState keyword_ui_state, - bool show_search_hint) + KeywordUIState keyword_ui_state) : user_input_in_progress(user_input_in_progress), user_text(user_text), keyword(keyword), is_keyword_hint(is_keyword_hint), - keyword_ui_state(keyword_ui_state), - show_search_hint(show_search_hint) { + keyword_ui_state(keyword_ui_state) { } bool user_input_in_progress; @@ -98,7 +96,6 @@ class AutocompleteEditModel : public NotificationObserver { const std::wstring keyword; const bool is_keyword_hint; const KeywordUIState keyword_ui_state; - const bool show_search_hint; }; AutocompleteEditModel(AutocompleteEditView* view, @@ -137,7 +134,10 @@ class AutocompleteEditModel : public NotificationObserver { // Returns true if the current edit contents will be treated as a // URL/navigation, as opposed to a search. - bool CurrentTextIsURL(); + bool CurrentTextIsURL() const; + + // Returns the match type for the current edit contents. + AutocompleteMatch::Type CurrentTextType() const; // Returns true if |text| (which is display text in the current context) // parses as a URL, and in that case sets |url| to the calculated URL. @@ -208,7 +208,7 @@ class AutocompleteEditModel : public NotificationObserver { // Accessors for keyword-related state (see comments on keyword_ and // is_keyword_hint_). std::wstring keyword() const { - return (is_keyword_hint_ ? has_focus_ : (keyword_ui_state_ != NO_KEYWORD)) ? + return (is_keyword_hint_ || (keyword_ui_state_ != NO_KEYWORD)) ? keyword_ : std::wstring(); } bool is_keyword_hint() const { return is_keyword_hint_; } @@ -220,10 +220,6 @@ class AutocompleteEditModel : public NotificationObserver { // currently visible in the edit. void ClearKeyword(const std::wstring& visible_text); - // True if we should show the "Type to search" hint (see comments on - // show_search_hint_). - bool show_search_hint() const { return has_focus_ && show_search_hint_; } - // Returns true if a query to an autocomplete provider is currently // in progress. This logic should in the future live in // AutocompleteController but resides here for now. This method is used by @@ -260,21 +256,20 @@ class AutocompleteEditModel : public NotificationObserver { // Called when any relevant data changes. This rolls together several // separate pieces of data into one call so we can update all the UI // efficiently: - // |text| is either the new temporary text (if |is_temporary_text| is true) - // from the user manually selecting a different match, or the inline - // autocomplete text (if |is_temporary_text| is false). + // |text| is either the new temporary text from the user manually selecting + // a different match, or the inline autocomplete text. We distinguish by + // checking if |destination_for_temporary_text_change| is NULL. + // |destination_for_temporary_text_change| is NULL (if temporary text should + // not change) or the pre-change desitnation URL (if temporary text should + // change) so we can save it off to restore later. // |keyword| is the keyword to show a hint for if |is_keyword_hint| is true, // or the currently selected keyword if |is_keyword_hint| is false (see // comments on keyword_ and is_keyword_hint_). - // |type| is the type of match selected; this is used to determine whether - // we can show the "Type to search" hint (see comments on - // show_search_hint_). void OnPopupDataChanged( const std::wstring& text, - bool is_temporary_text, + GURL* destination_for_temporary_text_change, const std::wstring& keyword, - bool is_keyword_hint, - AutocompleteMatch::Type type); + bool is_keyword_hint); // Called by the AutocompleteEditView after something changes, with details // about what state changes occured. Updates internal state, updates the @@ -326,16 +321,10 @@ class AutocompleteEditModel : public NotificationObserver { std::wstring DisplayTextFromUserText(const std::wstring& text) const; std::wstring UserTextFromDisplayText(const std::wstring& text) const; - // Returns the URL. If the user has not edited the text, this returns the - // permanent text. If the user has edited the text, this returns the default - // match based on the current text, which may be a search URL, or keyword - // generated URL. - // - // See AutocompleteEdit for a description of the args (they may be null if - // not needed). - GURL GetURLForCurrentText(PageTransition::Type* transition, - bool* is_history_what_you_typed_match, - GURL* alternate_nav_url) const; + // Returns the default match for the current text, as well as the alternate + // nav URL, if |alternate_nav_url| is non-NULL and there is such a URL. + void GetInfoForCurrentText(AutocompleteMatch* match, + GURL* alternate_nav_url) const; AutocompleteEditView* view_; @@ -432,10 +421,6 @@ class AutocompleteEditModel : public NotificationObserver { // See KeywordUIState enum. KeywordUIState keyword_ui_state_; - // True when it's safe to show a "Type to search" hint to the user (when the - // edit is empty, or the user is in the process of searching). - bool show_search_hint_; - // Paste And Go-related state. See CanPasteAndGo(). mutable GURL paste_and_go_url_; mutable PageTransition::Type paste_and_go_transition_; diff --git a/chrome/browser/autocomplete/autocomplete_edit_view.h b/chrome/browser/autocomplete/autocomplete_edit_view.h index 63c2524..0d4c230 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view.h @@ -59,6 +59,13 @@ class AutocompleteEditView { // browser, or just whatever the user has currently typed. virtual std::wstring GetText() const = 0; + // |true| if the user is in the process of editing the field, or if + // the field is empty. + virtual bool IsEditingOrEmpty() const = 0; + + // Returns the resource ID of the icon to show for the current text. + virtual int GetIcon() const = 0; + // The user text is the text the user has manually keyed in. When present, // this is shown in preference to the permanent text; hitting escape will // revert to the permanent text. diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc index 86d886d..006395f 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc @@ -17,7 +17,6 @@ #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/autocomplete/autocomplete_popup_view_gtk.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/command_updater.h" #include "chrome/browser/defaults.h" @@ -34,9 +33,11 @@ #include "net/base/escape.h" #if defined(TOOLKIT_VIEWS) +#include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h" #include "chrome/browser/views/location_bar_view.h" #include "gfx/skia_utils_gtk.h" #else +#include "chrome/browser/autocomplete/autocomplete_popup_view_gtk.h" #include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/location_bar_view_gtk.h" #endif @@ -45,11 +46,13 @@ using gfx::SkColorToGdkColor; namespace { +const gchar* kAutocompleteEditViewGtkKey = "__ACE_VIEW_GTK__"; + const char kTextBaseColor[] = "#808080"; -const char kSecureSchemeColor[] = "#009614"; -const char kInsecureSchemeColor[] = "#c80000"; +const char kSecureSchemeColor[] = "#079500"; +const char kSecurityErrorSchemeColor[] = "#a20000"; -const double kStrikethroughStrokeRed = 210.0 / 256.0; +const double kStrikethroughStrokeRed = 162.0 / 256.0; const double kStrikethroughStrokeWidth = 2.0; size_t GetUTF8Offset(const std::wstring& wide_text, size_t wide_text_offset) { @@ -108,6 +111,26 @@ void SetEntryStyle() { "style \"chrome-location-bar-entry\""); } +// Copied from GTK+. Called when we lose the primary selection. This will clear +// the selection in the text buffer. +void ClipboardSelectionCleared(GtkClipboard* clipboard, + gpointer data) { + GtkTextIter insert; + GtkTextIter selection_bound; + GtkTextBuffer* buffer = GTK_TEXT_BUFFER(data); + + gtk_text_buffer_get_iter_at_mark(buffer, &insert, + gtk_text_buffer_get_insert(buffer)); + gtk_text_buffer_get_iter_at_mark(buffer, &selection_bound, + gtk_text_buffer_get_selection_bound(buffer)); + + if (!gtk_text_iter_equal(&insert, &selection_bound)) { + gtk_text_buffer_move_mark(buffer, + gtk_text_buffer_get_selection_bound(buffer), + &insert); + } +} + } // namespace AutocompleteEditViewGtk::AutocompleteEditViewGtk( @@ -116,23 +139,30 @@ AutocompleteEditViewGtk::AutocompleteEditViewGtk( Profile* profile, CommandUpdater* command_updater, bool popup_window_mode, - const BubblePositioner* bubble_positioner) +#if defined(TOOLKIT_VIEWS) + const views::View* location_bar) +#else + GtkWidget* location_bar) +#endif : text_view_(NULL), tag_table_(NULL), text_buffer_(NULL), faded_text_tag_(NULL), secure_scheme_tag_(NULL), - insecure_scheme_tag_(NULL), + security_error_scheme_tag_(NULL), model_(new AutocompleteEditModel(this, controller, profile)), - popup_view_(AutocompletePopupView::CreatePopupView(gfx::Font(), this, - model_.get(), - profile, - bubble_positioner)), +#if defined(TOOLKIT_VIEWS) + popup_view_(new AutocompletePopupContentsView( + gfx::Font(), this, model_.get(), profile, location_bar)), +#else + popup_view_(new AutocompletePopupViewGtk(this, model_.get(), profile, + location_bar)), +#endif controller_(controller), toolbar_model_(toolbar_model), command_updater_(command_updater), popup_window_mode_(popup_window_mode), - scheme_security_level_(ToolbarModel::NORMAL), + security_level_(ToolbarModel::NONE), mark_set_handler_id_(0), #if defined(OS_CHROMEOS) button_1_pressed_(false), @@ -185,6 +215,7 @@ void AutocompleteEditViewGtk::Init() { // the other objects adds a reference; it doesn't adopt them. tag_table_ = gtk_text_tag_table_new(); text_buffer_ = gtk_text_buffer_new(tag_table_); + g_object_set_data(G_OBJECT(text_buffer_), kAutocompleteEditViewGtkKey, this); text_view_ = gtk_text_view_new_with_buffer(text_buffer_); if (popup_window_mode_) gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view_), false); @@ -215,8 +246,8 @@ void AutocompleteEditViewGtk::Init() { NULL, "foreground", kTextBaseColor, NULL); secure_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, NULL, "foreground", kSecureSchemeColor, NULL); - insecure_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, - NULL, "foreground", kInsecureSchemeColor, NULL); + security_error_scheme_tag_ = gtk_text_buffer_create_tag(text_buffer_, + NULL, "foreground", kSecurityErrorSchemeColor, NULL); normal_text_tag_ = gtk_text_buffer_create_tag(text_buffer_, NULL, "foreground", "#000000", NULL); @@ -258,6 +289,8 @@ void AutocompleteEditViewGtk::Init() { G_CALLBACK(&HandlePopulatePopupThunk), this); mark_set_handler_id_ = g_signal_connect( text_buffer_, "mark-set", G_CALLBACK(&HandleMarkSetThunk), this); + mark_set_handler_id2_ = g_signal_connect_after( + text_buffer_, "mark-set", G_CALLBACK(&HandleMarkSetAfterThunk), this); g_signal_connect(text_view_, "drag-data-received", G_CALLBACK(&HandleDragDataReceivedThunk), this); g_signal_connect(text_view_, "backspace", @@ -284,7 +317,7 @@ void AutocompleteEditViewGtk::Init() { SetBaseColor(); #endif - ViewIDUtil::SetID(widget(), VIEW_ID_AUTOCOMPLETE); + ViewIDUtil::SetID(GetNativeView(), VIEW_ID_AUTOCOMPLETE); } void AutocompleteEditViewGtk::SetFocus() { @@ -318,9 +351,8 @@ void AutocompleteEditViewGtk::SaveStateToTab(TabContents* tab) { DCHECK(tab); // If any text has been selected, register it as the PRIMARY selection so it // can still be pasted via middle-click after the text view is cleared. - if (!selected_text_.empty()) { + if (!selected_text_.empty()) SavePrimarySelection(selected_text_); - } // NOTE: GetStateForTabSwitch may affect GetSelection, so order is important. AutocompleteEditModel::State model_state = model_->GetStateForTabSwitch(); GetStateAccessor()->SetProperty( @@ -334,15 +366,9 @@ void AutocompleteEditViewGtk::Update(const TabContents* contents) { model_->UpdatePermanentText(toolbar_model_->GetText()); ToolbarModel::SecurityLevel security_level = - toolbar_model_->GetSchemeSecurityLevel(); - bool changed_security_level = (security_level != scheme_security_level_); - scheme_security_level_ = security_level; - - // TODO(deanm): This doesn't exactly match Windows. There there is a member - // background_color_. I think we can get away with just the level though. - if (changed_security_level) { - SetBaseColor(); - } + toolbar_model_->GetSecurityLevel(); + bool changed_security_level = (security_level != security_level_); + security_level_ = security_level; if (contents) { selected_text_.clear(); @@ -392,6 +418,17 @@ std::wstring AutocompleteEditViewGtk::GetText() const { return out; } +bool AutocompleteEditViewGtk::IsEditingOrEmpty() const { + return model_->user_input_in_progress() || + (gtk_text_buffer_get_char_count(text_buffer_) == 0); +} + +int AutocompleteEditViewGtk::GetIcon() const { + return IsEditingOrEmpty() ? + AutocompleteMatch::TypeToIcon(model_->CurrentTextType()) : + toolbar_model_->GetIcon(); +} + void AutocompleteEditViewGtk::SetUserText(const std::wstring& text, const std::wstring& display_text, bool update_popup) { @@ -582,10 +619,8 @@ void AutocompleteEditViewGtk::SetBaseColor() { bool use_gtk = theme_provider_->UseGtkTheme(); #endif - // If we're on a secure connection, ignore what the theme wants us to do - // and use a yellow background. - bool is_secure = (scheme_security_level_ == ToolbarModel::SECURE); - if (use_gtk && !is_secure) { + if (use_gtk) { + gtk_widget_modify_cursor(text_view_, NULL, NULL); gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, NULL); gtk_widget_modify_base(text_view_, GTK_STATE_SELECTED, NULL); gtk_widget_modify_text(text_view_, GTK_STATE_SELECTED, NULL); @@ -600,20 +635,21 @@ void AutocompleteEditViewGtk::SetBaseColor() { GdkColor average_color = gtk_util::AverageColors( style->text[GTK_STATE_NORMAL], style->base[GTK_STATE_NORMAL]); - g_object_set(faded_text_tag_, "foreground-gdk", - &average_color, NULL); + g_object_set(faded_text_tag_, "foreground-gdk", &average_color, NULL); g_object_set(normal_text_tag_, "foreground-gdk", &style->text[GTK_STATE_NORMAL], NULL); } else { + const GdkColor* background_color_ptr; #if defined(TOOLKIT_VIEWS) const GdkColor background_color = gfx::SkColorToGdkColor( - LocationBarView::GetColor(is_secure, LocationBarView::BACKGROUND)); - gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, - &background_color); + LocationBarView::GetColor(ToolbarModel::NONE, + LocationBarView::BACKGROUND)); + background_color_ptr = &background_color; #else - gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, - &LocationBarViewGtk::kBackgroundColorByLevel[scheme_security_level_]); + background_color_ptr = &LocationBarViewGtk::kBackgroundColor; #endif + gtk_widget_modify_cursor(text_view_, &gfx::kGdkBlack, &gfx::kGdkGray); + gtk_widget_modify_base(text_view_, GTK_STATE_NORMAL, background_color_ptr); #if !defined(TOOLKIT_VIEWS) // Override the selected colors so we don't leak colors from the current @@ -1037,11 +1073,32 @@ void AutocompleteEditViewGtk::HandleMarkSet(GtkTextBuffer* buffer, GtkClipboard* clipboard = gtk_clipboard_get(GDK_SELECTION_PRIMARY); if (gtk_clipboard_get_owner(clipboard) == G_OBJECT(text_buffer_)) SavePrimarySelection(selected_text_); + } else if (IsSelectAll() && !model_->user_input_in_progress()) { + // Copy the whole URL to the clipboard (including the scheme, which is + // hidden in the case of http://). + GURL url; + if (model_->GetURLForText(GetText(), &url)) + OwnPrimarySelection(url.spec()); } selected_text_ = new_selected_text; } +// Override the primary selection the text buffer has set. This has to happen +// after the default handler for the "mark-set" signal. +void AutocompleteEditViewGtk::HandleMarkSetAfter(GtkTextBuffer* buffer, + GtkTextIter* location, + GtkTextMark* mark) { + std::wstring text = GetText(); + if (IsSelectAll() && !model_->user_input_in_progress() && !text.empty()) { + // Copy the whole URL to the clipboard (including the scheme, which is + // hidden in the case of http://). + GURL url; + if (model_->GetURLForText(GetText(), &url)) + OwnPrimarySelection(url.spec()); + } +} + // Just use the default behavior for DnD, except if the drop can be a PasteAndGo // then override. void AutocompleteEditViewGtk::HandleDragDataReceived( @@ -1178,18 +1235,14 @@ void AutocompleteEditViewGtk::HandleCopyOrCutClipboard(GtkWidget* sender) { // string to avoid encoding and escaping issues when pasting this text // elsewhere. scw.WriteText(url_spec16); + OwnPrimarySelection(url.spec()); } else { scw.WriteText(text16); + OwnPrimarySelection(UTF16ToUTF8(text16)); } scw.WriteHyperlink(UTF16ToUTF8(EscapeForHTML(text16)), url.spec()); - // Update PRIMARY selection if it is not owned by the text_buffer. - if (gtk_clipboard_get_owner(clipboard) != G_OBJECT(text_buffer_)) { - std::string utf8_text(UTF16ToUTF8(text16)); - gtk_clipboard_set_text(clipboard, utf8_text.c_str(), utf8_text.length()); - } - // Stop propagating the signal. static guint signal_id = g_signal_lookup("copy-clipboard", GTK_TYPE_TEXT_VIEW); @@ -1197,16 +1250,27 @@ void AutocompleteEditViewGtk::HandleCopyOrCutClipboard(GtkWidget* sender) { return; } - // Passing gtk_text_buffer_copy_clipboard() a text buffer that already owns - // the clipboard that's being updated clears the highlighted text, which we - // don't want to do (and it also appears to at least sometimes trigger a - // failed G_IS_OBJECT() assertion). - if (gtk_clipboard_get_owner(clipboard) == G_OBJECT(text_buffer_)) - return; + OwnPrimarySelection(selected_text_); +} - // We can't just call SavePrimarySelection(); that makes the text view lose - // the selection and unhighlight its text. - gtk_text_buffer_copy_clipboard(text_buffer_, clipboard); +void AutocompleteEditViewGtk::OwnPrimarySelection(const std::string& text) { + primary_selection_text_ = text; + + GtkTargetList* list = gtk_target_list_new(NULL, 0); + gtk_target_list_add_text_targets(list, 0); + gint len; + GtkTargetEntry* entries = gtk_target_table_new_from_list(list, &len); + + // When |text_buffer_| is destroyed, it will clear the clipboard, hence + // we needn't worry about calling gtk_clipboard_clear(). + gtk_clipboard_set_with_owner(gtk_clipboard_get(GDK_SELECTION_PRIMARY), + entries, len, + ClipboardGetSelectionThunk, + ClipboardSelectionCleared, + G_OBJECT(text_buffer_)); + + gtk_target_list_unref(list); + gtk_target_table_free(entries, len); } void AutocompleteEditViewGtk::HandlePasteClipboard(GtkWidget* sender) { @@ -1294,6 +1358,7 @@ void AutocompleteEditViewGtk::StartUpdatingHighlightedText() { gtk_text_buffer_remove_selection_clipboard(text_buffer_, clipboard); } g_signal_handler_block(text_buffer_, mark_set_handler_id_); + g_signal_handler_block(text_buffer_, mark_set_handler_id2_); } void AutocompleteEditViewGtk::FinishUpdatingHighlightedText() { @@ -1305,6 +1370,7 @@ void AutocompleteEditViewGtk::FinishUpdatingHighlightedText() { gtk_text_buffer_add_selection_clipboard(text_buffer_, clipboard); } g_signal_handler_unblock(text_buffer_, mark_set_handler_id_); + g_signal_handler_unblock(text_buffer_, mark_set_handler_id2_); } AutocompleteEditViewGtk::CharRange AutocompleteEditViewGtk::GetSelection() { @@ -1374,22 +1440,21 @@ void AutocompleteEditViewGtk::EmphasizeURLComponents() { strikethrough_ = CharRange(); // Emphasize the scheme for security UI display purposes (if necessary). if (!model_->user_input_in_progress() && scheme.is_nonempty() && - (scheme_security_level_ != ToolbarModel::NORMAL)) { + (security_level_ != ToolbarModel::NONE)) { CharRange scheme_range = CharRange(GetUTF8Offset(text, scheme.begin), GetUTF8Offset(text, scheme.end())); ItersFromCharRange(scheme_range, &start, &end); - if (scheme_security_level_ == ToolbarModel::SECURE) { - gtk_text_buffer_apply_tag(text_buffer_, secure_scheme_tag_, - &start, &end); - } else { + if (security_level_ == ToolbarModel::SECURITY_ERROR) { strikethrough_ = scheme_range; // When we draw the strikethrough, we don't want to include the ':' at the // end of the scheme. strikethrough_.cp_max--; - gtk_text_buffer_apply_tag(text_buffer_, insecure_scheme_tag_, + gtk_text_buffer_apply_tag(text_buffer_, security_error_scheme_tag_, &start, &end); + } else { + gtk_text_buffer_apply_tag(text_buffer_, secure_scheme_tag_, &start, &end); } } } @@ -1469,3 +1534,23 @@ void AutocompleteEditViewGtk::HandleWidgetDirectionChanged( void AutocompleteEditViewGtk::HandleKeymapDirectionChanged(GdkKeymap* sender) { AdjustTextJustification(); } + +// static +void AutocompleteEditViewGtk::ClipboardGetSelectionThunk( + GtkClipboard* clipboard, + GtkSelectionData* selection_data, + guint info, + gpointer object) { + AutocompleteEditViewGtk* edit_view = + reinterpret_cast<AutocompleteEditViewGtk*>( + g_object_get_data(G_OBJECT(object), kAutocompleteEditViewGtkKey)); + edit_view->ClipboardGetSelection(clipboard, selection_data, info); +} + +void AutocompleteEditViewGtk::ClipboardGetSelection( + GtkClipboard* clipboard, + GtkSelectionData* selection_data, + guint info) { + gtk_selection_data_set_text(selection_data, primary_selection_text_.c_str(), + primary_selection_text_.size()); +} diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h index 1eb1736..66b837b 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -25,9 +25,11 @@ class AutocompleteEditController; class AutocompleteEditModel; class AutocompletePopupView; -class BubblePositioner; class Profile; class TabContents; +namespace views { +class View; +} #if !defined(TOOLKIT_VIEWS) class GtkThemeProvider; @@ -53,14 +55,16 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, Profile* profile, CommandUpdater* command_updater, bool popup_window_mode, - const BubblePositioner* bubble_positioner); +#if defined(TOOLKIT_VIEWS) + const views::View* location_bar); +#else + GtkWidget* location_bar); +#endif ~AutocompleteEditViewGtk(); // Initialize, create the underlying widgets, etc. void Init(); - GtkWidget* widget() { return alignment_.get(); } - // Returns the width, in pixels, needed to display the current text. The // returned value includes margins and borders. int TextWidth(); @@ -82,6 +86,9 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, virtual std::wstring GetText() const; + virtual bool IsEditingOrEmpty() const; + virtual int GetIcon() const; + virtual void SetUserText(const std::wstring& text) { SetUserText(text, text, true); } @@ -134,6 +141,9 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, GtkTextBuffer*); CHROMEG_CALLBACK_2(AutocompleteEditViewGtk, void, HandleMarkSet, GtkTextBuffer*, GtkTextIter*, GtkTextMark*); + // As above, but called after the default handler. + CHROMEG_CALLBACK_2(AutocompleteEditViewGtk, void, HandleMarkSetAfter, + GtkTextBuffer*, GtkTextIter*, GtkTextMark*); CHROMEG_CALLBACK_3(AutocompleteEditViewGtk, void, HandleInsertText, GtkTextBuffer*, GtkTextIter*, const gchar*, gint); CHROMEG_CALLBACK_0(AutocompleteEditViewGtk, void, @@ -172,6 +182,20 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, CHROMEGTK_CALLBACK_1(AutocompleteEditViewGtk, void, HandleWidgetDirectionChanged, GtkTextDirection); + // Callback for the PRIMARY selection clipboard. + static void ClipboardGetSelectionThunk(GtkClipboard* clipboard, + GtkSelectionData* selection_data, + guint info, + gpointer object); + void ClipboardGetSelection(GtkClipboard* clipboard, + GtkSelectionData* selection_data, + guint info); + + // Take control of the PRIMARY selection clipboard with |text|. Use + // |text_buffer_| as the owner, so that this doesn't remove the selection on + // it. This makes use of the above callbacks. + void OwnPrimarySelection(const std::string& text); + // Gets the GTK_TEXT_WINDOW_WIDGET coordinates for |text_view_| that bound the // given iters. gfx::Rect WindowBoundsFromIters(GtkTextIter* iter1, GtkTextIter* iter2); @@ -209,7 +233,8 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, // Internally invoked whenever the text changes in some way. void TextChanged(); - // Save |selected_text| as the PRIMARY X selection. + // Save |selected_text| as the PRIMARY X selection. Unlike + // OwnPrimarySelection(), this won't set an owner or use callbacks. void SavePrimarySelection(const std::string& selected_text); // Update the field with |text| and set the selection. @@ -239,7 +264,7 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, GtkTextBuffer* text_buffer_; GtkTextTag* faded_text_tag_; GtkTextTag* secure_scheme_tag_; - GtkTextTag* insecure_scheme_tag_; + GtkTextTag* security_error_scheme_tag_; GtkTextTag* normal_text_tag_; scoped_ptr<AutocompleteEditModel> model_; @@ -255,7 +280,7 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, // different presentation (smaller font size). This is used for popups. bool popup_window_mode_; - ToolbarModel::SecurityLevel scheme_security_level_; + ToolbarModel::SecurityLevel security_level_; // Selection at the point where the user started using the // arrows to move around in the popup. @@ -272,8 +297,12 @@ class AutocompleteEditViewGtk : public AutocompleteEditView, // it, we pass this string to SavePrimarySelection()). std::string selected_text_; - // ID of the signal handler for "mark-set" on |text_buffer_|. + // When we own the X clipboard, this is the text for it. + std::string primary_selection_text_; + + // IDs of the signal handlers for "mark-set" on |text_buffer_|. gulong mark_set_handler_id_; + gulong mark_set_handler_id2_; #if defined(OS_CHROMEOS) // The following variables are used to implement select-all-on-mouse-up, which diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.h b/chrome/browser/autocomplete/autocomplete_edit_view_mac.h index 4cf7aee..740fde7 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.h @@ -13,7 +13,6 @@ class AutocompleteEditController; class AutocompletePopupViewMac; -class BubblePositioner; class Clipboard; class Profile; class ToolbarModel; @@ -24,7 +23,6 @@ class AutocompleteEditViewMac : public AutocompleteEditView, public AutocompleteTextFieldObserver { public: AutocompleteEditViewMac(AutocompleteEditController* controller, - const BubblePositioner* bubble_positioner, ToolbarModel* toolbar_model, Profile* profile, CommandUpdater* command_updater, @@ -48,6 +46,10 @@ class AutocompleteEditViewMac : public AutocompleteEditView, const std::wstring& keyword); virtual std::wstring GetText() const; + + virtual bool IsEditingOrEmpty() const; + virtual int GetIcon() const; + virtual void SetUserText(const std::wstring& text) { SetUserText(text, text, true); } @@ -98,6 +100,10 @@ class AutocompleteEditViewMac : public AutocompleteEditView, // empty string if no appropriate data is found on |clipboard|. static std::wstring GetClipboardText(Clipboard* clipboard); + // If |resource_id| has a PDF image which can be used, return it. + // Otherwise return the PNG image from the resource bundle. + static NSImage* ImageForResource(int resource_id); + private: // Called when the user hits backspace in |field_|. Checks whether // keyword search is being terminated. Returns true if the diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm index e337744..a4a54ce 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_edit_view_mac.mm @@ -9,6 +9,7 @@ #include "app/clipboard/clipboard.h" #include "app/clipboard/scoped_clipboard_writer.h" #include "app/resource_bundle.h" +#include "base/nsimage_cache_mac.h" #include "base/string_util.h" #include "base/sys_string_conversions.h" #include "base/utf_string_conversions.h" @@ -20,6 +21,7 @@ #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/toolbar_model.h" #include "grit/generated_resources.h" +#include "grit/theme_resources.h" #include "net/base/escape.h" // Focus-handling between |field_| and |model_| is a bit subtle. @@ -61,15 +63,6 @@ const NSColor* ColorWithRGBBytes(int rr, int gg, int bb) { blue:static_cast<float>(bb)/255.0 alpha:1.0]; } -const NSColor* SecureBackgroundColor() { - return ColorWithRGBBytes(255, 245, 195); // Yellow -} -const NSColor* NormalBackgroundColor() { - return [NSColor controlBackgroundColor]; -} -const NSColor* InsecureBackgroundColor() { - return [NSColor controlBackgroundColor]; -} const NSColor* HostTextColor() { return [NSColor blackColor]; @@ -77,11 +70,14 @@ const NSColor* HostTextColor() { const NSColor* BaseTextColor() { return [NSColor darkGrayColor]; } +const NSColor* EVSecureSchemeColor() { + return ColorWithRGBBytes(0x07, 0x95, 0x00); +} const NSColor* SecureSchemeColor() { - return ColorWithRGBBytes(0x00, 0x96, 0x14); + return ColorWithRGBBytes(0x00, 0x0e, 0x95); } -const NSColor* InsecureSchemeColor() { - return ColorWithRGBBytes(0xc8, 0x00, 0x00); +const NSColor* SecurityErrorSchemeColor() { + return ColorWithRGBBytes(0xa2, 0x00, 0x00); } // Store's the model and view state across tab switches. @@ -125,20 +121,57 @@ NSRange ComponentToNSRange(const url_parse::Component& component) { } // namespace +// static +NSImage* AutocompleteEditViewMac::ImageForResource(int resource_id) { + NSString* image_name = nil; + + switch(resource_id) { + // From the autocomplete popup, or the star icon at the RHS of the + // text field. + case IDR_OMNIBOX_STAR: image_name = @"omnibox_star.pdf"; break; + case IDR_OMNIBOX_STAR_LIT: image_name = @"omnibox_star_lit.pdf"; break; + + // Values from |AutocompleteMatch::TypeToIcon()|. + case IDR_OMNIBOX_SEARCH: image_name = @"omnibox_search.pdf"; break; + case IDR_OMNIBOX_HTTP: image_name = @"omnibox_http.pdf"; break; + case IDR_OMNIBOX_HISTORY: image_name = @"omnibox_history.pdf"; break; + case IDR_OMNIBOX_MORE: image_name = @"omnibox_more.pdf"; break; + + // Values from |ToolbarModel::GetIcon()|. + case IDR_OMNIBOX_HTTPS_VALID: + image_name = @"omnibox_https_valid.pdf"; break; + case IDR_OMNIBOX_HTTPS_WARNING: + image_name = @"omnibox_https_warning.pdf"; break; + case IDR_OMNIBOX_HTTPS_INVALID: + image_name = @"omnibox_https_invalid.pdf"; break; + } + + if (image_name) { + if (NSImage* image = nsimage_cache::ImageNamed(image_name)) { + return image; + } else { + NOTREACHED() + << "Missing image for " << base::SysNSStringToUTF8(image_name); + } + } + + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + return rb.GetNSImageNamed(resource_id); +} + // TODO(shess): AutocompletePopupViewMac doesn't really need an // NSTextField. It wants to know where the position the popup, what // font to use, and it also needs to be able to attach the popup to // the window |field_| is in. AutocompleteEditViewMac::AutocompleteEditViewMac( AutocompleteEditController* controller, - const BubblePositioner* bubble_positioner, ToolbarModel* toolbar_model, Profile* profile, CommandUpdater* command_updater, AutocompleteTextField* field) : model_(new AutocompleteEditModel(this, controller, profile)), - popup_view_(new AutocompletePopupViewMac( - this, model_.get(), bubble_positioner, profile, field)), + popup_view_(new AutocompletePopupViewMac(this, model_.get(), profile, + field)), controller_(controller), toolbar_model_(toolbar_model), command_updater_(command_updater), @@ -272,6 +305,17 @@ std::wstring AutocompleteEditViewMac::GetText() const { return base::SysNSStringToWide([field_ stringValue]); } +bool AutocompleteEditViewMac::IsEditingOrEmpty() const { + return model_->user_input_in_progress() || + ([[field_ stringValue] length] == 0); +} + +int AutocompleteEditViewMac::GetIcon() const { + return IsEditingOrEmpty() ? + AutocompleteMatch::TypeToIcon(model_->CurrentTextType()) : + toolbar_model_->GetIcon(); +} + void AutocompleteEditViewMac::SetUserText(const std::wstring& text, const std::wstring& display_text, bool update_popup) { @@ -410,32 +454,23 @@ void AutocompleteEditViewMac::SetText(const std::wstring& display_text) { // TODO(shess): GTK has this as a member var, figure out why. // [Could it be to not change if no change? If so, I'm guessing // AppKit may already handle that.] - const ToolbarModel::SecurityLevel scheme_security_level = - toolbar_model_->GetSchemeSecurityLevel(); - - if (scheme_security_level == ToolbarModel::SECURE) { - [field_ setBackgroundColor:SecureBackgroundColor()]; - } else if (scheme_security_level == ToolbarModel::NORMAL) { - [field_ setBackgroundColor:NormalBackgroundColor()]; - } else if (scheme_security_level == ToolbarModel::INSECURE) { - [field_ setBackgroundColor:InsecureBackgroundColor()]; - } else { - NOTREACHED() << "Unexpected scheme_security_level: " - << scheme_security_level; - } + const ToolbarModel::SecurityLevel security_level = + toolbar_model_->GetSecurityLevel(); // Emphasize the scheme for security UI display purposes (if necessary). if (!model_->user_input_in_progress() && scheme.is_nonempty() && - (scheme_security_level != ToolbarModel::NORMAL)) { + (security_level != ToolbarModel::NONE)) { NSColor* color; - if (scheme_security_level == ToolbarModel::SECURE) { - color = SecureSchemeColor(); - } else { - color = InsecureSchemeColor(); + if (security_level == ToolbarModel::EV_SECURE) { + color = EVSecureSchemeColor(); + } else if (security_level == ToolbarModel::SECURITY_ERROR) { + color = SecurityErrorSchemeColor(); // Add a strikethrough through the scheme. [as addAttribute:NSStrikethroughStyleAttributeName value:[NSNumber numberWithInt:NSUnderlineStyleSingle] range:ComponentToNSRange(scheme)]; + } else { + color = SecureSchemeColor(); } [as addAttribute:NSForegroundColorAttributeName value:color range:ComponentToNSRange(scheme)]; diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc index 6ead1fe..5a0632f 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc @@ -28,7 +28,6 @@ #include "chrome/app/chrome_dll_resource.h" #include "chrome/browser/autocomplete/autocomplete_accessibility.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/autocomplete/autocomplete_popup_view.h" #include "chrome/browser/autocomplete/keyword_provider.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/command_updater.h" @@ -387,10 +386,10 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( Profile* profile, CommandUpdater* command_updater, bool popup_window_mode, - const BubblePositioner* bubble_positioner) + const views::View* location_bar) : model_(new AutocompleteEditModel(this, controller, profile)), - popup_view_(AutocompletePopupView::CreatePopupView( - font, this, model_.get(), profile, bubble_positioner)), + popup_view_(new AutocompletePopupContentsView(font, this, model_.get(), + profile, location_bar)), controller_(controller), parent_view_(parent_view), toolbar_model_(toolbar_model), @@ -407,8 +406,9 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( in_drag_(false), initiated_drag_(false), drop_highlight_position_(-1), - background_color_(0), - scheme_security_level_(ToolbarModel::NORMAL), + background_color_(skia::SkColorToCOLORREF(LocationBarView::GetColor( + ToolbarModel::NONE, LocationBarView::BACKGROUND))), + security_level_(ToolbarModel::NONE), text_object_model_(NULL) { // Dummy call to a function exported by riched20.dll to ensure it sets up an // import dependency on the dll. @@ -459,6 +459,8 @@ AutocompleteEditViewWin::AutocompleteEditViewWin( cf.yOffset = -font_y_adjustment_ * kTwipsPerPixel; SetDefaultCharFormat(cf); + SetBackgroundColor(background_color_); + // By default RichEdit has a drop target. Revoke it so that we can install our // own. Revoke takes care of deleting the existing one. RevokeDragDrop(m_hWnd); @@ -508,30 +510,21 @@ void AutocompleteEditViewWin::Update( model_->UpdatePermanentText(toolbar_model_->GetText()); const ToolbarModel::SecurityLevel security_level = - toolbar_model_->GetSchemeSecurityLevel(); - const COLORREF background_color = - skia::SkColorToCOLORREF(LocationBarView::GetColor( - security_level == ToolbarModel::SECURE, LocationBarView::BACKGROUND)); - const bool changed_security_level = - (security_level != scheme_security_level_); + toolbar_model_->GetSecurityLevel(); + const bool changed_security_level = (security_level != security_level_); // Bail early when no visible state will actually change (prevents an // unnecessary ScopedFreeze, and thus UpdateWindow()). - if ((background_color == background_color_) && !changed_security_level && - !visibly_changed_permanent_text && !tab_for_state_restoring) + if (!changed_security_level && !visibly_changed_permanent_text && + !tab_for_state_restoring) return; - // Update our local state as desired. We set scheme_security_level_ here so - // it will already be correct before we get to any RevertAll()s below and use - // it. - ScopedFreeze freeze(this, GetTextObjectModel()); - if (background_color_ != background_color) { - background_color_ = background_color; - SetBackgroundColor(background_color_); - } - scheme_security_level_ = security_level; + // Update our local state as desired. We set security_level_ here so it will + // already be correct before we get to any RevertAll()s below and use it. + security_level_ = security_level; // When we're switching to a new tab, restore its state, if any. + ScopedFreeze freeze(this, GetTextObjectModel()); if (tab_for_state_restoring) { // Make sure we reset our own state first. The new tab may not have any // saved state, or it may not have had input in progress, in which case we @@ -605,6 +598,16 @@ std::wstring AutocompleteEditViewWin::GetText() const { return str; } +bool AutocompleteEditViewWin::IsEditingOrEmpty() const { + return model_->user_input_in_progress() || (GetTextLength() == 0); +} + +int AutocompleteEditViewWin::GetIcon() const { + return IsEditingOrEmpty() ? + AutocompleteMatch::TypeToIcon(model_->CurrentTextType()) : + toolbar_model_->GetIcon(); +} + void AutocompleteEditViewWin::SetUserText(const std::wstring& text, const std::wstring& display_text, bool update_popup) { @@ -1369,15 +1372,6 @@ void AutocompleteEditViewWin::OnKillFocus(HWND focus_wnd) { ScopedFreeze freeze(this, GetTextObjectModel()); DefWindowProc(WM_KILLFOCUS, reinterpret_cast<WPARAM>(focus_wnd), 0); - // Hide the "Type to search" hint if necessary. We do this after calling - // DefWindowProc() because processing the resulting IME messages may notify - // the controller that input is in progress, which could cause the visible - // hints to change. (I don't know if there's a real scenario where they - // actually do change, but this is safest.) - if (model_->show_search_hint() || - (model_->is_keyword_hint() && !model_->keyword().empty())) - controller_->OnChanged(); - // Cancel any user selection and scroll the text back to the beginning of the // URL. We have to do this after calling DefWindowProc() because otherwise // an in-progress IME composition will be completed at the new caret position, @@ -1687,12 +1681,6 @@ void AutocompleteEditViewWin::OnSetFocus(HWND focus_wnd) { model_->OnSetFocus(GetKeyState(VK_CONTROL) < 0); - // Notify controller if it needs to show hint UI of some kind. - ScopedFreeze freeze(this, GetTextObjectModel()); - if (model_->show_search_hint() || - (model_->is_keyword_hint() && !model_->keyword().empty())) - controller_->OnChanged(); - // Restore saved selection if available. if (saved_selection_for_focus_change_.cpMin != -1) { SetSelectionRange(saved_selection_for_focus_change_); @@ -2060,11 +2048,11 @@ void AutocompleteEditViewWin::EmphasizeURLComponents() { // Set the baseline emphasis. CHARFORMAT cf = {0}; cf.dwMask = CFM_COLOR; - const bool is_secure = (scheme_security_level_ == ToolbarModel::SECURE); // If we're going to emphasize parts of the text, then the baseline state // should be "de-emphasized". If not, then everything should be rendered in // the standard text color. - cf.crTextColor = skia::SkColorToCOLORREF(LocationBarView::GetColor(is_secure, + cf.crTextColor = skia::SkColorToCOLORREF(LocationBarView::GetColor( + security_level_, emphasize ? LocationBarView::DEEMPHASIZED_TEXT : LocationBarView::TEXT)); // NOTE: Don't use SetDefaultCharFormat() instead of the below; that sets the // format that will get applied to text added in the future, not to text @@ -2075,7 +2063,7 @@ void AutocompleteEditViewWin::EmphasizeURLComponents() { if (emphasize) { // We've found a host name, give it more emphasis. cf.crTextColor = skia::SkColorToCOLORREF(LocationBarView::GetColor( - is_secure, LocationBarView::TEXT)); + security_level_, LocationBarView::TEXT)); SetSelection(host.begin, host.end()); SetSelectionCharFormat(cf); } @@ -2083,13 +2071,13 @@ void AutocompleteEditViewWin::EmphasizeURLComponents() { // Emphasize the scheme for security UI display purposes (if necessary). insecure_scheme_component_.reset(); if (!model_->user_input_in_progress() && scheme.is_nonempty() && - (scheme_security_level_ != ToolbarModel::NORMAL)) { - if (!is_secure) { + (security_level_ != ToolbarModel::NONE)) { + if (security_level_ == ToolbarModel::SECURITY_ERROR) { insecure_scheme_component_.begin = scheme.begin; insecure_scheme_component_.len = scheme.len; } cf.crTextColor = skia::SkColorToCOLORREF(LocationBarView::GetColor( - is_secure, LocationBarView::SECURITY_TEXT)); + security_level_, LocationBarView::SECURITY_TEXT)); SetSelection(scheme.begin, scheme.end()); SetSelectionCharFormat(cf); } @@ -2183,8 +2171,8 @@ void AutocompleteEditViewWin::DrawSlashForInsecureScheme( canvas.save(); if (selection_rect.isEmpty() || canvas.clipRect(selection_rect, SkRegion::kDifference_Op)) { - paint.setColor(LocationBarView::GetColor(false, - LocationBarView::SCHEME_STRIKEOUT)); + paint.setColor(LocationBarView::GetColor(security_level_, + LocationBarView::SECURITY_TEXT)); canvas.drawLine(start_point.fX, start_point.fY, end_point.fX, end_point.fY, paint); } @@ -2192,7 +2180,7 @@ void AutocompleteEditViewWin::DrawSlashForInsecureScheme( // Draw the selected portion of the stroke. if (!selection_rect.isEmpty() && canvas.clipRect(selection_rect)) { - paint.setColor(LocationBarView::GetColor(false, + paint.setColor(LocationBarView::GetColor(security_level_, LocationBarView::SELECTED_TEXT)); canvas.drawLine(start_point.fX, start_point.fY, end_point.fX, end_point.fY, paint); diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.h b/chrome/browser/autocomplete/autocomplete_edit_view_win.h index 9de2d34..33af6a7 100644 --- a/chrome/browser/autocomplete/autocomplete_edit_view_win.h +++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.h @@ -69,7 +69,7 @@ class AutocompleteEditViewWin Profile* profile, CommandUpdater* command_updater, bool popup_window_mode, - const BubblePositioner* bubble_positioner); + const views::View* location_bar); ~AutocompleteEditViewWin(); views::View* parent_view() const { return parent_view_; } @@ -91,6 +91,9 @@ class AutocompleteEditViewWin virtual std::wstring GetText() const; + virtual bool IsEditingOrEmpty() const; + virtual int GetIcon() const; + virtual void SetUserText(const std::wstring& text) { SetUserText(text, text, true); } @@ -476,7 +479,7 @@ class AutocompleteEditViewWin // Security UI-related data. COLORREF background_color_; - ToolbarModel::SecurityLevel scheme_security_level_; + ToolbarModel::SecurityLevel security_level_; // This interface is useful for accessing the CRichEditCtrl at a low level. mutable ITextDocument* text_object_model_; diff --git a/chrome/browser/autocomplete/autocomplete_popup_model.cc b/chrome/browser/autocomplete/autocomplete_popup_model.cc index 41e0255..009cc0b 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_model.cc +++ b/chrome/browser/autocomplete/autocomplete_popup_model.cc @@ -103,12 +103,24 @@ void AutocompletePopupModel::SetSelectedLine(size_t line, if (line == selected_line_) return; // Nothing else to do. + // We need to update |selected_line_| before calling OnPopupDataChanged(), so + // that when the edit notifies its controller that something has changed, the + // controller can get the correct updated data. + // + // NOTE: We should never reach here with no selected line; the same code that + // opened the popup and made it possible to get here should have also set a + // selected line. + CHECK(selected_line_ != kNoMatch); + GURL current_destination(result.match_at(selected_line_).destination_url); + view_->InvalidateLine(selected_line_); + selected_line_ = line; + view_->InvalidateLine(selected_line_); + // Update the edit with the new data for this match. // TODO(pkasting): If |selected_line_| moves to the controller, this can be // eliminated and just become a call to the observer on the edit. std::wstring keyword; const bool is_keyword_hint = GetKeywordForMatch(match, &keyword); - if (reset_to_default) { std::wstring inline_autocomplete_text; if ((match.inline_autocomplete_offset != std::wstring::npos) && @@ -116,27 +128,15 @@ void AutocompletePopupModel::SetSelectedLine(size_t line, inline_autocomplete_text = match.fill_into_edit.substr(match.inline_autocomplete_offset); } - edit_model_->OnPopupDataChanged(inline_autocomplete_text, false, - keyword, is_keyword_hint, match.type); + edit_model_->OnPopupDataChanged(inline_autocomplete_text, NULL, + keyword, is_keyword_hint); } else { - edit_model_->OnPopupDataChanged(match.fill_into_edit, true, - keyword, is_keyword_hint, match.type); + edit_model_->OnPopupDataChanged(match.fill_into_edit, ¤t_destination, + keyword, is_keyword_hint); } // Repaint old and new selected lines immediately, so that the edit doesn't - // appear to update [much] faster than the popup. We must not update - // |selected_line_| before calling OnPopupDataChanged() (since the edit may - // call us back to get data about the old selection), and we must not call - // UpdateWindow() before updating |selected_line_| (since the paint routine - // relies on knowing the correct selected line). - // - // NOTE: We should never reach here with no selected line; the same code that - // opened the popup and made it possible to get here should have also set a - // selected line. - CHECK(selected_line_ != kNoMatch); - view_->InvalidateLine(selected_line_); - selected_line_ = line; - view_->InvalidateLine(selected_line_); + // appear to update [much] faster than the popup. view_->PaintUpdatesNow(); } @@ -147,22 +147,21 @@ void AutocompletePopupModel::ResetToDefaultMatch() { view_->OnDragCanceled(); } -GURL AutocompletePopupModel::URLsForCurrentSelection( - PageTransition::Type* transition, - bool* is_history_what_you_typed_match, +void AutocompletePopupModel::InfoForCurrentSelection( + AutocompleteMatch* match, GURL* alternate_nav_url) const { + DCHECK(match != NULL); const AutocompleteResult* result; - AutocompleteResult::const_iterator match; if (!controller_->done()) { result = &controller_->latest_result(); // It's technically possible for |result| to be empty if no provider returns // a synchronous result but the query has not completed synchronously; // pratically, however, that should never actually happen. if (result->empty()) - return GURL(); + return; // The user cannot have manually selected a match, or the query would have // stopped. So the default match must be the desired selection. - match = result->default_match(); + *match = *result->default_match(); } else { CHECK(IsOpen()); // The query isn't running, so the standard result set can't possibly be out @@ -177,15 +176,10 @@ GURL AutocompletePopupModel::URLsForCurrentSelection( // called instead. CHECK(!result->empty()); CHECK(selected_line_ < result->size()); - match = result->begin() + selected_line_; + *match = result->match_at(selected_line_); } - if (transition) - *transition = match->transition; - if (is_history_what_you_typed_match) - *is_history_what_you_typed_match = match->is_history_what_you_typed_match; if (alternate_nav_url && manually_selected_match_.empty()) *alternate_nav_url = result->alternate_nav_url(); - return match->destination_url; } bool AutocompletePopupModel::GetKeywordForMatch(const AutocompleteMatch& match, @@ -239,7 +233,7 @@ void AutocompletePopupModel::Move(int count) { } void AutocompletePopupModel::TryDeletingCurrentItem() { - // We could use URLsForCurrentSelection() here, but it seems better to try + // We could use InfoForCurrentSelection() here, but it seems better to try // and shift-delete the actual selection, rather than any "in progress, not // yet visible" one. if (selected_line_ == kNoMatch) diff --git a/chrome/browser/autocomplete/autocomplete_popup_model.h b/chrome/browser/autocomplete/autocomplete_popup_model.h index 166a238..a986419 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_model.h +++ b/chrome/browser/autocomplete/autocomplete_popup_model.h @@ -1,4 +1,4 @@ -// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -73,15 +73,9 @@ class AutocompletePopupModel : public NotificationObserver { // will change the selected line back to the default match and redraw. void ResetToDefaultMatch(); - // Returns the URL for the selected match. If an update is in progress, - // "selected" means "default in the latest matches". If there are no - // matches, returns the empty string. - // - // If |transition_type| is non-NULL, it will be set to the appropriate - // transition type for the selected entry (TYPED or GENERATED). - // - // If |is_history_what_you_typed_match| is non-NULL, it will be set based on - // the selected entry's is_history_what_you_typed value. + // Copies the selected match into |match|. If an update is in progress, + // "selected" means "default in the latest matches". If there are no matches, + // does not update |match|. // // If |alternate_nav_url| is non-NULL, it will be set to the alternate // navigation URL for |url| if one exists, or left unchanged otherwise. See @@ -89,10 +83,8 @@ class AutocompletePopupModel : public NotificationObserver { // // TODO(pkasting): When manually_selected_match_ moves to the controller, this // can move too. - GURL URLsForCurrentSelection( - PageTransition::Type* transition, - bool* is_history_what_you_typed_match, - GURL* alternate_nav_url) const; + void InfoForCurrentSelection(AutocompleteMatch* match, + GURL* alternate_nav_url) const; // Gets the selected keyword or keyword hint for the given match. Returns // true if |keyword| represents a keyword hint, or false if |keyword| diff --git a/chrome/browser/autocomplete/autocomplete_popup_view.h b/chrome/browser/autocomplete/autocomplete_popup_view.h index 41b21a6..5674e4b 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view.h +++ b/chrome/browser/autocomplete/autocomplete_popup_view.h @@ -13,15 +13,7 @@ #include "build/build_config.h" -class AutocompleteEditView; class AutocompletePopupModel; -class BubblePositioner; -namespace gfx { -class Font; -} -class AutocompleteEditViewWin; -class AutocompleteEditModel; -class Profile; class AutocompletePopupView { public: @@ -48,17 +40,6 @@ class AutocompletePopupView { // Returns the popup's model. virtual AutocompletePopupModel* GetModel() = 0; - -#if !defined(OS_MACOSX) - // Create a popup view implementation. It may make sense for this to become - // platform independent eventually. - static AutocompletePopupView* CreatePopupView( - const gfx::Font& font, - AutocompleteEditView* edit_view, - AutocompleteEditModel* edit_model, - Profile* profile, - const BubblePositioner* bubble_positioner); -#endif }; #endif // CHROME_BROWSER_AUTOCOMPLETE_AUTOCOMPLETE_POPUP_VIEW_H_ diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc index 0332c28..2f9895d 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc +++ b/chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -18,16 +18,18 @@ #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/bubble_positioner.h" #include "chrome/browser/defaults.h" +#include "chrome/browser/gtk/gtk_theme_provider.h" #include "chrome/browser/gtk/gtk_util.h" #include "chrome/browser/profile.h" #include "chrome/browser/search_engines/template_url.h" #include "chrome/browser/search_engines/template_url_model.h" #include "chrome/common/notification_service.h" +#include "gfx/color_utils.h" #include "gfx/font.h" #include "gfx/gtk_util.h" #include "gfx/rect.h" +#include "gfx/skia_utils_gtk.h" #include "grit/theme_resources.h" namespace { @@ -44,27 +46,40 @@ const GdkColor kDescriptionSelectedTextColor = GDK_COLOR_RGB(0x78, 0x82, 0xb1); // We have a 1 pixel border around the entire results popup. const int kBorderThickness = 1; + // The vertical height of each result. const int kHeightPerResult = 24; + // Width of the icons. -const int kIconWidth = 16; +const int kIconWidth = 17; + // We want to vertically center the image in the result space. -const int kIconTopPadding = 4; +const int kIconTopPadding = 2; + // Space between the left edge (including the border) and the text. -const int kIconLeftPadding = 6 + kBorderThickness; -// Space between the image and the text. Would be 6 to line up with the -// entry, but nudge it a bit more to match with the text in the entry. -const int kIconRightPadding = 10; +const int kIconLeftPadding = 5 + kBorderThickness; + +// Space between the image and the text. +const int kIconRightPadding = 7; + // Space between the left edge (including the border) and the text. const int kIconAreaWidth = kIconLeftPadding + kIconWidth + kIconRightPadding; + // Space between the right edge (including the border) and the text. const int kRightPadding = 3; + // When we have both a content and description string, we don't want the // content to push the description off. Limit the content to a percentage of // the total width. const float kContentWidthPercentage = 0.7; +// How much to offset the popup from the bottom of the location bar in gtk mode. +const int kGtkVerticalOffset = 3; + +// How much we shrink the popup on the left/right in gtk mode. +const int kGtkHorizontalOffset = 1; + // UTF-8 Left-to-right embedding. const char* kLRE = "\xe2\x80\xaa"; @@ -103,6 +118,7 @@ void SetupLayoutForMatch(PangoLayout* layout, const std::wstring& text, AutocompleteMatch::ACMatchClassifications classifications, const GdkColor* base_color, + const GdkColor* url_color, const std::string& prefix_text) { // We can have a prefix, or insert additional characters while processing the @@ -139,7 +155,7 @@ void SetupLayoutForMatch(PangoLayout* layout, // support it. const GdkColor* color = base_color; if (i->style & ACMatchClassification::URL) { - color = &kURLTextColor; + color = url_color; // Insert a left to right embedding to make sure that URLs are shown LTR. std::string lre(kLRE); text_utf8.insert(offset, lre); @@ -164,48 +180,81 @@ void SetupLayoutForMatch(PangoLayout* layout, pango_attr_list_unref(attrs); } -GdkPixbuf* IconForMatch(const AutocompleteMatch& match, bool selected) { - // TODO(deanm): These would be better as pixmaps someday. - // TODO(estade): Do we want to flip these for RTL? (Windows doesn't). - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - static GdkPixbuf* o2_globe = rb.GetPixbufNamed(IDR_O2_GLOBE); - static GdkPixbuf* o2_globe_s = rb.GetPixbufNamed(IDR_O2_GLOBE_SELECTED_DARK); - static GdkPixbuf* o2_history = rb.GetPixbufNamed(IDR_O2_HISTORY); - static GdkPixbuf* o2_history_s = - rb.GetPixbufNamed(IDR_O2_HISTORY_SELECTED_DARK); - static GdkPixbuf* o2_more = rb.GetPixbufNamed(IDR_O2_MORE); - static GdkPixbuf* o2_more_s = rb.GetPixbufNamed(IDR_O2_MORE_SELECTED_DARK); - static GdkPixbuf* o2_search = rb.GetPixbufNamed(IDR_O2_SEARCH); - static GdkPixbuf* o2_search_s = - rb.GetPixbufNamed(IDR_O2_SEARCH_SELECTED_DARK); - static GdkPixbuf* o2_star = rb.GetPixbufNamed(IDR_O2_STAR); - static GdkPixbuf* o2_star_s = rb.GetPixbufNamed(IDR_O2_STAR_SELECTED_DARK); - - if (match.starred) - return selected ? o2_star_s : o2_star; - - switch (match.type) { - case AutocompleteMatch::URL_WHAT_YOU_TYPED: - case AutocompleteMatch::NAVSUGGEST: - return selected ? o2_globe_s : o2_globe; - case AutocompleteMatch::HISTORY_URL: - case AutocompleteMatch::HISTORY_TITLE: - case AutocompleteMatch::HISTORY_BODY: - case AutocompleteMatch::HISTORY_KEYWORD: - return selected ? o2_history_s : o2_history; - case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: - case AutocompleteMatch::SEARCH_HISTORY: - case AutocompleteMatch::SEARCH_SUGGEST: - case AutocompleteMatch::SEARCH_OTHER_ENGINE: - return selected ? o2_search_s : o2_search; - case AutocompleteMatch::OPEN_HISTORY_PAGE: - return selected ? o2_more_s : o2_more; - default: - NOTREACHED(); - break; +GdkPixbuf* IconForMatch(BrowserThemeProvider* theme, + const AutocompleteMatch& match, + bool selected) { + int icon = match.starred ? + IDR_OMNIBOX_STAR : AutocompleteMatch::TypeToIcon(match.type); + if (selected) { + switch (icon) { + case IDR_OMNIBOX_HTTP: icon = IDR_OMNIBOX_HTTP_DARK; break; + case IDR_OMNIBOX_HISTORY: icon = IDR_OMNIBOX_HISTORY_DARK; break; + case IDR_OMNIBOX_SEARCH: icon = IDR_OMNIBOX_SEARCH_DARK; break; + case IDR_OMNIBOX_MORE: icon = IDR_OMNIBOX_MORE_DARK; break; + case IDR_OMNIBOX_STAR: icon = IDR_OMNIBOX_STAR_DARK; break; + default: NOTREACHED(); break; + } } - return NULL; + // TODO(estade): Do we want to flip these for RTL? (Windows doesn't). + return theme->GetPixbufNamed(icon); +} + +// Generates the normal URL color, a green color used in unhighlighted URL +// text. It is a mix of |kURLTextColor| and the current text color. Unlike the +// selected text color, It is more important to match the qualities of the +// foreground typeface color instead of taking the background into account. +GdkColor NormalURLColor(GdkColor foreground) { + color_utils::HSL fg_hsl; + color_utils::SkColorToHSL(gfx::GdkColorToSkColor(foreground), &fg_hsl); + + color_utils::HSL hue_hsl; + color_utils::SkColorToHSL(gfx::GdkColorToSkColor(kURLTextColor), &hue_hsl); + + // Only allow colors that have a fair amount of saturation in them (color vs + // white). This means that our output color will always be fairly green. + double s = std::max(0.5, fg_hsl.s); + + // Make sure the luminance is at least as bright as the |kURLTextColor| green + // would be if we were to use that. + double l; + if (fg_hsl.l < hue_hsl.l) + l = hue_hsl.l; + else + l = (fg_hsl.l + hue_hsl.l) / 2; + + color_utils::HSL output = { hue_hsl.h, s, l }; + return gfx::SkColorToGdkColor(color_utils::HSLToSkColor(output, 255)); +} + +// Generates the selected URL color, a green color used on URL text in the +// currently highlighted entry in the autocomplete popup. It's a mix of +// |kURLTextColor|, the current text color, and the background color (the +// select highlight). It is more important to contrast with the background +// saturation than to look exactly like the foreground color. +GdkColor SelectedURLColor(GdkColor foreground, GdkColor background) { + color_utils::HSL fg_hsl; + color_utils::SkColorToHSL(gfx::GdkColorToSkColor(foreground), &fg_hsl); + + color_utils::HSL bg_hsl; + color_utils::SkColorToHSL(gfx::GdkColorToSkColor(background), &bg_hsl); + + color_utils::HSL hue_hsl; + color_utils::SkColorToHSL(gfx::GdkColorToSkColor(kURLTextColor), &hue_hsl); + + // The saturation of the text should be opposite of the background, clamped + // to 0.2-0.8. We make sure it's greater than 0.2 so there's some color, but + // less than 0.8 so it's not the oversaturated neon-color. + double opposite_s = 1 - bg_hsl.s; + double s = std::max(0.2, std::min(0.8, opposite_s)); + + // The luminance should match the luminance of the foreground text. Again, + // we clamp so as to have at some amount of color (green) in the text. + double opposite_l = fg_hsl.l; + double l = std::max(0.1, std::min(0.9, opposite_l)); + + color_utils::HSL output = { hue_hsl.h, s, l }; + return gfx::SkColorToGdkColor(color_utils::HSLToSkColor(output, 255)); } } // namespace @@ -214,12 +263,13 @@ AutocompletePopupViewGtk::AutocompletePopupViewGtk( AutocompleteEditView* edit_view, AutocompleteEditModel* edit_model, Profile* profile, - const BubblePositioner* bubble_positioner) + GtkWidget* location_bar) : model_(new AutocompletePopupModel(this, edit_model, profile)), edit_view_(edit_view), - bubble_positioner_(bubble_positioner), + location_bar_(location_bar), window_(gtk_window_new(GTK_WINDOW_POPUP)), layout_(NULL), + theme_provider_(GtkThemeProvider::GetFrom(profile)), ignore_mouse_drag_(false), opened_(false) { GTK_WIDGET_UNSET_FLAGS(window_, GTK_CAN_FOCUS); @@ -229,8 +279,6 @@ AutocompletePopupViewGtk::AutocompletePopupViewGtk( gtk_widget_set_app_paintable(window_, TRUE); // Have GTK double buffer around the expose signal. gtk_widget_set_double_buffered(window_, TRUE); - // Set the background color, so we don't need to paint it manually. - gtk_widget_modify_bg(window_, GTK_STATE_NORMAL, &kBackgroundColor); // Cache the layout so we don't have to create it for every expose. If we // were a real widget we should handle changing directions, but we're not @@ -263,6 +311,11 @@ AutocompletePopupViewGtk::AutocompletePopupViewGtk( g_signal_connect(window_, "expose-event", G_CALLBACK(&HandleExposeThunk), this); + registrar_.Add(this, + NotificationType::BROWSER_THEME_CHANGED, + NotificationService::AllSources()); + theme_provider_->InitThemesFor(this); + // TODO(erg): There appears to be a bug somewhere in something which shows // itself when we're in NX. Previously, we called // gtk_util::ActAsRoundedWindow() to make this popup have rounded @@ -317,16 +370,85 @@ AutocompletePopupModel* AutocompletePopupViewGtk::GetModel() { return model_.get(); } +void AutocompletePopupViewGtk::Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(type == NotificationType::BROWSER_THEME_CHANGED); + + if (theme_provider_->UseGtkTheme()) { + border_color_ = theme_provider_->GetBorderColor(); + + // Create a fake gtk table + GtkWidget* fake_tree = gtk_entry_new(); + GtkStyle* style = gtk_rc_get_style(fake_tree); + + background_color_ = style->base[GTK_STATE_NORMAL]; + selected_background_color_ = style->base[GTK_STATE_SELECTED]; + hovered_background_color_ = gtk_util::AverageColors( + background_color_, selected_background_color_); + + content_text_color_ = style->text[GTK_STATE_NORMAL]; + selected_content_text_color_ = style->text[GTK_STATE_SELECTED]; + url_text_color_ = + NormalURLColor(style->text[GTK_STATE_NORMAL]); + url_selected_text_color_ = + SelectedURLColor(style->text[GTK_STATE_SELECTED], + style->base[GTK_STATE_SELECTED]); + + description_text_color_ = style->text[GTK_STATE_NORMAL]; + description_selected_text_color_ = style->text[GTK_STATE_SELECTED]; + + g_object_ref_sink(fake_tree); + g_object_unref(fake_tree); + } else { + border_color_ = kBorderColor; + background_color_ = kBackgroundColor; + selected_background_color_ = kSelectedBackgroundColor; + hovered_background_color_ = kHoveredBackgroundColor; + + content_text_color_ = kContentTextColor; + selected_content_text_color_ = kContentTextColor; + url_text_color_ = kURLTextColor; + url_selected_text_color_ = kURLTextColor; + description_text_color_ = kDescriptionTextColor; + description_selected_text_color_ = kDescriptionSelectedTextColor; + } + + // Set the background color, so we don't need to paint it manually. + gtk_widget_modify_bg(window_, GTK_STATE_NORMAL, &background_color_); +} + void AutocompletePopupViewGtk::Show(size_t num_results) { - gfx::Rect rect = bubble_positioner_->GetLocationStackBounds(); - rect.set_y(rect.bottom()); - rect.set_height((num_results * kHeightPerResult) + (kBorderThickness * 2)); - - gtk_window_move(GTK_WINDOW(window_), rect.x(), rect.y()); - gtk_widget_set_size_request(window_, rect.width(), rect.height()); - gtk_widget_show(window_); - StackWindow(); - opened_ = true; + gint origin_x, origin_y; + gdk_window_get_origin(location_bar_->window, &origin_x, &origin_y); + GtkAllocation allocation = location_bar_->allocation; + int vertical_offset = 0; + int horizontal_offset = 0; + if (theme_provider_->UseGtkTheme()) { + // Shrink the popup by 1 pixel on both sides in gtk mode. The darkest line + // is usually one pixel in, and is almost always +/-1 pixel from this, + // meaning the vertical offset will hide (hopefully) problems when this is + // wrong. + horizontal_offset = kGtkHorizontalOffset; + + // We offset the the popup from the bottom of the location bar in gtk + // mode. The background color between the bottom of the location bar and + // the popup helps hide the fact that we can't really reliably match what + // the user would otherwise preceive as the left/right edges of the + // location bar. + vertical_offset = kGtkVerticalOffset; + } + + gtk_window_move(GTK_WINDOW(window_), + origin_x + allocation.x - kBorderThickness + horizontal_offset, + origin_y + allocation.y + allocation.height - kBorderThickness - 1 + + vertical_offset); + gtk_widget_set_size_request(window_, + allocation.width + (kBorderThickness * 2) - (horizontal_offset * 2), + (num_results * kHeightPerResult) + (kBorderThickness * 2)); + gtk_widget_show(window_); + StackWindow(); + opened_ = true; } void AutocompletePopupViewGtk::Hide() { @@ -426,7 +548,7 @@ gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget, GdkGC* gc = gdk_gc_new(drawable); // kBorderColor is unallocated, so use the GdkRGB routine. - gdk_gc_set_rgb_fg_color(gc, &kBorderColor); + gdk_gc_set_rgb_fg_color(gc, &border_color_); // This assert is kinda ugly, but it would be more currently unneeded work // to support painting a border that isn't 1 pixel thick. There is no point @@ -439,8 +561,17 @@ gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget, pango_layout_set_height(layout_, kHeightPerResult * PANGO_SCALE); - // TODO(deanm): Intersect the line and damage rects, and only repaint and - // layout the lines that are actually damaged. For now paint everything. + // An offset to align text in gtk mode. The hard coded constants in this file + // are all created for the chrome-theme. In an effort to make this look good + // on the majority of gtk themes, we shrink the popup by one pixel on each + // side and push it downwards a bit so there's space between the drawn + // location bar and the popup so we don't touch it (contrast with + // chrome-theme where that's exactly what we want). Because of that, we need + // to shift the content inside the popup by one pixel. + int gtk_offset = 0; + if (theme_provider_->UseGtkTheme()) + gtk_offset = kGtkHorizontalOffset; + for (size_t i = 0; i < result.size(); ++i) { gfx::Rect line_rect = GetRectForLine(i, window_rect.width()); // Only repaint and layout damaged lines. @@ -451,18 +582,19 @@ gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget, bool is_selected = (model_->selected_line() == i); bool is_hovered = (model_->hovered_line() == i); if (is_selected || is_hovered) { - gdk_gc_set_rgb_fg_color(gc, is_selected ? &kSelectedBackgroundColor : - &kHoveredBackgroundColor); + gdk_gc_set_rgb_fg_color(gc, is_selected ? &selected_background_color_ : + &hovered_background_color_); // This entry is selected or hovered, fill a rect with the color. gdk_draw_rectangle(drawable, gc, TRUE, line_rect.x(), line_rect.y(), line_rect.width(), line_rect.height()); } - int icon_start_x = ltr ? kIconLeftPadding : - line_rect.width() - kIconLeftPadding - kIconWidth; + int icon_start_x = ltr ? (kIconLeftPadding - gtk_offset) : + (line_rect.width() - kIconLeftPadding - kIconWidth + gtk_offset); // Draw the icon for this result. - DrawFullPixbuf(drawable, gc, IconForMatch(match, is_selected), + DrawFullPixbuf(drawable, gc, + IconForMatch(theme_provider_, match, is_selected), icon_start_x, line_rect.y() + kIconTopPadding); // Draw the results text vertically centered in the results space. @@ -476,7 +608,11 @@ gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget, // Note: We force to URL to LTR for all text directions. SetupLayoutForMatch(layout_, match.contents, match.contents_class, - &kContentTextColor, std::string()); + is_selected ? &selected_content_text_color_ : + &content_text_color_, + is_selected ? &url_selected_text_color_ : + &url_text_color_, + std::string()); int actual_content_width, actual_content_height; pango_layout_get_size(layout_, @@ -490,22 +626,25 @@ gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget, line_rect.y() + ((kHeightPerResult - actual_content_height) / 2)); gdk_draw_layout(drawable, gc, - ltr ? kIconAreaWidth : text_width - actual_content_width, + ltr ? (kIconAreaWidth - gtk_offset) : + (text_width - actual_content_width + gtk_offset), content_y, layout_); if (has_description) { pango_layout_set_width(layout_, (text_width - actual_content_width) * PANGO_SCALE); SetupLayoutForMatch(layout_, match.description, match.description_class, - is_selected ? &kDescriptionSelectedTextColor : - &kDescriptionTextColor, + is_selected ? &description_selected_text_color_ : + &description_text_color_, + is_selected ? &url_selected_text_color_ : + &url_text_color_, std::string(" - ")); gint actual_description_width; pango_layout_get_size(layout_, &actual_description_width, NULL); - gdk_draw_layout(drawable, gc, - ltr ? kIconAreaWidth + actual_content_width : - text_width - actual_content_width - - actual_description_width / PANGO_SCALE, + gdk_draw_layout(drawable, gc, ltr ? + (kIconAreaWidth - gtk_offset + actual_content_width) : + (text_width - actual_content_width + gtk_offset - + (actual_description_width / PANGO_SCALE)), content_y, layout_); } } @@ -514,14 +653,3 @@ gboolean AutocompletePopupViewGtk::HandleExpose(GtkWidget* widget, return TRUE; } - -// static -AutocompletePopupView* AutocompletePopupView::CreatePopupView( - const gfx::Font& font, - AutocompleteEditView* edit_view, - AutocompleteEditModel* edit_model, - Profile* profile, - const BubblePositioner* bubble_positioner) { - return new AutocompletePopupViewGtk(edit_view, edit_model, profile, - bubble_positioner); -} diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_gtk.h b/chrome/browser/autocomplete/autocomplete_popup_view_gtk.h index a56a55a..4759417 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_gtk.h +++ b/chrome/browser/autocomplete/autocomplete_popup_view_gtk.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,23 +10,27 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" #include "chrome/browser/autocomplete/autocomplete_popup_view.h" +#include "chrome/common/notification_observer.h" +#include "chrome/common/notification_registrar.h" #include "webkit/glue/window_open_disposition.h" class AutocompleteEditModel; class AutocompleteEditView; class AutocompletePopupModel; +class GtkThemeProvider; class Profile; class SkBitmap; -class AutocompletePopupViewGtk : public AutocompletePopupView { +class AutocompletePopupViewGtk : public AutocompletePopupView, + public NotificationObserver { public: AutocompletePopupViewGtk(AutocompleteEditView* edit_view, AutocompleteEditModel* edit_model, Profile* profile, - const BubblePositioner* bubble_positioner); + GtkWidget* location_bar); ~AutocompletePopupViewGtk(); - // Implement the AutocompletePopupView interface. + // Overridden from AutocompletePopupView: virtual bool IsOpen() const { return opened_; } virtual void InvalidateLine(size_t line); virtual void UpdatePopupAppearance(); @@ -34,6 +38,11 @@ class AutocompletePopupViewGtk : public AutocompletePopupView { virtual void OnDragCanceled(); virtual AutocompletePopupModel* GetModel(); + // Overridden from NotificationObserver: + virtual void Observe(NotificationType type, + const NotificationSource& source, + const NotificationDetails& details); + private: void Show(size_t num_results); void Hide(); @@ -79,7 +88,7 @@ class AutocompletePopupViewGtk : public AutocompletePopupView { scoped_ptr<AutocompletePopupModel> model_; AutocompleteEditView* edit_view_; - const BubblePositioner* bubble_positioner_; + GtkWidget* location_bar_; // Our popup window, which is the only widget used, and we paint it on our // own. This widget shouldn't be exposed outside of this class. @@ -87,6 +96,22 @@ class AutocompletePopupViewGtk : public AutocompletePopupView { // The pango layout object created from the window, cached across exposes. PangoLayout* layout_; + GtkThemeProvider* theme_provider_; + NotificationRegistrar registrar_; + + // A list of colors which we should use for drawing the popup. These change + // between gtk and normal mode. + GdkColor border_color_; + GdkColor background_color_; + GdkColor selected_background_color_; + GdkColor hovered_background_color_; + GdkColor content_text_color_; + GdkColor selected_content_text_color_; + GdkColor url_text_color_; + GdkColor url_selected_text_color_; + GdkColor description_text_color_; + GdkColor description_selected_text_color_; + // If the user cancels a dragging action (i.e. by pressing ESC), we don't have // a convenient way to release mouse capture. Instead we use this flag to // simply ignore all remaining drag events, and the eventual mouse release diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.h b/chrome/browser/autocomplete/autocomplete_popup_view_mac.h index a430f58..56d20fd 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.h +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.h @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -32,7 +32,6 @@ class AutocompletePopupViewMac : public AutocompletePopupView { public: AutocompletePopupViewMac(AutocompleteEditViewMac* edit_view, AutocompleteEditModel* edit_model, - const BubblePositioner* bubble_positioner, Profile* profile, NSTextField* field); virtual ~AutocompletePopupViewMac(); @@ -109,7 +108,6 @@ class AutocompletePopupViewMac : public AutocompletePopupView { scoped_ptr<AutocompletePopupModel> model_; AutocompleteEditViewMac* edit_view_; - const BubblePositioner* bubble_positioner_; // owned by toolbar controller NSTextField* field_; // owned by tab controller // Child window containing a matrix which implements the popup. diff --git a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm index 2ab01ad..29ea9ab 100644 --- a/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm +++ b/chrome/browser/autocomplete/autocomplete_popup_view_mac.mm @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -10,11 +10,11 @@ #include "chrome/browser/autocomplete/autocomplete_edit.h" #include "chrome/browser/autocomplete/autocomplete_edit_view_mac.h" #include "chrome/browser/autocomplete/autocomplete_popup_model.h" -#include "chrome/browser/bubble_positioner.h" #include "chrome/browser/cocoa/event_utils.h" #include "gfx/rect.h" #include "grit/theme_resources.h" #import "third_party/GTM/AppKit/GTMNSAnimation+Duration.h" +#import "third_party/GTM/AppKit/GTMNSBezierPath+RoundRect.h" namespace { @@ -31,17 +31,17 @@ const int kCellHeightAdjust = 7.0; const CGFloat kPopupRoundingRadius = 3.5; // Gap between the field and the popup. -const CGFloat kPopupFieldGap = 2.0; +const CGFloat kPopupFieldGap = 0.0; // How opaque the popup window should be. This matches Windows (see // autocomplete_popup_contents_view.cc, kGlassPopupTransparency). const CGFloat kPopupAlpha = 240.0 / 255.0; // How much space to leave for the left and right margins. -const CGFloat kLeftRightMargin = 6.0; +const CGFloat kLeftRightMargin = 5.0; // How far to offset the text column from the left. -const CGFloat kTextXOffset = 31.0; +const CGFloat kTextXOffset = 29.0; // Animation duration when animating the popup window smaller. const CGFloat kShrinkAnimationDuration = 0.1; @@ -78,54 +78,6 @@ static const NSColor* DescriptionTextColor() { return [NSColor darkGrayColor]; } -// Helper to fetch and retain an image from the resource bundle. -NSImage* RetainedResourceImage(int resource_id) { - ResourceBundle& rb = ResourceBundle::GetSharedInstance(); - NSImage* image = rb.GetNSImageNamed(resource_id); - DCHECK(image); - return [image retain]; -} - -// Return the appropriate icon for the given match. Derived from the -// gtk code. -NSImage* MatchIcon(const AutocompleteMatch& match) { - if (match.starred) { - static NSImage* starImage = RetainedResourceImage(IDR_O2_STAR); - return starImage; - } - - switch (match.type) { - case AutocompleteMatch::URL_WHAT_YOU_TYPED: - case AutocompleteMatch::NAVSUGGEST: { - static NSImage* globeImage = RetainedResourceImage(IDR_O2_GLOBE); - return globeImage; - } - case AutocompleteMatch::HISTORY_URL: - case AutocompleteMatch::HISTORY_TITLE: - case AutocompleteMatch::HISTORY_BODY: - case AutocompleteMatch::HISTORY_KEYWORD: { - static NSImage* historyImage = RetainedResourceImage(IDR_O2_HISTORY); - return historyImage; - } - case AutocompleteMatch::SEARCH_WHAT_YOU_TYPED: - case AutocompleteMatch::SEARCH_HISTORY: - case AutocompleteMatch::SEARCH_SUGGEST: - case AutocompleteMatch::SEARCH_OTHER_ENGINE: { - static NSImage* searchImage = RetainedResourceImage(IDR_O2_SEARCH); - return searchImage; - } - case AutocompleteMatch::OPEN_HISTORY_PAGE: { - static NSImage* moreImage = RetainedResourceImage(IDR_O2_MORE); - return moreImage; - } - default: - NOTREACHED(); - break; - } - - return nil; -} - } // namespace // Helper for MatchText() to allow sharing code between the contents @@ -293,12 +245,10 @@ NSAttributedString* AutocompletePopupViewMac::MatchText( AutocompletePopupViewMac::AutocompletePopupViewMac( AutocompleteEditViewMac* edit_view, AutocompleteEditModel* edit_model, - const BubblePositioner* bubble_positioner, Profile* profile, NSTextField* field) : model_(new AutocompletePopupModel(this, edit_model, profile)), edit_view_(edit_view), - bubble_positioner_(bubble_positioner), field_(field), popup_(nil) { DCHECK(edit_view); @@ -365,8 +315,12 @@ void AutocompletePopupViewMac::UpdatePopupAppearance() { CreatePopupIfNeeded(); // Layout the popup and size it to land underneath the field. - NSRect r = - NSRectFromCGRect(bubble_positioner_->GetLocationStackBounds().ToCGRect()); + // The field has a single-pixel border on the left and right. This + // needs to be factored out so that the popup window's border (which + // is outside the frame) lines up. + const int kLocationStackEdgeWidth = 1; + NSRect r = NSInsetRect([field_ convertRect:[field_ bounds] toView:nil], + kLocationStackEdgeWidth, 0); r.origin = [[field_ window] convertBaseToScreen:r.origin]; DCHECK_GT(r.size.width, 0.0); @@ -386,7 +340,9 @@ void AutocompletePopupViewMac::UpdatePopupAppearance() { for (size_t ii = 0; ii < rows; ++ii) { AutocompleteButtonCell* cell = [matrix cellAtRow:ii column:0]; const AutocompleteMatch& match = model_->result().match_at(ii); - [cell setImage:MatchIcon(match)]; + const int resource_id = match.starred ? IDR_OMNIBOX_STAR + : AutocompleteMatch::TypeToIcon(match.type); + [cell setImage:AutocompleteEditViewMac::ImageForResource(resource_id)]; [cell setAttributedTitle:MatchText(match, resultFont, r.size.width)]; } @@ -507,7 +463,11 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { imageRect.origin.y += floor((NSHeight(cellFrame) - NSHeight(imageRect)) / 2); imageRect.origin.x += kLeftRightMargin; - [self drawImage:image withFrame:imageRect inView:controlView]; + [image setFlipped:[controlView isFlipped]]; + [image drawInRect:imageRect + fromRect:NSZeroRect // Entire image + operation:NSCompositeSourceOver + fraction:1.0]; } // Adjust the title position to be lined up under the field's text. @@ -704,10 +664,15 @@ void AutocompletePopupViewMac::OpenURLForRow(int row, bool force_background) { // This handles drawing the decorations of the rounded popup window, // calling on NSMatrix to draw the actual contents. - (void)drawRect:(NSRect)rect { + // Apparently this expects flipped coordinates, because in order to + // round the bottom corners visually, I need to specify the top + // corners here. NSBezierPath* path = - [NSBezierPath bezierPathWithRoundedRect:[self bounds] - xRadius:kPopupRoundingRadius - yRadius:kPopupRoundingRadius]; + [NSBezierPath gtm_bezierPathWithRoundRect:[self bounds] + topLeftCornerRadius:kPopupRoundingRadius + topRightCornerRadius:kPopupRoundingRadius + bottomLeftCornerRadius:0.0 + bottomRightCornerRadius:0.0]; // Draw the matrix clipped to our border. [NSGraphicsContext saveGraphicsState]; diff --git a/chrome/browser/autocomplete/history_contents_provider.cc b/chrome/browser/autocomplete/history_contents_provider.cc index ac81c31..1e72ceb 100644 --- a/chrome/browser/autocomplete/history_contents_provider.cc +++ b/chrome/browser/autocomplete/history_contents_provider.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -207,11 +207,9 @@ AutocompleteMatch HistoryContentsProvider::ResultToMatch( // Also show star in popup. AutocompleteMatch match(this, score, false, MatchInTitle(result) ? AutocompleteMatch::HISTORY_TITLE : AutocompleteMatch::HISTORY_BODY); - match.fill_into_edit = StringForURLDisplay(result.url(), true); + match.fill_into_edit = StringForURLDisplay(result.url(), true, trim_http_); match.destination_url = result.url(); match.contents = match.fill_into_edit; - if (trim_http_) - TrimHttpPrefix(&match.contents); match.contents_class.push_back( ACMatchClassification(0, ACMatchClassification::URL)); match.description = result.title(); diff --git a/chrome/browser/autocomplete/history_url_provider.cc b/chrome/browser/autocomplete/history_url_provider.cc index 2708d47..a748700 100644 --- a/chrome/browser/autocomplete/history_url_provider.cc +++ b/chrome/browser/autocomplete/history_url_provider.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -256,10 +256,14 @@ AutocompleteMatch HistoryURLProvider::SuggestExactInput( const GURL& url = input.canonicalized_url(); if (url.is_valid()) { match.destination_url = url; - match.fill_into_edit = StringForURLDisplay(url, false); + match.fill_into_edit = StringForURLDisplay(url, false, false); // NOTE: Don't set match.input_location (to allow inline autocompletion) // here, it's surprising and annoying. // Trim off "http://" if the user didn't type it. + // Double NOTE: we use TrimHttpPrefix here rather than StringForURLDisplay + // to strip the http as we need to know the offset so we can adjust the + // match_location below. StringForURLDisplay and TrimHttpPrefix have + // slightly different behavior when stripping http as well. const size_t offset = trim_http ? TrimHttpPrefix(&match.fill_into_edit) : 0; // Try to highlight "innermost" match location. If we fix up "w" into @@ -828,17 +832,13 @@ AutocompleteMatch HistoryURLProvider::HistoryMatchToACMatch( DCHECK(match.destination_url.is_valid()); size_t inline_autocomplete_offset = history_match.input_location + params->input.text().length(); + const net::FormatUrlTypes format_types = + (params->trim_http && !history_match.match_in_scheme) ? + net::kFormatUrlOmitAll : net::kFormatUrlOmitUsernamePassword; match.fill_into_edit = net::FormatUrl(info.url(), - match_type == WHAT_YOU_TYPED ? std::wstring() : params->languages, true, - UnescapeRule::SPACES, NULL, NULL, &inline_autocomplete_offset); - size_t offset = 0; - if (params->trim_http && !history_match.match_in_scheme) { - offset = TrimHttpPrefix(&match.fill_into_edit); - if (inline_autocomplete_offset != std::wstring::npos) { - DCHECK(inline_autocomplete_offset >= offset); - inline_autocomplete_offset -= offset; - } - } + match_type == WHAT_YOU_TYPED ? std::wstring() : params->languages, + format_types, UnescapeRule::SPACES, NULL, NULL, + &inline_autocomplete_offset); if (!params->input.prevent_inline_autocomplete()) match.inline_autocomplete_offset = inline_autocomplete_offset; DCHECK((match.inline_autocomplete_offset == std::wstring::npos) || @@ -846,15 +846,8 @@ AutocompleteMatch HistoryURLProvider::HistoryMatchToACMatch( size_t match_start = history_match.input_location; match.contents = net::FormatUrl(info.url(), - match_type == WHAT_YOU_TYPED ? std::wstring() : params->languages, true, - UnescapeRule::SPACES, NULL, NULL, &match_start); - if (offset) { - TrimHttpPrefix(&match.contents); - if (match_start != std::wstring::npos) { - DCHECK(match_start >= offset); - match_start -= offset; - } - } + match_type == WHAT_YOU_TYPED ? std::wstring() : params->languages, + format_types, UnescapeRule::SPACES, NULL, NULL, &match_start); if ((match_start != std::wstring::npos) && (inline_autocomplete_offset != std::wstring::npos) && (inline_autocomplete_offset != match_start)) { diff --git a/chrome/browser/autocomplete/search_provider.cc b/chrome/browser/autocomplete/search_provider.cc index 5833611..acba81e 100644 --- a/chrome/browser/autocomplete/search_provider.cc +++ b/chrome/browser/autocomplete/search_provider.cc @@ -98,8 +98,8 @@ void SearchProvider::Start(const AutocompleteInput& input, // User typed "?" alone. Give them a placeholder result indicating what // this syntax does. if (default_provider) { - AutocompleteMatch match(this, 0, false, - AutocompleteMatch::SEARCH_WHAT_YOU_TYPED); + AutocompleteMatch match; + match.provider = this; match.contents.assign(l10n_util::GetString(IDS_EMPTY_KEYWORD_VALUE)); match.contents_class.push_back( ACMatchClassification(0, ACMatchClassification::NONE)); @@ -737,10 +737,9 @@ AutocompleteMatch SearchProvider::NavigationToMatch( AutocompleteMatch match(this, relevance, false, AutocompleteMatch::NAVSUGGEST); match.destination_url = navigation.url; - match.contents = StringForURLDisplay(navigation.url, true); - if (!url_util::FindAndCompareScheme(WideToUTF8(input_text), - chrome::kHttpScheme, NULL)) - TrimHttpPrefix(&match.contents); + const bool trim_http = !url_util::FindAndCompareScheme( + WideToUTF8(input_text), chrome::kHttpScheme, NULL); + match.contents = StringForURLDisplay(navigation.url, true, trim_http); AutocompleteMatch::ClassifyMatchInString(input_text, match.contents, ACMatchClassification::URL, &match.contents_class); |