summaryrefslogtreecommitdiffstats
path: root/chrome/browser/autocomplete
diff options
context:
space:
mode:
authorshess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-23 20:01:00 +0000
committershess@chromium.org <shess@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-23 20:01:00 +0000
commit69c579e522c4493c15c93ebf33b28a35b1e7213b (patch)
tree5dde3cc78e0de04bb87613c09be12b47b80d8307 /chrome/browser/autocomplete
parent12f144239468f206dc82c3f3481fef477f636798 (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/autocomplete/autocomplete.cc72
-rw-r--r--chrome/browser/autocomplete/autocomplete.h39
-rw-r--r--chrome/browser/autocomplete/autocomplete_classifier.cc34
-rw-r--r--chrome/browser/autocomplete/autocomplete_classifier.h43
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit.cc134
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit.h55
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view.h7
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc199
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_gtk.h47
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_mac.h10
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_mac.mm101
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.cc82
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.h7
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_model.cc56
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_model.h20
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_view.h19
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_view_gtk.cc306
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_view_gtk.h35
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_view_mac.h4
-rw-r--r--chrome/browser/autocomplete/autocomplete_popup_view_mac.mm89
-rw-r--r--chrome/browser/autocomplete/history_contents_provider.cc6
-rw-r--r--chrome/browser/autocomplete/history_url_provider.cc35
-rw-r--r--chrome/browser/autocomplete/search_provider.cc11
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, &current_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);