summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjcivelli@chromium.org <jcivelli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 17:57:17 +0000
committerjcivelli@chromium.org <jcivelli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-29 17:57:17 +0000
commit265ccd99339c4a7bcdc3c163692f9344fe9e2ae5 (patch)
treec07c81496c8b66a1d9f55bc7d11ac842151b3e25
parent24e2b10503e5f54ce5b4beb96a6403c3a8e7e62f (diff)
downloadchromium_src-265ccd99339c4a7bcdc3c163692f9344fe9e2ae5.zip
chromium_src-265ccd99339c4a7bcdc3c163692f9344fe9e2ae5.tar.gz
chromium_src-265ccd99339c4a7bcdc3c163692f9344fe9e2ae5.tar.bz2
Relanding http://codereview.chromium.org/1746009/show
(fixed the ChromeOS build). The app launcher now uses the location bar (instead of the autocomplete edit), so it has "tab to search" and the icons on the left side, Also split location_bar_view.cc so that every inner-class gets its own .h and .cc file. BUG=None TEST=Make sure the location bar works as expected (tab to search, bookmark star, page actions...). Open the app launcher, make sure "tab to search" works as expected. Review URL: http://codereview.chromium.org/1792010 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@45957 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc2
-rw-r--r--chrome/browser/autocomplete/autocomplete_edit_view_win.cc2
-rw-r--r--chrome/browser/browser.cc2
-rw-r--r--chrome/browser/browser_focus_uitest.cc4
-rw-r--r--chrome/browser/views/app_launcher.cc216
-rw-r--r--chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc19
-rw-r--r--chrome/browser/views/bookmark_bar_view.cc2
-rw-r--r--chrome/browser/views/extensions/extension_installed_bubble.cc2
-rw-r--r--chrome/browser/views/go_button.cc2
-rw-r--r--chrome/browser/views/location_bar/click_handler.cc36
-rw-r--r--chrome/browser/views/location_bar/click_handler.h33
-rw-r--r--chrome/browser/views/location_bar/content_setting_image_view.cc93
-rw-r--r--chrome/browser/views/location_bar/content_setting_image_view.h59
-rw-r--r--chrome/browser/views/location_bar/ev_bubble_view.cc28
-rw-r--r--chrome/browser/views/location_bar/ev_bubble_view.h37
-rw-r--r--chrome/browser/views/location_bar/icon_label_bubble_view.cc72
-rw-r--r--chrome/browser/views/location_bar/icon_label_bubble_view.h54
-rw-r--r--chrome/browser/views/location_bar/keyword_hint_view.cc137
-rw-r--r--chrome/browser/views/location_bar/keyword_hint_view.h65
-rw-r--r--chrome/browser/views/location_bar/location_bar_view.cc942
-rw-r--r--chrome/browser/views/location_bar/location_bar_view.h338
-rw-r--r--chrome/browser/views/location_bar/location_icon_view.cc23
-rw-r--r--chrome/browser/views/location_bar/location_icon_view.h34
-rw-r--r--chrome/browser/views/location_bar/page_action_image_view.cc221
-rw-r--r--chrome/browser/views/location_bar/page_action_image_view.h109
-rw-r--r--chrome/browser/views/location_bar/page_action_with_badge_view.cc35
-rw-r--r--chrome/browser/views/location_bar/page_action_with_badge_view.h35
-rw-r--r--chrome/browser/views/location_bar/selected_keyword_view.cc84
-rw-r--r--chrome/browser/views/location_bar/selected_keyword_view.h61
-rw-r--r--chrome/browser/views/location_bar/star_view.cc58
-rw-r--r--chrome/browser/views/location_bar/star_view.h43
-rw-r--r--chrome/browser/views/location_bar_view.cc1668
-rw-r--r--chrome/browser/views/location_bar_view.h645
-rw-r--r--chrome/browser/views/toolbar_view.cc4
-rw-r--r--chrome/browser/views/toolbar_view.h3
-rw-r--r--chrome/chrome_browser.gypi46
36 files changed, 2723 insertions, 2491 deletions
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
index 452d1fe..4c506bc 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_gtk.cc
@@ -34,7 +34,7 @@
#if defined(TOOLKIT_VIEWS)
#include "chrome/browser/views/autocomplete/autocomplete_popup_contents_view.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "gfx/skia_utils_gtk.h"
#else
#include "chrome/browser/autocomplete/autocomplete_popup_view_gtk.h"
diff --git a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
index 153354c..a434fc3 100644
--- a/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
+++ b/chrome/browser/autocomplete/autocomplete_edit_view_win.cc
@@ -37,7 +37,7 @@
#include "chrome/browser/search_engines/template_url.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "chrome/common/gfx/utils.h"
#include "chrome/common/notification_service.h"
#include "googleurl/src/url_util.h"
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index a346eb9..ed1e38a 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -102,7 +102,7 @@
#include "chrome/browser/user_data_manager.h"
#include "chrome/browser/view_ids.h"
#include "chrome/browser/views/app_launcher.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#endif // OS_WIN
#if defined(OS_MACOSX)
diff --git a/chrome/browser/browser_focus_uitest.cc b/chrome/browser/browser_focus_uitest.cc
index d6a1d28..b5c9df23 100644
--- a/chrome/browser/browser_focus_uitest.cc
+++ b/chrome/browser/browser_focus_uitest.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.
@@ -25,7 +25,7 @@
#if defined(TOOLKIT_VIEWS)
#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "chrome/browser/views/tab_contents/tab_contents_container.h"
#endif
diff --git a/chrome/browser/views/app_launcher.cc b/chrome/browser/views/app_launcher.cc
index 240a926..9f05f48 100644
--- a/chrome/browser/views/app_launcher.cc
+++ b/chrome/browser/views/app_launcher.cc
@@ -12,8 +12,7 @@
#include "base/message_loop.h"
#include "base/string_util.h"
#include "base/task.h"
-#include "chrome/browser/autocomplete/autocomplete_edit.h"
-#include "chrome/browser/autocomplete/autocomplete_edit_view.h"
+#include "chrome/app/chrome_dll_resource.h"
#include "chrome/browser/browser.h"
#include "chrome/browser/browser_window.h"
#include "chrome/browser/profile.h"
@@ -22,16 +21,10 @@
#include "chrome/browser/views/dom_view.h"
#include "chrome/browser/views/info_bubble.h"
#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/toolbar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "chrome/common/url_constants.h"
#include "views/widget/root_view.h"
-#include "views/widget/widget.h"
-#if defined(OS_WIN)
-#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h"
-#elif defined(OS_LINUX)
-#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
-#endif
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/status/status_area_view.h"
#endif
@@ -69,146 +62,14 @@ static GURL GetMenuURL() {
} // namespace
-////////////////////////////////////////////////////////////////////////////////
-// NavigationBar
-//
-// A navigation bar that is shown in the app launcher in compact navigation bar
-// mode.
-
-class NavigationBar : public views::View,
- public AutocompleteEditController {
- public:
- explicit NavigationBar(AppLauncher* app_launcher)
- : app_launcher_(app_launcher),
- location_entry_view_(NULL) {
- SetFocusable(true);
- location_entry_view_ = new views::NativeViewHost;
- AddChildView(location_entry_view_);
- set_border(views::Border::CreateSolidBorder(kNavigationBarBorderThickness,
- SK_ColorGRAY));
-
- AddChildView(&popup_positioning_view_);
- popup_positioning_view_.SetVisible(false);
- popup_positioning_view_.set_parent_owned(false);
- }
-
- virtual ~NavigationBar() {
- if (location_entry_view_->native_view())
- location_entry_view_->Detach();
- }
-
- // views::View overrides.
- virtual void Focus() {
- location_entry_->SetFocus();
- location_entry_->SelectAll(true);
- }
-
- virtual void ViewHierarchyChanged(bool is_add,
- views::View* parent,
- views::View* child) {
- if (!is_add || child != this)
- return;
-
- DCHECK(!location_entry_.get());
-
- Browser* browser = app_launcher_->browser();
-#if defined (OS_WIN)
- gfx::Font font;
- font = font.DeriveFont(kAutocompleteEditFontDelta);
- AutocompleteEditViewWin* autocomplete_view =
- new AutocompleteEditViewWin(font, this, browser->toolbar_model(),
- this, GetWidget()->GetNativeView(),
- browser->profile(),
- browser->command_updater(), false,
- &popup_positioning_view_);
- location_entry_.reset(autocomplete_view);
- autocomplete_view->Update(NULL);
- // The Update call above sets the autocomplete text to the current one in
- // the location bar, make sure to clear it.
- autocomplete_view->SetUserText(std::wstring());
-#elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
- AutocompleteEditViewGtk* autocomplete_view =
- new AutocompleteEditViewGtk(this, browser->toolbar_model(),
- browser->profile(),
- browser->command_updater(), false,
- &popup_positioning_view_);
- autocomplete_view->Init();
- gtk_widget_show_all(autocomplete_view->GetNativeView());
- gtk_widget_hide(autocomplete_view->GetNativeView());
- location_entry_.reset(autocomplete_view);
-#else
- NOTIMPLEMENTED();
-#endif
- location_entry_view_->set_focus_view(this);
- location_entry_view_->Attach(location_entry_->GetNativeView());
- }
-
- virtual void Layout() {
- gfx::Rect bounds = GetLocalBounds(false);
- location_entry_view_->SetBounds(
- bounds.x() + kNavigationEntryXMargin + kNavigationEntryPadding,
- bounds.y() + kNavigationEntryYMargin,
- bounds.width() - 2 * (kNavigationEntryPadding +
- kNavigationEntryXMargin),
- bounds.height() - kNavigationEntryYMargin * 2);
-
- gfx::Rect popup_positioning_bounds(bounds);
- popup_positioning_bounds.Inset(0, -(kNavigationBarBorderThickness + 1));
- popup_positioning_view_.SetBounds(popup_positioning_bounds);
- }
-
- // AutocompleteController implementation.
- virtual void OnAutocompleteAccept(const GURL& url,
- WindowOpenDisposition disposition,
- PageTransition::Type transition,
- const GURL& alternate_nav_url) {
- app_launcher_->AddTabWithURL(url, transition);
- app_launcher_->Hide();
- }
- virtual void OnChanged() {}
- virtual void OnInputInProgress(bool in_progress) {}
- virtual void OnKillFocus() {}
- virtual void OnSetFocus() {
- views::FocusManager* focus_manager = GetFocusManager();
- if (!focus_manager) {
- NOTREACHED();
- return;
- }
- focus_manager->SetFocusedView(this);
- }
- virtual SkBitmap GetFavIcon() const {
- return SkBitmap();
- }
- virtual std::wstring GetTitle() const {
- return std::wstring();
- }
-
- private:
- AppLauncher* app_launcher_;
- views::NativeViewHost* location_entry_view_;
-#if defined(OS_WIN)
- scoped_ptr<AutocompleteEditViewWin> location_entry_;
-#elif defined(OS_LINUX) && defined(TOOLKIT_VIEWS)
- scoped_ptr<AutocompleteEditViewGtk> location_entry_;
-#else
- NOTIMPLEMENTED();
-#endif
-
- // This invisible view is provided to the popup in place of |this|, so the
- // popup can size itself against it using the same offsets it does with the
- // LocationBarView.
- views::View popup_positioning_view_;
-
- DISALLOW_COPY_AND_ASSIGN(NavigationBar);
-};
-
-////////////////////////////////////////////////////////////////////////////////
// InfoBubbleContentsView
//
// The view that contains the navigation bar and DOMUI.
// It is displayed in an info-bubble.
-class InfoBubbleContentsView : public views::View {
+class InfoBubbleContentsView : public views::View,
+ public LocationBarView::Delegate,
+ public CommandUpdater::CommandUpdaterDelegate {
public:
explicit InfoBubbleContentsView(AppLauncher* app_launcher);
~InfoBubbleContentsView();
@@ -224,23 +85,36 @@ class InfoBubbleContentsView : public views::View {
views::View* parent,
views::View* child);
+ // LocationBarView::Delegate implementation:
+ virtual TabContents* GetTabContents();
+ virtual void OnInputInProgress(bool in_progress) {}
+
+ // CommandUpdater::CommandUpdaterDelegate implementation:
+ virtual void ExecuteCommand(int id);
+
private:
// The application launcher displaying this info bubble.
AppLauncher* app_launcher_;
- // The navigation bar.
- NavigationBar* navigation_bar_;
+ // The location bar.
+ LocationBarView* location_bar_;
// The view containing the renderer view.
DOMView* dom_view_;
+ // CommandUpdater the location bar sends commands to.
+ CommandUpdater command_updater_;
+
DISALLOW_COPY_AND_ASSIGN(InfoBubbleContentsView);
};
InfoBubbleContentsView::InfoBubbleContentsView(AppLauncher* app_launcher)
: app_launcher_(app_launcher),
- navigation_bar_(NULL),
- dom_view_(NULL) {
+ location_bar_(NULL),
+ dom_view_(NULL),
+ ALLOW_THIS_IN_INITIALIZER_LIST(command_updater_(this)) {
+ // Allow the location bar to open URLs.
+ command_updater_.UpdateCommandEnabled(IDC_OPEN_CURRENT_URL, true);
DCHECK(app_launcher);
}
@@ -248,7 +122,7 @@ InfoBubbleContentsView::~InfoBubbleContentsView() {
}
void InfoBubbleContentsView::BubbleShown() {
- navigation_bar_->RequestFocus();
+ location_bar_->RequestFocus();
}
void InfoBubbleContentsView::ViewHierarchyChanged(
@@ -266,8 +140,21 @@ void InfoBubbleContentsView::ViewHierarchyChanged(
dom_view_->tab_contents()->set_delegate(app_launcher_);
dom_view_->LoadURL(GetMenuURL());
- navigation_bar_ = new NavigationBar(app_launcher_);
- AddChildView(navigation_bar_);
+ Browser* browser = app_launcher_->browser();
+ location_bar_ = new LocationBarView(browser->profile(),
+ &command_updater_,
+ browser->toolbar_model(),
+ this,
+ LocationBarView::APP_LAUNCHER);
+
+ location_bar_->set_border(
+ views::Border::CreateSolidBorder(1, SkColorSetRGB(205, 201, 201)));
+ AddChildView(location_bar_);
+ location_bar_->Init();
+}
+
+TabContents* InfoBubbleContentsView::GetTabContents() {
+ return app_launcher_->browser()->GetSelectedTabContents();
}
gfx::Size InfoBubbleContentsView::GetPreferredSize() {
@@ -280,24 +167,24 @@ void InfoBubbleContentsView::Layout() {
return;
gfx::Rect bounds = GetLocalBounds(false);
- int navigation_bar_height =
- kNavigationBarHeight + kNavigationEntryYMargin * 2;
- const views::Border* border = navigation_bar_->border();
- if (border) {
- gfx::Insets insets;
- border->GetInsets(&insets);
- navigation_bar_height += insets.height();
- }
- navigation_bar_->SetBounds(bounds.x(), bounds.y(),
- bounds.width(), navigation_bar_height);
- int render_y = navigation_bar_->bounds().bottom() +
- kNavigationBarBottomPadding;
+
+ location_bar_->SetBounds(bounds.x(), bounds.y(), bounds.width(),
+ location_bar_->GetPreferredSize().height());
+ int render_y = location_bar_->bounds().bottom() + kNavigationBarBottomPadding;
gfx::Size dom_view_size =
gfx::Size(width(), std::max(0, bounds.height() - render_y + bounds.y()));
dom_view_->SetBounds(bounds.x(), render_y,
dom_view_size.width(), dom_view_size.height());
}
+void InfoBubbleContentsView::ExecuteCommand(int id) {
+ // The user navigated by typing or selecting an entry in the location bar.
+ DCHECK_EQ(IDC_OPEN_CURRENT_URL, id);
+ GURL url(WideToUTF8(location_bar_->GetInputString()));
+ app_launcher_->AddTabWithURL(url, location_bar_->GetPageTransition());
+ app_launcher_->Hide();
+}
+
////////////////////////////////////////////////////////////////////////////////
// AppLauncher
@@ -358,7 +245,8 @@ void AppLauncher::OpenURLFromTab(TabContents* source,
PageTransition::Type transition) {
// TODO(jcivelli): we should call Browser::OpenApplicationTab(), we would need
// to access the app for this URL.
- AddTabWithURL(url, PageTransition::LINK);
+ // The user clicked an item in the app launcher contents.
+ AddTabWithURL(url, PageTransition::AUTO_BOOKMARK);
Hide();
}
diff --git a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc
index de0464e..4f71b75 100644
--- a/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc
+++ b/chrome/browser/views/autocomplete/autocomplete_popup_contents_view.cc
@@ -582,9 +582,26 @@ void AutocompletePopupContentsView::UpdatePopupAppearance() {
// Calculate desired bounds.
gfx::Rect location_bar_bounds(location_bar_->bounds());
gfx::Point location;
+ const views::Border* border = location_bar_->border();
+ int location_bar_height = location_bar_bounds.height();
+ if (border) {
+ // Adjust for the border so that the bubble and location bar borders are
+ // aligned.
+ gfx::Insets insets;
+ border->GetInsets(&insets);
+ location_bar_bounds.Inset(insets.left(), 0, insets.right(), 0);
+ location.Offset(insets.left(), 0);
+ } else {
+ // The normal location bar is drawn using a background graphic that includes
+ // the border. The graphic is actually one pixel larger above and below the
+ // dark of the border, so that it can draw a faint highlight.
+ // So, in order to make the popup butt up against the dark border, it has to
+ // overlap the location bar by one pixel.
+ location_bar_height -= 1;
+ }
views::View::ConvertPointToScreen(location_bar_, &location);
location_bar_bounds.set_origin(location);
- location_bar_bounds.set_height(location_bar_bounds.height() - 1);
+ location_bar_bounds.set_height(location_bar_height);
gfx::Rect new_target_bounds(bubble_border_->GetBounds(location_bar_bounds,
gfx::Size(location_bar_bounds.width(), total_child_height)));
diff --git a/chrome/browser/views/bookmark_bar_view.cc b/chrome/browser/views/bookmark_bar_view.cc
index 8c2b497..0cf4a71 100644
--- a/chrome/browser/views/bookmark_bar_view.cc
+++ b/chrome/browser/views/bookmark_bar_view.cc
@@ -32,7 +32,7 @@
#include "chrome/browser/views/bookmark_context_menu.h"
#include "chrome/browser/views/event_utils.h"
#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/page_transition_types.h"
#include "chrome/common/pref_names.h"
diff --git a/chrome/browser/views/extensions/extension_installed_bubble.cc b/chrome/browser/views/extensions/extension_installed_bubble.cc
index 61d4768..b02b56d 100644
--- a/chrome/browser/views/extensions/extension_installed_bubble.cc
+++ b/chrome/browser/views/extensions/extension_installed_bubble.cc
@@ -13,7 +13,7 @@
#include "chrome/browser/shell_integration.h"
#include "chrome/browser/views/browser_actions_container.h"
#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "chrome/browser/views/toolbar_view.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/common/extensions/extension.h"
diff --git a/chrome/browser/views/go_button.cc b/chrome/browser/views/go_button.cc
index 05fc1c4..f674c72 100644
--- a/chrome/browser/views/go_button.cc
+++ b/chrome/browser/views/go_button.cc
@@ -13,7 +13,7 @@
#include "chrome/browser/profile.h"
#include "chrome/browser/search_engines/template_url_model.h"
#include "chrome/browser/views/event_utils.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "grit/generated_resources.h"
////////////////////////////////////////////////////////////////////////////////
diff --git a/chrome/browser/views/location_bar/click_handler.cc b/chrome/browser/views/location_bar/click_handler.cc
new file mode 100644
index 0000000..e9c414c
--- /dev/null
+++ b/chrome/browser/views/location_bar/click_handler.cc
@@ -0,0 +1,36 @@
+// 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/views/location_bar/click_handler.h"
+
+#include "chrome/browser/tab_contents/navigation_controller.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
+#include "views/view.h"
+
+ClickHandler::ClickHandler(const views::View* owner,
+ const LocationBarView* location_bar)
+ : owner_(owner),
+ location_bar_(location_bar) {
+}
+
+void ClickHandler::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ if (canceled || !owner_->HitTest(event.location()))
+ return;
+
+ // Do not show page info if the user has been editing the location
+ // bar, or the location bar is at the NTP.
+ if (location_bar_->location_entry()->IsEditingOrEmpty())
+ return;
+
+ TabContents* tab = location_bar_->GetTabContents();
+ NavigationEntry* nav_entry = tab->controller().GetActiveEntry();
+ if (!nav_entry) {
+ NOTREACHED();
+ return;
+ }
+ tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true);
+}
+
diff --git a/chrome/browser/views/location_bar/click_handler.h b/chrome/browser/views/location_bar/click_handler.h
new file mode 100644
index 0000000..e477e94
--- /dev/null
+++ b/chrome/browser/views/location_bar/click_handler.h
@@ -0,0 +1,33 @@
+// 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_VIEWS_LOCATION_BAR_CLICK_HANDLER_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_CLICK_HANDLER_H_
+
+#include "base/basictypes.h"
+
+class LocationBarView;
+
+namespace views {
+class MouseEvent;
+class View;
+}
+
+// This helper class is kept as a member by classes that need to show the Page
+// Info dialog on click, to encapsulate that logic in one place.
+class ClickHandler {
+ public:
+ ClickHandler(const views::View* owner, const LocationBarView* location_bar);
+
+ void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+
+ private:
+ const views::View* owner_;
+ const LocationBarView* location_bar_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ClickHandler);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_CLICK_HANDLER_H_
+
diff --git a/chrome/browser/views/location_bar/content_setting_image_view.cc b/chrome/browser/views/location_bar/content_setting_image_view.cc
new file mode 100644
index 0000000..03b30eb
--- /dev/null
+++ b/chrome/browser/views/location_bar/content_setting_image_view.cc
@@ -0,0 +1,93 @@
+// 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/views/location_bar/content_setting_image_view.h"
+
+#include "app/resource_bundle.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/content_setting_bubble_model.h"
+#include "chrome/browser/content_setting_image_model.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/views/content_blocked_bubble_contents.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
+
+ContentSettingImageView::ContentSettingImageView(
+ ContentSettingsType content_type,
+ const LocationBarView* parent,
+ Profile* profile)
+ : content_setting_image_model_(
+ ContentSettingImageModel::CreateContentSettingImageModel(
+ content_type)),
+ parent_(parent),
+ profile_(profile),
+ info_bubble_(NULL) {
+}
+
+ContentSettingImageView::~ContentSettingImageView() {
+ if (info_bubble_)
+ info_bubble_->Close();
+}
+
+void ContentSettingImageView::UpdateFromTabContents(
+ const TabContents* tab_contents) {
+ int old_icon = content_setting_image_model_->get_icon();
+ content_setting_image_model_->UpdateFromTabContents(tab_contents);
+ if (!content_setting_image_model_->is_visible()) {
+ SetVisible(false);
+ return;
+ }
+ if (old_icon != content_setting_image_model_->get_icon()) {
+ SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ content_setting_image_model_->get_icon()));
+ }
+ SetTooltipText(UTF8ToWide(content_setting_image_model_->get_tooltip()));
+ SetVisible(true);
+}
+
+bool ContentSettingImageView::OnMousePressed(const views::MouseEvent& event) {
+ // We want to show the bubble on mouse release; that is the standard behavior
+ // for buttons.
+ return true;
+}
+
+void ContentSettingImageView::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ if (canceled || !HitTest(event.location()))
+ return;
+
+ TabContents* tab_contents = parent_->GetTabContents();
+ if (!tab_contents)
+ return;
+
+ gfx::Rect screen_bounds(GetImageBounds());
+ gfx::Point origin(screen_bounds.origin());
+ views::View::ConvertPointToScreen(this, &origin);
+ screen_bounds.set_origin(origin);
+ ContentSettingBubbleContents* bubble_contents =
+ new ContentSettingBubbleContents(
+ ContentSettingBubbleModel::CreateContentSettingBubbleModel(
+ tab_contents, profile_,
+ content_setting_image_model_->get_content_settings_type()),
+ profile_, tab_contents);
+ DCHECK(!info_bubble_);
+ info_bubble_ =
+ InfoBubble::Show(GetWindow(), screen_bounds, bubble_contents, this);
+ bubble_contents->set_info_bubble(info_bubble_);
+}
+
+void ContentSettingImageView::VisibilityChanged(View* starting_from,
+ bool is_visible) {
+ if (!is_visible && info_bubble_)
+ info_bubble_->Close();
+}
+
+void ContentSettingImageView::InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape) {
+ info_bubble_ = NULL;
+}
+
+bool ContentSettingImageView::CloseOnEscape() {
+ return true;
+}
+
diff --git a/chrome/browser/views/location_bar/content_setting_image_view.h b/chrome/browser/views/location_bar/content_setting_image_view.h
new file mode 100644
index 0000000..382d8a11
--- /dev/null
+++ b/chrome/browser/views/location_bar/content_setting_image_view.h
@@ -0,0 +1,59 @@
+// 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_VIEWS_LOCATION_BAR_CONTENT_SETTING_IMAGE_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_CONTENT_SETTING_IMAGE_VIEW_H_
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/views/info_bubble.h"
+#include "chrome/common/content_settings_types.h"
+#include "views/controls/image_view.h"
+
+class ContentSettingImageModel;
+class InfoBubble;
+class LocationBarView;
+class Profile;
+class TabContents;
+
+namespace views {
+class MouseEvent;
+}
+
+class ContentSettingImageView : public views::ImageView,
+ public InfoBubbleDelegate {
+ public:
+ ContentSettingImageView(ContentSettingsType content_type,
+ const LocationBarView* parent,
+ Profile* profile);
+ virtual ~ContentSettingImageView();
+
+ void set_profile(Profile* profile) { profile_ = profile; }
+ void UpdateFromTabContents(const TabContents* tab_contents);
+
+ private:
+ // views::ImageView overrides:
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+ virtual void VisibilityChanged(View* starting_from, bool is_visible);
+
+ // InfoBubbleDelegate overrides:
+ virtual void InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape);
+ virtual bool CloseOnEscape();
+
+ scoped_ptr<ContentSettingImageModel> content_setting_image_model_;
+
+ // The owning LocationBarView.
+ const LocationBarView* parent_;
+
+ // The currently active profile.
+ Profile* profile_;
+
+ // The currently shown info bubble if any.
+ InfoBubble* info_bubble_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(ContentSettingImageView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_CONTENT_SETTING_IMAGE_VIEW_H_
diff --git a/chrome/browser/views/location_bar/ev_bubble_view.cc b/chrome/browser/views/location_bar/ev_bubble_view.cc
new file mode 100644
index 0000000..882bfd0
--- /dev/null
+++ b/chrome/browser/views/location_bar/ev_bubble_view.cc
@@ -0,0 +1,28 @@
+// 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/views/location_bar/ev_bubble_view.h"
+
+EVBubbleView::EVBubbleView(const int background_images[],
+ int contained_image,
+ const SkColor& color,
+ const LocationBarView* location_bar)
+ : IconLabelBubbleView(background_images, contained_image, color),
+ ALLOW_THIS_IN_INITIALIZER_LIST(click_handler_(this, location_bar)) {
+}
+
+EVBubbleView::~EVBubbleView() {
+}
+
+bool EVBubbleView::OnMousePressed(const views::MouseEvent& event) {
+ // We want to show the dialog on mouse release; that is the standard behavior
+ // for buttons.
+ return true;
+}
+
+void EVBubbleView::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ click_handler_.OnMouseReleased(event, canceled);
+}
+
diff --git a/chrome/browser/views/location_bar/ev_bubble_view.h b/chrome/browser/views/location_bar/ev_bubble_view.h
new file mode 100644
index 0000000..4b92944
--- /dev/null
+++ b/chrome/browser/views/location_bar/ev_bubble_view.h
@@ -0,0 +1,37 @@
+// 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_VIEWS_LOCATION_BAR_EV_BUBBLE_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_EV_BUBBLE_VIEW_H_
+
+#include "chrome/browser/views/location_bar/click_handler.h"
+#include "chrome/browser/views/location_bar/icon_label_bubble_view.h"
+
+class LocationBarView;
+
+namespace views {
+class MouseEvent;
+}
+
+// EVBubbleView displays the EV Bubble in the LocationBarView.
+class EVBubbleView : public IconLabelBubbleView {
+ public:
+ EVBubbleView(const int background_images[],
+ int contained_image,
+ const SkColor& color,
+ const LocationBarView* location_bar);
+ virtual ~EVBubbleView();
+
+ // Overridden from view.
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+
+ private:
+ ClickHandler click_handler_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(EVBubbleView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_EV_BUBBLE_VIEW_H_
+
diff --git a/chrome/browser/views/location_bar/icon_label_bubble_view.cc b/chrome/browser/views/location_bar/icon_label_bubble_view.cc
new file mode 100644
index 0000000..c40acff
--- /dev/null
+++ b/chrome/browser/views/location_bar/icon_label_bubble_view.cc
@@ -0,0 +1,72 @@
+// 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/views/location_bar/icon_label_bubble_view.h"
+
+#include "app/resource_bundle.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
+#include "gfx/canvas.h"
+#include "views/controls/image_view.h"
+#include "views/controls/label.h"
+
+// Amount to offset the image.
+static const int kImageOffset = 1;
+
+// Amount to offset the label from the image.
+static const int kLabelOffset = 3;
+
+// Amount of padding after the label.
+static const int kLabelPadding = 4;
+
+IconLabelBubbleView::IconLabelBubbleView(const int background_images[],
+ int contained_image,
+ const SkColor& color)
+ : background_painter_(background_images) {
+ image_ = new views::ImageView();
+ AddChildView(image_);
+ image_->SetImage(
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(contained_image));
+ label_ = new views::Label();
+ AddChildView(label_);
+ label_->SetColor(color);
+}
+
+IconLabelBubbleView::~IconLabelBubbleView() {
+}
+
+void IconLabelBubbleView::SetFont(const gfx::Font& font) {
+ label_->SetFont(font);
+}
+
+void IconLabelBubbleView::SetLabel(const std::wstring& label) {
+ label_->SetText(label);
+}
+
+void IconLabelBubbleView::Paint(gfx::Canvas* canvas) {
+ int y_offset = (GetParent()->height() - height()) / 2;
+ canvas->TranslateInt(0, y_offset);
+ background_painter_.Paint(width(), height(), canvas);
+ canvas->TranslateInt(0, -y_offset);
+}
+
+gfx::Size IconLabelBubbleView::GetPreferredSize() {
+ gfx::Size size(GetNonLabelSize());
+ size.Enlarge(label_->GetPreferredSize().width(), 0);
+ return size;
+}
+
+void IconLabelBubbleView::Layout() {
+ image_->SetBounds(kImageOffset, 0, image_->GetPreferredSize().width(),
+ height());
+ gfx::Size label_size(label_->GetPreferredSize());
+ label_->SetBounds(image_->x() + image_->width() + kLabelOffset,
+ (height() - label_size.height()) / 2, label_size.width(),
+ label_size.height());
+}
+
+gfx::Size IconLabelBubbleView::GetNonLabelSize() {
+ return gfx::Size(kImageOffset + image_->GetPreferredSize().width() +
+ kLabelOffset + kLabelPadding, background_painter_.height());
+}
+
diff --git a/chrome/browser/views/location_bar/icon_label_bubble_view.h b/chrome/browser/views/location_bar/icon_label_bubble_view.h
new file mode 100644
index 0000000..b8b9485
--- /dev/null
+++ b/chrome/browser/views/location_bar/icon_label_bubble_view.h
@@ -0,0 +1,54 @@
+// 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_VIEWS_LOCATION_BAR_ICON_LABEL_BUBBLE_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_ICON_LABEL_BUBBLE_VIEW_H_
+
+#include <string>
+
+#include "gfx/size.h"
+#include "views/painter.h"
+#include "views/view.h"
+
+namespace gfx {
+class Canvas;
+class Font;
+}
+namespace views {
+class ImageView;
+class Label;
+}
+
+// View used to draw a bubble to the left of the address, containing an icon and
+// a label. We use this as a base for the classes that handle the EV bubble and
+// tab-to-search UI.
+class IconLabelBubbleView : public views::View {
+ public:
+ IconLabelBubbleView(const int background_images[],
+ int contained_image,
+ const SkColor& color);
+ virtual ~IconLabelBubbleView();
+
+ void SetFont(const gfx::Font& font);
+ void SetLabel(const std::wstring& label);
+
+ virtual void Paint(gfx::Canvas* canvas);
+ virtual gfx::Size GetPreferredSize();
+ virtual void Layout();
+
+ protected:
+ gfx::Size GetNonLabelSize();
+
+ private:
+ // For painting the background.
+ views::HorizontalPainter background_painter_;
+
+ // The contents of the bubble.
+ views::ImageView* image_;
+ views::Label* label_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(IconLabelBubbleView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_ICON_LABEL_BUBBLE_VIEW_H_
diff --git a/chrome/browser/views/location_bar/keyword_hint_view.cc b/chrome/browser/views/location_bar/keyword_hint_view.cc
new file mode 100644
index 0000000..9f35e3b
--- /dev/null
+++ b/chrome/browser/views/location_bar/keyword_hint_view.cc
@@ -0,0 +1,137 @@
+// 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/views/location_bar/keyword_hint_view.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "base/logging.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/search_engines/template_url_model.h"
+#include "gfx/canvas.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+#include "views/controls/label.h"
+#include "third_party/skia/include/core/SkBitmap.h"
+
+// Amount of space to offset the tab image from the top of the view by.
+static const int kTabImageYOffset = 4;
+
+// The tab key image.
+static const SkBitmap* kTabButtonBitmap = NULL;
+
+KeywordHintView::KeywordHintView(Profile* profile) : profile_(profile) {
+ leading_label_ = new views::Label();
+ trailing_label_ = new views::Label();
+ AddChildView(leading_label_);
+ AddChildView(trailing_label_);
+
+ if (!kTabButtonBitmap) {
+ kTabButtonBitmap = ResourceBundle::GetSharedInstance().
+ GetBitmapNamed(IDR_LOCATION_BAR_KEYWORD_HINT_TAB);
+ }
+}
+
+KeywordHintView::~KeywordHintView() {
+}
+
+void KeywordHintView::SetFont(const gfx::Font& font) {
+ leading_label_->SetFont(font);
+ trailing_label_->SetFont(font);
+}
+
+void KeywordHintView::SetColor(const SkColor& color) {
+ leading_label_->SetColor(color);
+ trailing_label_->SetColor(color);
+}
+
+void KeywordHintView::SetKeyword(const std::wstring& keyword) {
+ keyword_ = keyword;
+ if (keyword_.empty())
+ return;
+ DCHECK(profile_);
+ if (!profile_->GetTemplateURLModel())
+ return;
+
+ std::vector<size_t> content_param_offsets;
+ const std::wstring keyword_hint(l10n_util::GetStringF(
+ IDS_OMNIBOX_KEYWORD_HINT, std::wstring(),
+ GetKeywordName(profile_, keyword), &content_param_offsets));
+ if (content_param_offsets.size() == 2) {
+ leading_label_->SetText(
+ keyword_hint.substr(0, content_param_offsets.front()));
+ trailing_label_->SetText(
+ keyword_hint.substr(content_param_offsets.front()));
+ } else {
+ // See comments on an identical NOTREACHED() in search_provider.cc.
+ NOTREACHED();
+ }
+}
+
+void KeywordHintView::Paint(gfx::Canvas* canvas) {
+ int image_x = leading_label_->IsVisible() ? leading_label_->width() : 0;
+
+ // Since we paint the button image directly on the canvas (instead of using a
+ // child view), we must mirror the button's position manually if the locale
+ // is right-to-left.
+ gfx::Rect tab_button_bounds(image_x,
+ kTabImageYOffset,
+ kTabButtonBitmap->width(),
+ kTabButtonBitmap->height());
+ tab_button_bounds.set_x(MirroredLeftPointForRect(tab_button_bounds));
+ canvas->DrawBitmapInt(*kTabButtonBitmap,
+ tab_button_bounds.x(),
+ tab_button_bounds.y());
+}
+
+gfx::Size KeywordHintView::GetPreferredSize() {
+ // TODO(sky): currently height doesn't matter, once baseline support is
+ // added this should check baselines.
+ gfx::Size prefsize = leading_label_->GetPreferredSize();
+ int width = prefsize.width();
+ width += kTabButtonBitmap->width();
+ prefsize = trailing_label_->GetPreferredSize();
+ width += prefsize.width();
+ return gfx::Size(width, prefsize.height());
+}
+
+gfx::Size KeywordHintView::GetMinimumSize() {
+ // TODO(sky): currently height doesn't matter, once baseline support is
+ // added this should check baselines.
+ return gfx::Size(kTabButtonBitmap->width(), 0);
+}
+
+void KeywordHintView::Layout() {
+ // TODO(sky): baseline layout.
+ bool show_labels = (width() != kTabButtonBitmap->width());
+
+ leading_label_->SetVisible(show_labels);
+ trailing_label_->SetVisible(show_labels);
+ int x = 0;
+ gfx::Size pref;
+
+ if (show_labels) {
+ pref = leading_label_->GetPreferredSize();
+ leading_label_->SetBounds(x, 0, pref.width(), height());
+
+ x += pref.width() + kTabButtonBitmap->width();
+ pref = trailing_label_->GetPreferredSize();
+ trailing_label_->SetBounds(x, 0, pref.width(), height());
+ }
+}
+
+
+// static
+std::wstring KeywordHintView::GetKeywordName(Profile* profile,
+ const std::wstring& keyword) {
+ // Make sure the TemplateURL still exists.
+ // TODO(sky): Once LocationBarView adds a listener to the TemplateURLModel
+ // to track changes to the model, this should become a DCHECK.
+ const TemplateURL* template_url =
+ profile->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword);
+ if (template_url)
+ return template_url->AdjustedShortNameForLocaleDirection();
+ return std::wstring();
+}
diff --git a/chrome/browser/views/location_bar/keyword_hint_view.h b/chrome/browser/views/location_bar/keyword_hint_view.h
new file mode 100644
index 0000000..500216c
--- /dev/null
+++ b/chrome/browser/views/location_bar/keyword_hint_view.h
@@ -0,0 +1,65 @@
+// 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_VIEWS_LOCATION_BAR_KEYWORD_HINT_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_KEYWORD_HINT_VIEW_H_
+
+#include <string>
+
+#include "gfx/size.h"
+#include "views/view.h"
+
+namespace gfx {
+class Font;
+}
+class Profile;
+namespace views {
+class Label;
+}
+
+// KeywordHintView is used by the location bar view to display a hint to the
+// user when the selected url has a corresponding keyword.
+//
+// Internally KeywordHintView uses two labels to render the text, and draws
+// the tab image itself.
+//
+// NOTE: This should really be called LocationBarKeywordHintView, but I
+// couldn't bring myself to use such a long name.
+class KeywordHintView : public views::View {
+ public:
+ explicit KeywordHintView(Profile* profile);
+ virtual ~KeywordHintView();
+
+ void SetFont(const gfx::Font& font);
+
+ void SetColor(const SkColor& color);
+
+ void SetKeyword(const std::wstring& keyword);
+ std::wstring keyword() const { return keyword_; }
+
+ virtual void Paint(gfx::Canvas* canvas);
+ virtual gfx::Size GetPreferredSize();
+ // The minimum size is just big enough to show the tab.
+ virtual gfx::Size GetMinimumSize();
+ virtual void Layout();
+
+ void set_profile(Profile* profile) { profile_ = profile; }
+
+ // Returns the short name for a keyword.
+ static std::wstring GetKeywordName(Profile* profile,
+ const std::wstring& keyword);
+
+ private:
+ views::Label* leading_label_;
+ views::Label* trailing_label_;
+
+ // The keyword.
+ std::wstring keyword_;
+
+ Profile* profile_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(KeywordHintView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_KEYWORD_HINT_VIEW_H_
diff --git a/chrome/browser/views/location_bar/location_bar_view.cc b/chrome/browser/views/location_bar/location_bar_view.cc
new file mode 100644
index 0000000..16ea52f
--- /dev/null
+++ b/chrome/browser/views/location_bar/location_bar_view.cc
@@ -0,0 +1,942 @@
+// 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/views/location_bar/location_bar_view.h"
+
+#if defined(OS_LINUX)
+#include <gtk/gtk.h>
+#endif
+
+#include "app/drag_drop_types.h"
+#include "app/resource_bundle.h"
+#include "app/theme_provider.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/alternate_nav_url_fetcher.h"
+#include "chrome/browser/extensions/extension_browser_event_router.h"
+#include "chrome/browser/view_ids.h"
+#include "chrome/browser/views/browser_dialogs.h"
+#include "chrome/browser/views/location_bar/content_setting_image_view.h"
+#include "chrome/browser/views/location_bar/ev_bubble_view.h"
+#include "chrome/browser/views/location_bar/keyword_hint_view.h"
+#include "chrome/browser/views/location_bar/location_icon_view.h"
+#include "chrome/browser/views/location_bar/page_action_image_view.h"
+#include "chrome/browser/views/location_bar/page_action_with_badge_view.h"
+#include "chrome/browser/views/location_bar/selected_keyword_view.h"
+#include "chrome/browser/views/location_bar/star_view.h"
+#include "gfx/canvas.h"
+#include "gfx/color_utils.h"
+#include "grit/theme_resources.h"
+#include "views/drag_utils.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/views/first_run_bubble.h"
+#endif
+
+using views::View;
+
+// static
+const int LocationBarView::kVertMargin = 2;
+
+// Padding between items in the location bar.
+static const int kViewPadding = 3;
+
+// Padding before the start of a bubble.
+static const int kBubblePadding = kViewPadding - 1;
+
+// Padding between the location icon and the edit, if they're adjacent.
+static const int kLocationIconEditPadding = kViewPadding - 1;
+
+static const int kEVBubbleBackgroundImages[] = {
+ IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_L,
+ IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_C,
+ IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_R,
+};
+
+static const int kSelectedKeywordBackgroundImages[] = {
+ IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_L,
+ IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_C,
+ IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_R,
+};
+
+static const SkBitmap* kBackground = NULL;
+
+static const SkBitmap* kPopupBackground = NULL;
+
+// LocationBarView -----------------------------------------------------------
+
+LocationBarView::LocationBarView(Profile* profile,
+ CommandUpdater* command_updater,
+ ToolbarModel* model,
+ Delegate* delegate,
+ Mode mode)
+ : profile_(profile),
+ command_updater_(command_updater),
+ model_(model),
+ delegate_(delegate),
+ disposition_(CURRENT_TAB),
+ location_icon_view_(NULL),
+ ev_bubble_view_(NULL),
+ location_entry_view_(NULL),
+ selected_keyword_view_(NULL),
+ keyword_hint_view_(NULL),
+ star_view_(NULL),
+ mode_(mode),
+ ALLOW_THIS_IN_INITIALIZER_LIST(first_run_bubble_(this)) {
+ DCHECK(profile_);
+ SetID(VIEW_ID_LOCATION_BAR);
+ SetFocusable(true);
+
+ if (!kBackground) {
+ ResourceBundle &rb = ResourceBundle::GetSharedInstance();
+ kBackground = rb.GetBitmapNamed(IDR_LOCATIONBG);
+ kPopupBackground = rb.GetBitmapNamed(IDR_LOCATIONBG_POPUPMODE_CENTER);
+ }
+}
+
+LocationBarView::~LocationBarView() {
+}
+
+void LocationBarView::Init() {
+ if (mode_ == POPUP) {
+ font_ = ResourceBundle::GetSharedInstance().GetFont(
+ ResourceBundle::BaseFont);
+ } else {
+ // Use a larger version of the system font.
+ font_ = font_.DeriveFont(3);
+ }
+
+ location_icon_view_ = new LocationIconView(this);
+ AddChildView(location_icon_view_);
+ location_icon_view_->SetVisible(true);
+ location_icon_view_->SetDragController(this);
+
+ ev_bubble_view_ =
+ new EVBubbleView(kEVBubbleBackgroundImages, IDR_OMNIBOX_HTTPS_VALID,
+ GetColor(ToolbarModel::EV_SECURE, SECURITY_TEXT), this);
+ AddChildView(ev_bubble_view_);
+ ev_bubble_view_->SetVisible(false);
+ ev_bubble_view_->SetDragController(this);
+
+ // URL edit field.
+ // View container for URL edit field.
+#if defined(OS_WIN)
+ location_entry_.reset(new AutocompleteEditViewWin(font_, this, model_, this,
+ GetWidget()->GetNativeView(), profile_, command_updater_,
+ mode_ == POPUP, this));
+#else
+ location_entry_.reset(new AutocompleteEditViewGtk(this, model_, profile_,
+ command_updater_, mode_ == POPUP, this));
+ location_entry_->Init();
+ // Make all the children of the widget visible. NOTE: this won't display
+ // anything, it just toggles the visible flag.
+ gtk_widget_show_all(location_entry_->GetNativeView());
+ // Hide the widget. NativeViewHostGtk will make it visible again as
+ // necessary.
+ gtk_widget_hide(location_entry_->GetNativeView());
+#endif
+ location_entry_view_ = new views::NativeViewHost;
+ location_entry_view_->SetID(VIEW_ID_AUTOCOMPLETE);
+ AddChildView(location_entry_view_);
+ location_entry_view_->set_focus_view(this);
+ location_entry_view_->Attach(location_entry_->GetNativeView());
+
+ selected_keyword_view_ =
+ new SelectedKeywordView(kSelectedKeywordBackgroundImages,
+ IDR_OMNIBOX_SEARCH, SK_ColorBLACK, profile_),
+ AddChildView(selected_keyword_view_);
+ selected_keyword_view_->SetFont(font_);
+ selected_keyword_view_->SetVisible(false);
+
+ SkColor dimmed_text = GetColor(ToolbarModel::NONE, DEEMPHASIZED_TEXT);
+
+ keyword_hint_view_ = new KeywordHintView(profile_);
+ AddChildView(keyword_hint_view_);
+ keyword_hint_view_->SetVisible(false);
+ keyword_hint_view_->SetFont(font_);
+ keyword_hint_view_->SetColor(dimmed_text);
+
+ for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
+ ContentSettingImageView* content_blocked_view = new ContentSettingImageView(
+ static_cast<ContentSettingsType>(i), this, profile_);
+ content_setting_views_.push_back(content_blocked_view);
+ AddChildView(content_blocked_view);
+ content_blocked_view->SetVisible(false);
+ }
+
+ // The star is not visible in popups and in the app launcher.
+ if (mode_ == NORMAL) {
+ star_view_ = new StarView(command_updater_);
+ AddChildView(star_view_);
+ star_view_->SetVisible(true);
+ }
+
+ // Notify us when any ancestor is resized. In this case we want to tell the
+ // AutocompleteEditView to close its popup.
+ SetNotifyWhenVisibleBoundsInRootChanges(true);
+
+ // Initialize the location entry. We do this to avoid a black flash which is
+ // visible when the location entry has just been initialized.
+ Update(NULL);
+
+ OnChanged();
+}
+
+bool LocationBarView::IsInitialized() const {
+ return location_entry_view_ != NULL;
+}
+
+// static
+SkColor LocationBarView::GetColor(ToolbarModel::SecurityLevel security_level,
+ ColorKind kind) {
+ switch (kind) {
+#if defined(OS_WIN)
+ case BACKGROUND: return color_utils::GetSysSkColor(COLOR_WINDOW);
+ case TEXT: return color_utils::GetSysSkColor(COLOR_WINDOWTEXT);
+ case SELECTED_TEXT: return color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT);
+#else
+ // TODO(beng): source from theme provider.
+ case BACKGROUND: return SK_ColorWHITE;
+ case TEXT: return SK_ColorBLACK;
+ case SELECTED_TEXT: return SK_ColorWHITE;
+#endif
+
+ case DEEMPHASIZED_TEXT:
+ return color_utils::AlphaBlend(GetColor(security_level, TEXT),
+ GetColor(security_level, BACKGROUND), 128);
+
+ case SECURITY_TEXT: {
+ SkColor color;
+ switch (security_level) {
+ case ToolbarModel::EV_SECURE:
+ case ToolbarModel::SECURE:
+ color = SkColorSetRGB(7, 149, 0);
+ break;
+
+ case ToolbarModel::SECURITY_WARNING:
+ return GetColor(security_level, DEEMPHASIZED_TEXT);
+ break;
+
+ case ToolbarModel::SECURITY_ERROR:
+ color = SkColorSetRGB(162, 0, 0);
+ break;
+
+ default:
+ NOTREACHED();
+ return GetColor(security_level, TEXT);
+ }
+ return color_utils::GetReadableColor(color, GetColor(security_level,
+ BACKGROUND));
+ }
+
+ default:
+ NOTREACHED();
+ return GetColor(security_level, TEXT);
+ }
+}
+
+void LocationBarView::Update(const TabContents* tab_for_state_restoring) {
+ RefreshContentSettingViews();
+ RefreshPageActionViews();
+ // Don't Update in app launcher mode so that the location entry does not show
+ // a URL or security background.
+ if (mode_ != APP_LAUNCHER)
+ location_entry_->Update(tab_for_state_restoring);
+ OnChanged();
+}
+
+void LocationBarView::UpdateContentSettingsIcons() {
+ RefreshContentSettingViews();
+
+ Layout();
+ SchedulePaint();
+}
+
+void LocationBarView::UpdatePageActions() {
+ size_t count_before = page_action_views_.size();
+ RefreshPageActionViews();
+ if (page_action_views_.size() != count_before) {
+ NotificationService::current()->Notify(
+ NotificationType::EXTENSION_PAGE_ACTION_COUNT_CHANGED,
+ Source<LocationBar>(this),
+ NotificationService::NoDetails());
+ }
+
+ Layout();
+ SchedulePaint();
+}
+
+void LocationBarView::InvalidatePageActions() {
+ size_t count_before = page_action_views_.size();
+ DeletePageActionViews();
+ if (page_action_views_.size() != count_before) {
+ NotificationService::current()->Notify(
+ NotificationType::EXTENSION_PAGE_ACTION_COUNT_CHANGED,
+ Source<LocationBar>(this),
+ NotificationService::NoDetails());
+ }
+}
+
+void LocationBarView::Focus() {
+ // Focus the location entry native view.
+ location_entry_->SetFocus();
+}
+
+void LocationBarView::SetProfile(Profile* profile) {
+ DCHECK(profile);
+ if (profile_ != profile) {
+ profile_ = profile;
+ location_entry_->model()->SetProfile(profile);
+ selected_keyword_view_->set_profile(profile);
+ keyword_hint_view_->set_profile(profile);
+ for (ContentSettingViews::const_iterator i(content_setting_views_.begin());
+ i != content_setting_views_.end(); ++i)
+ (*i)->set_profile(profile);
+ }
+}
+
+TabContents* LocationBarView::GetTabContents() const {
+ return delegate_->GetTabContents();
+}
+
+void LocationBarView::SetPreviewEnabledPageAction(ExtensionAction* page_action,
+ bool preview_enabled) {
+ if (mode_ != NORMAL)
+ return;
+
+ DCHECK(page_action);
+ TabContents* contents = delegate_->GetTabContents();
+
+ RefreshPageActionViews();
+ PageActionWithBadgeView* page_action_view =
+ static_cast<PageActionWithBadgeView*>(GetPageActionView(page_action));
+ DCHECK(page_action_view);
+ if (!page_action_view)
+ return;
+
+ page_action_view->image_view()->set_preview_enabled(preview_enabled);
+ page_action_view->UpdateVisibility(contents,
+ GURL(WideToUTF8(model_->GetText())));
+ Layout();
+ SchedulePaint();
+}
+
+views::View* LocationBarView::GetPageActionView(
+ ExtensionAction *page_action) {
+ DCHECK(page_action);
+ for (PageActionViews::const_iterator i(page_action_views_.begin());
+ i != page_action_views_.end(); ++i) {
+ if ((*i)->image_view()->page_action() == page_action)
+ return *i;
+ }
+ return NULL;
+}
+
+void LocationBarView::SetStarToggled(bool on) {
+ if (star_view_)
+ star_view_->SetToggled(on);
+}
+
+void LocationBarView::ShowStarBubble(const GURL& url, bool newly_bookmarked) {
+ gfx::Rect screen_bounds(star_view_->GetImageBounds());
+ // Compensate for some built-in padding in the Star image.
+ screen_bounds.Inset(1, 1, 1, 2);
+ gfx::Point origin(screen_bounds.origin());
+ views::View::ConvertPointToScreen(star_view_, &origin);
+ screen_bounds.set_origin(origin);
+ browser::ShowBookmarkBubbleView(GetWindow(), screen_bounds, star_view_,
+ profile_, url, newly_bookmarked);
+}
+
+gfx::Size LocationBarView::GetPreferredSize() {
+ return gfx::Size(0,
+ (mode_ == POPUP ? kPopupBackground : kBackground)->height());
+}
+
+void LocationBarView::Layout() {
+ if (!location_entry_.get())
+ return;
+
+ int entry_width = width() - kViewPadding;
+
+ // |location_icon_view_| is visible except when |ev_bubble_view_| or
+ // |selected_keyword_view_| are visible.
+ int location_icon_width = 0;
+ int ev_bubble_width = 0;
+ location_icon_view_->SetVisible(false);
+ ev_bubble_view_->SetVisible(false);
+ const std::wstring keyword(location_entry_->model()->keyword());
+ const bool is_keyword_hint(location_entry_->model()->is_keyword_hint());
+ const bool show_selected_keyword = !keyword.empty() && !is_keyword_hint;
+ if (show_selected_keyword) {
+ entry_width -= kViewPadding; // Assume the keyword might be hidden.
+ } else if (model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) {
+ ev_bubble_view_->SetVisible(true);
+ ev_bubble_view_->SetLabel(model_->GetEVCertName());
+ ev_bubble_width = ev_bubble_view_->GetPreferredSize().width();
+ entry_width -= kBubblePadding + ev_bubble_width + kViewPadding;
+ } else {
+ location_icon_view_->SetVisible(true);
+ location_icon_width = location_icon_view_->GetPreferredSize().width();
+ entry_width -=
+ kViewPadding + location_icon_width + kLocationIconEditPadding;
+ }
+
+ if (star_view_)
+ entry_width -= star_view_->GetPreferredSize().width() + kViewPadding;
+ for (PageActionViews::const_iterator i(page_action_views_.begin());
+ i != page_action_views_.end(); ++i) {
+ if ((*i)->IsVisible())
+ entry_width -= (*i)->GetPreferredSize().width() + kViewPadding;
+ }
+ for (ContentSettingViews::const_iterator i(content_setting_views_.begin());
+ i != content_setting_views_.end(); ++i) {
+ if ((*i)->IsVisible())
+ entry_width -= (*i)->GetPreferredSize().width() + kViewPadding;
+ }
+
+#if defined(OS_WIN)
+ RECT formatting_rect;
+ location_entry_->GetRect(&formatting_rect);
+ RECT edit_bounds;
+ location_entry_->GetClientRect(&edit_bounds);
+ int max_edit_width = entry_width - formatting_rect.left -
+ (edit_bounds.right - formatting_rect.right);
+#else
+ int max_edit_width = entry_width;
+#endif
+
+ if (max_edit_width < 0)
+ return;
+ const int available_width = AvailableWidth(max_edit_width);
+
+ const bool show_keyword_hint = !keyword.empty() && is_keyword_hint;
+ selected_keyword_view_->SetVisible(show_selected_keyword);
+ keyword_hint_view_->SetVisible(show_keyword_hint);
+ if (show_selected_keyword) {
+ if (selected_keyword_view_->keyword() != keyword)
+ selected_keyword_view_->SetKeyword(keyword);
+ } else if (show_keyword_hint) {
+ if (keyword_hint_view_->keyword() != keyword)
+ keyword_hint_view_->SetKeyword(keyword);
+ }
+
+ // TODO(sky): baseline layout.
+ int location_y = TopMargin();
+ int location_height = std::max(height() - location_y - kVertMargin, 0);
+
+ // Lay out items to the right of the edit field.
+ int offset = width() - kViewPadding;
+ if (star_view_) {
+ int star_width = star_view_->GetPreferredSize().width();
+ offset -= star_width;
+ star_view_->SetBounds(offset, location_y, star_width, location_height);
+ offset -= kViewPadding;
+ }
+
+ for (PageActionViews::const_iterator i(page_action_views_.begin());
+ i != page_action_views_.end(); ++i) {
+ if ((*i)->IsVisible()) {
+ int page_action_width = (*i)->GetPreferredSize().width();
+ offset -= page_action_width;
+ (*i)->SetBounds(offset, location_y, page_action_width, location_height);
+ offset -= kViewPadding;
+ }
+ }
+ // We use a reverse_iterator here because we're laying out the views from
+ // right to left but in the vector they're ordered left to right.
+ for (ContentSettingViews::const_reverse_iterator
+ i(content_setting_views_.rbegin()); i != content_setting_views_.rend();
+ ++i) {
+ if ((*i)->IsVisible()) {
+ int content_blocked_width = (*i)->GetPreferredSize().width();
+ offset -= content_blocked_width;
+ (*i)->SetBounds(offset, location_y, content_blocked_width,
+ location_height);
+ offset -= kViewPadding;
+ }
+ }
+
+ // Now lay out items to the left of the edit field.
+ if (location_icon_view_->IsVisible()) {
+ location_icon_view_->SetBounds(kViewPadding, location_y,
+ location_icon_width, location_height);
+ offset = location_icon_view_->bounds().right() + kLocationIconEditPadding;
+ } else if (ev_bubble_view_->IsVisible()) {
+ ev_bubble_view_->SetBounds(kBubblePadding, location_y, ev_bubble_width,
+ location_height);
+ offset = ev_bubble_view_->bounds().right() + kViewPadding;
+ } else {
+ offset = show_selected_keyword ? kBubblePadding : kViewPadding;
+ }
+
+ // Now lay out the edit field and views that autocollapse to give it more
+ // room.
+ gfx::Rect location_bounds(offset, location_y, entry_width, location_height);
+ if (show_selected_keyword) {
+ LayoutView(true, selected_keyword_view_, available_width, &location_bounds);
+ if (!selected_keyword_view_->IsVisible()) {
+ location_bounds.set_x(
+ location_bounds.x() + kViewPadding - kBubblePadding);
+ }
+ } else if (show_keyword_hint) {
+ LayoutView(false, keyword_hint_view_, available_width, &location_bounds);
+ }
+
+ location_entry_view_->SetBounds(location_bounds);
+}
+
+void LocationBarView::Paint(gfx::Canvas* canvas) {
+ View::Paint(canvas);
+ // When used in the app launcher, don't draw a border, the LocationBarView has
+ // its own views::Border.
+ if (mode_ != APP_LAUNCHER) {
+ const SkBitmap* background =
+ mode_ == POPUP ?
+ kPopupBackground :
+ GetThemeProvider()->GetBitmapNamed(IDR_LOCATIONBG);
+
+ canvas->TileImageInt(*background, 0, 0, 0, 0, width(), height());
+ }
+ gfx::Rect bounds = GetLocalBounds(false);
+ int top_margin = TopMargin();
+ canvas->FillRectInt(GetColor(ToolbarModel::NONE, BACKGROUND), bounds.x(),
+ top_margin, bounds.width(),
+ std::max(height() - top_margin - kVertMargin, 0));
+}
+
+void LocationBarView::VisibleBoundsInRootChanged() {
+ location_entry_->ClosePopup();
+}
+
+#if defined(OS_WIN)
+bool LocationBarView::OnMousePressed(const views::MouseEvent& event) {
+ UINT msg;
+ if (event.IsLeftMouseButton()) {
+ msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ?
+ WM_LBUTTONDBLCLK : WM_LBUTTONDOWN;
+ } else if (event.IsMiddleMouseButton()) {
+ msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ?
+ WM_MBUTTONDBLCLK : WM_MBUTTONDOWN;
+ } else if (event.IsRightMouseButton()) {
+ msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ?
+ WM_RBUTTONDBLCLK : WM_RBUTTONDOWN;
+ } else {
+ NOTREACHED();
+ return false;
+ }
+ OnMouseEvent(event, msg);
+ return true;
+}
+
+bool LocationBarView::OnMouseDragged(const views::MouseEvent& event) {
+ OnMouseEvent(event, WM_MOUSEMOVE);
+ return true;
+}
+
+void LocationBarView::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ UINT msg;
+ if (canceled) {
+ msg = WM_CAPTURECHANGED;
+ } else if (event.IsLeftMouseButton()) {
+ msg = WM_LBUTTONUP;
+ } else if (event.IsMiddleMouseButton()) {
+ msg = WM_MBUTTONUP;
+ } else if (event.IsRightMouseButton()) {
+ msg = WM_RBUTTONUP;
+ } else {
+ NOTREACHED();
+ return;
+ }
+ OnMouseEvent(event, msg);
+}
+#endif
+
+void LocationBarView::OnAutocompleteAccept(
+ const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url) {
+ if (!url.is_valid())
+ return;
+
+ location_input_ = UTF8ToWide(url.spec());
+ disposition_ = disposition;
+ transition_ = transition;
+
+ if (command_updater_) {
+ if (!alternate_nav_url.is_valid()) {
+ command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
+ return;
+ }
+
+ scoped_ptr<AlternateNavURLFetcher> fetcher(
+ new AlternateNavURLFetcher(alternate_nav_url));
+ // The AlternateNavURLFetcher will listen for the pending navigation
+ // notification that will be issued as a result of the "open URL." It
+ // will automatically install itself into that navigation controller.
+ command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
+ if (fetcher->state() == AlternateNavURLFetcher::NOT_STARTED) {
+ // I'm not sure this should be reachable, but I'm not also sure enough
+ // that it shouldn't to stick in a NOTREACHED(). In any case, this is
+ // harmless; we can simply let the fetcher get deleted here and it will
+ // clean itself up properly.
+ } else {
+ fetcher.release(); // The navigation controller will delete the fetcher.
+ }
+ }
+}
+
+void LocationBarView::OnChanged() {
+ location_icon_view_->SetImage(
+ ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ location_entry_->GetIcon()));
+ Layout();
+ SchedulePaint();
+}
+
+void LocationBarView::OnInputInProgress(bool in_progress) {
+ delegate_->OnInputInProgress(in_progress);
+}
+
+void LocationBarView::OnKillFocus() {
+}
+
+void LocationBarView::OnSetFocus() {
+ views::FocusManager* focus_manager = GetFocusManager();
+ if (!focus_manager) {
+ NOTREACHED();
+ return;
+ }
+ focus_manager->SetFocusedView(this);
+}
+
+SkBitmap LocationBarView::GetFavIcon() const {
+ DCHECK(delegate_);
+ DCHECK(delegate_->GetTabContents());
+ return delegate_->GetTabContents()->GetFavIcon();
+}
+
+std::wstring LocationBarView::GetTitle() const {
+ DCHECK(delegate_);
+ DCHECK(delegate_->GetTabContents());
+ return UTF16ToWideHack(delegate_->GetTabContents()->GetTitle());
+}
+
+int LocationBarView::TopMargin() const {
+ return std::min(kVertMargin, height());
+}
+
+int LocationBarView::AvailableWidth(int location_bar_width) {
+#if defined(OS_WIN)
+ // Use font_.GetStringWidth() instead of
+ // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is
+ // apparently buggy. In both LTR UI and RTL UI with left-to-right layout,
+ // PosFromChar(i) might return 0 when i is greater than 1.
+ return std::max(
+ location_bar_width - font_.GetStringWidth(location_entry_->GetText()), 0);
+#else
+ return location_bar_width - location_entry_->TextWidth();
+#endif
+}
+
+bool LocationBarView::UsePref(int pref_width, int available_width) {
+ return (pref_width + kViewPadding <= available_width);
+}
+
+void LocationBarView::LayoutView(bool leading,
+ views::View* view,
+ int available_width,
+ gfx::Rect* bounds) {
+ DCHECK(view && bounds);
+ gfx::Size view_size = view->GetPreferredSize();
+ if (!UsePref(view_size.width(), available_width))
+ view_size = view->GetMinimumSize();
+ if (view_size.width() + kViewPadding >= bounds->width()) {
+ view->SetVisible(false);
+ return;
+ }
+ if (leading) {
+ view->SetBounds(bounds->x(), bounds->y(), view_size.width(),
+ bounds->height());
+ bounds->Offset(view_size.width() + kViewPadding, 0);
+ } else {
+ view->SetBounds(bounds->right() - view_size.width(), bounds->y(),
+ view_size.width(), bounds->height());
+ }
+ bounds->set_width(bounds->width() - view_size.width() - kViewPadding);
+ view->SetVisible(true);
+}
+
+void LocationBarView::RefreshContentSettingViews() {
+ const TabContents* tab_contents = delegate_->GetTabContents();
+ for (ContentSettingViews::const_iterator i(content_setting_views_.begin());
+ i != content_setting_views_.end(); ++i) {
+ (*i)->UpdateFromTabContents(
+ model_->input_in_progress() ? NULL : tab_contents);
+ }
+}
+
+void LocationBarView::DeletePageActionViews() {
+ for (PageActionViews::const_iterator i(page_action_views_.begin());
+ i != page_action_views_.end(); ++i)
+ RemoveChildView(*i);
+ STLDeleteElements(&page_action_views_);
+}
+
+void LocationBarView::RefreshPageActionViews() {
+ if (mode_ != NORMAL)
+ return;
+
+ ExtensionsService* service = profile_->GetExtensionsService();
+ if (!service)
+ return;
+
+ std::map<ExtensionAction*, bool> old_visibility;
+ for (PageActionViews::const_iterator i(page_action_views_.begin());
+ i != page_action_views_.end(); ++i)
+ old_visibility[(*i)->image_view()->page_action()] = (*i)->IsVisible();
+
+ // Remember the previous visibility of the page actions so that we can
+ // notify when this changes.
+ std::vector<ExtensionAction*> page_actions;
+ for (size_t i = 0; i < service->extensions()->size(); ++i) {
+ if (service->extensions()->at(i)->page_action())
+ page_actions.push_back(service->extensions()->at(i)->page_action());
+ }
+
+ // On startup we sometimes haven't loaded any extensions. This makes sure
+ // we catch up when the extensions (and any page actions) load.
+ if (page_actions.size() != page_action_views_.size()) {
+ DeletePageActionViews(); // Delete the old views (if any).
+
+ page_action_views_.resize(page_actions.size());
+
+ for (size_t i = 0; i < page_actions.size(); ++i) {
+ page_action_views_[i] = new PageActionWithBadgeView(
+ new PageActionImageView(this, profile_, page_actions[i]));
+ page_action_views_[i]->SetVisible(false);
+ AddChildView(page_action_views_[i]);
+ }
+ }
+
+ TabContents* contents = delegate_->GetTabContents();
+ if (!page_action_views_.empty() && contents) {
+ GURL url = GURL(WideToUTF8(model_->GetText()));
+
+ for (PageActionViews::const_iterator i(page_action_views_.begin());
+ i != page_action_views_.end(); ++i) {
+ (*i)->UpdateVisibility(contents, url);
+
+ // Check if the visibility of the action changed and notify if it did.
+ ExtensionAction* action = (*i)->image_view()->page_action();
+ if (old_visibility.find(action) == old_visibility.end() ||
+ old_visibility[action] != (*i)->IsVisible()) {
+ NotificationService::current()->Notify(
+ NotificationType::EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
+ Source<ExtensionAction>(action),
+ Details<TabContents>(contents));
+ }
+ }
+ }
+}
+
+#if defined(OS_WIN)
+void LocationBarView::OnMouseEvent(const views::MouseEvent& event, UINT msg) {
+ UINT flags = 0;
+ if (event.IsControlDown())
+ flags |= MK_CONTROL;
+ if (event.IsShiftDown())
+ flags |= MK_SHIFT;
+ if (event.IsLeftMouseButton())
+ flags |= MK_LBUTTON;
+ if (event.IsMiddleMouseButton())
+ flags |= MK_MBUTTON;
+ if (event.IsRightMouseButton())
+ flags |= MK_RBUTTON;
+
+ gfx::Point screen_point(event.location());
+ ConvertPointToScreen(this, &screen_point);
+ location_entry_->HandleExternalMsg(msg, flags, screen_point.ToPOINT());
+}
+#endif
+
+void LocationBarView::ShowFirstRunBubbleInternal(
+ FirstRun::BubbleType bubble_type) {
+#if defined(OS_WIN) // First run bubble doesn't make sense for Chrome OS.
+ // If the browser is no longer active, let's not show the info bubble, as this
+ // would make the browser the active window again.
+ if (!location_entry_view_ || !location_entry_view_->GetWidget()->IsActive())
+ return;
+
+ // Point at the start of the edit control; adjust to look as good as possible.
+ const int kXOffset = 1; // Text looks like it actually starts 1 px in.
+ const int kYOffset = -4; // Point into the omnibox, not just at its edge.
+ gfx::Point origin(location_entry_view_->bounds().x() + kXOffset,
+ y() + height() + kYOffset);
+ // If the UI layout is RTL, the coordinate system is not transformed and
+ // therefore we need to adjust the X coordinate so that bubble appears on the
+ // right hand side of the location bar.
+ if (UILayoutIsRightToLeft())
+ origin.set_x(width() - origin.x());
+ views::View::ConvertPointToScreen(this, &origin);
+ FirstRunBubble::Show(profile_, GetWindow(), gfx::Rect(origin, gfx::Size()),
+ bubble_type);
+#endif
+}
+
+bool LocationBarView::SkipDefaultKeyEventProcessing(const views::KeyEvent& e) {
+ if (keyword_hint_view_->IsVisible() &&
+ views::FocusManager::IsTabTraversalKeyEvent(e)) {
+ // We want to receive tab key events when the hint is showing.
+ return true;
+ }
+
+#if defined(OS_WIN)
+ return location_entry_->SkipDefaultKeyEventProcessing(e);
+#else
+ // TODO(jcampan): We need to refactor the code of
+ // AutocompleteEditViewWin::SkipDefaultKeyEventProcessing into this class so
+ // it can be shared between Windows and Linux.
+ // For now, we just override back-space as it is the accelerator for back
+ // navigation.
+ if (e.GetKeyCode() == base::VKEY_BACK)
+ return true;
+ return false;
+#endif
+}
+
+bool LocationBarView::GetAccessibleRole(AccessibilityTypes::Role* role) {
+ DCHECK(role);
+
+ *role = AccessibilityTypes::ROLE_GROUPING;
+ return true;
+}
+
+
+void LocationBarView::WriteDragData(views::View* sender,
+ const gfx::Point& press_pt,
+ OSExchangeData* data) {
+ DCHECK(GetDragOperations(sender, press_pt) != DragDropTypes::DRAG_NONE);
+
+ TabContents* tab_contents = delegate_->GetTabContents();
+ DCHECK(tab_contents);
+ drag_utils::SetURLAndDragImage(tab_contents->GetURL(),
+ UTF16ToWideHack(tab_contents->GetTitle()),
+ tab_contents->GetFavIcon(), data);
+}
+
+int LocationBarView::GetDragOperations(views::View* sender,
+ const gfx::Point& p) {
+ DCHECK((sender == location_icon_view_) || (sender == ev_bubble_view_));
+ TabContents* tab_contents = delegate_->GetTabContents();
+ return (tab_contents && tab_contents->GetURL().is_valid() &&
+ !location_entry()->IsEditingOrEmpty()) ?
+ (DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK) :
+ DragDropTypes::DRAG_NONE;
+}
+
+bool LocationBarView::CanStartDrag(View* sender,
+ const gfx::Point& press_pt,
+ const gfx::Point& p) {
+ return true;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// LocationBarView, LocationBar implementation:
+
+void LocationBarView::ShowFirstRunBubble(FirstRun::BubbleType bubble_type) {
+ // We wait 30 milliseconds to open. It allows less flicker.
+ Task* task = first_run_bubble_.NewRunnableMethod(
+ &LocationBarView::ShowFirstRunBubbleInternal, bubble_type);
+ MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 30);
+}
+
+std::wstring LocationBarView::GetInputString() const {
+ return location_input_;
+}
+
+WindowOpenDisposition LocationBarView::GetWindowOpenDisposition() const {
+ return disposition_;
+}
+
+PageTransition::Type LocationBarView::GetPageTransition() const {
+ return transition_;
+}
+
+void LocationBarView::AcceptInput() {
+ location_entry_->model()->AcceptInput(CURRENT_TAB, false);
+}
+
+void LocationBarView::AcceptInputWithDisposition(WindowOpenDisposition disp) {
+ location_entry_->model()->AcceptInput(disp, false);
+}
+
+void LocationBarView::FocusLocation(bool select_all) {
+ location_entry_->SetFocus();
+ if (select_all)
+ location_entry_->SelectAll(true);
+}
+
+void LocationBarView::FocusSearch() {
+ location_entry_->SetFocus();
+ location_entry_->SetForcedQuery();
+}
+
+void LocationBarView::SaveStateToContents(TabContents* contents) {
+ location_entry_->SaveStateToTab(contents);
+}
+
+void LocationBarView::Revert() {
+ location_entry_->RevertAll();
+}
+
+int LocationBarView::PageActionVisibleCount() {
+ int result = 0;
+ for (size_t i = 0; i < page_action_views_.size(); i++) {
+ if (page_action_views_[i]->IsVisible())
+ ++result;
+ }
+ return result;
+}
+
+ExtensionAction* LocationBarView::GetPageAction(size_t index) {
+ if (index < page_action_views_.size())
+ return page_action_views_[index]->image_view()->page_action();
+
+ NOTREACHED();
+ return NULL;
+}
+
+ExtensionAction* LocationBarView::GetVisiblePageAction(size_t index) {
+ size_t current = 0;
+ for (size_t i = 0; i < page_action_views_.size(); ++i) {
+ if (page_action_views_[i]->IsVisible()) {
+ if (current == index)
+ return page_action_views_[i]->image_view()->page_action();
+
+ ++current;
+ }
+ }
+
+ NOTREACHED();
+ return NULL;
+}
+
+void LocationBarView::TestPageActionPressed(size_t index) {
+ size_t current = 0;
+ for (size_t i = 0; i < page_action_views_.size(); ++i) {
+ if (page_action_views_[i]->IsVisible()) {
+ if (current == index) {
+ const int kLeftMouseButton = 1;
+ page_action_views_[i]->image_view()->ExecuteAction(kLeftMouseButton,
+ false); // inspect_with_devtools
+ return;
+ }
+ ++current;
+ }
+ }
+
+ NOTREACHED();
+}
diff --git a/chrome/browser/views/location_bar/location_bar_view.h b/chrome/browser/views/location_bar/location_bar_view.h
new file mode 100644
index 0000000..1f9c62b
--- /dev/null
+++ b/chrome/browser/views/location_bar/location_bar_view.h
@@ -0,0 +1,338 @@
+// 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_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
+
+#include <string>
+#include <vector>
+
+#include "base/task.h"
+#include "chrome/browser/autocomplete/autocomplete_edit.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
+#include "chrome/browser/first_run.h"
+#include "chrome/browser/location_bar.h"
+#include "chrome/browser/tab_contents/tab_contents.h"
+#include "chrome/browser/toolbar_model.h"
+#include "chrome/browser/views/extensions/extension_popup.h"
+#include "chrome/common/notification_observer.h"
+#include "chrome/common/notification_registrar.h"
+#include "gfx/font.h"
+#include "gfx/rect.h"
+#include "views/controls/native/native_view_host.h"
+
+#if defined(OS_WIN)
+#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h"
+#else
+#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
+#endif
+
+class Browser;
+class CommandUpdater;
+class ContentSettingImageView;
+class EVBubbleView;
+class ExtensionAction;
+class GURL;
+class KeywordHintView;
+class LocationIconView;
+class PageActionWithBadgeView;
+class Profile;
+class SelectedKeywordView;
+class StarView;
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// LocationBarView class
+//
+// The LocationBarView class is a View subclass that paints the background
+// of the URL bar strip and contains its content.
+//
+/////////////////////////////////////////////////////////////////////////////
+class LocationBarView : public LocationBar,
+ public LocationBarTesting,
+ public views::View,
+ public views::DragController,
+ public AutocompleteEditController {
+ public:
+ class Delegate {
+ public:
+ // Should return the current tab contents.
+ virtual TabContents* GetTabContents() = 0;
+
+ // Called by the location bar view when the user starts typing in the edit.
+ // This forces our security style to be UNKNOWN for the duration of the
+ // editing.
+ virtual void OnInputInProgress(bool in_progress) = 0;
+ };
+
+ enum ColorKind {
+ BACKGROUND = 0,
+ TEXT,
+ SELECTED_TEXT,
+ DEEMPHASIZED_TEXT,
+ SECURITY_TEXT,
+ };
+
+ // The modes reflect the different scenarios where a location bar can be used.
+ // The normal mode is the mode used in a regular browser window.
+ // In popup mode, the location bar view is read only and has a slightly
+ // different presentation (font size / color).
+ // In app launcher mode, the location bar is empty and no security states or
+ // page/browser actions are displayed.
+ enum Mode {
+ NORMAL = 0,
+ POPUP,
+ APP_LAUNCHER
+ };
+
+ LocationBarView(Profile* profile,
+ CommandUpdater* command_updater,
+ ToolbarModel* model,
+ Delegate* delegate,
+ Mode mode);
+ virtual ~LocationBarView();
+
+ void Init();
+
+ // Returns whether this instance has been initialized by callin Init. Init can
+ // only be called when the receiving instance is attached to a view container.
+ bool IsInitialized() const;
+
+ // Returns the appropriate color for the desired kind, based on the user's
+ // system theme.
+ static SkColor GetColor(ToolbarModel::SecurityLevel security_level,
+ ColorKind kind);
+
+ // Updates the location bar. We also reset the bar's permanent text and
+ // security style, and, if |tab_for_state_restoring| is non-NULL, also restore
+ // saved state that the tab holds.
+ void Update(const TabContents* tab_for_state_restoring);
+
+ void SetProfile(Profile* profile);
+ Profile* profile() const { return profile_; }
+
+ // Returns the current TabContents.
+ TabContents* GetTabContents() const;
+
+ // Sets |preview_enabled| for the PageAction View associated with this
+ // |page_action|. If |preview_enabled| is true, the view will display the
+ // PageActions icon even though it has not been activated by the extension.
+ // This is used by the ExtensionInstalledBubble to preview what the icon
+ // will look like for the user upon installation of the extension.
+ void SetPreviewEnabledPageAction(ExtensionAction *page_action,
+ bool preview_enabled);
+
+ // Retrieves the PageAction View which is associated with |page_action|.
+ views::View* GetPageActionView(ExtensionAction* page_action);
+
+ // Toggles the star on or off.
+ void SetStarToggled(bool on);
+
+ // Shows the bookmark bubble.
+ void ShowStarBubble(const GURL& url, bool newly_bookmarked);
+
+ // Sizing functions
+ virtual gfx::Size GetPreferredSize();
+
+ // Layout and Painting functions
+ virtual void Layout();
+ virtual void Paint(gfx::Canvas* canvas);
+
+ // No focus border for the location bar, the caret is enough.
+ virtual void PaintFocusBorder(gfx::Canvas* canvas) { }
+
+ // Called when any ancestor changes its size, asks the AutocompleteEditModel
+ // to close its popup.
+ virtual void VisibleBoundsInRootChanged();
+
+#if defined(OS_WIN)
+ // Event Handlers
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual bool OnMouseDragged(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+#endif
+
+ // AutocompleteEditController
+ virtual void OnAutocompleteAccept(const GURL& url,
+ WindowOpenDisposition disposition,
+ PageTransition::Type transition,
+ const GURL& alternate_nav_url);
+ virtual void OnChanged();
+ virtual void OnInputInProgress(bool in_progress);
+ virtual void OnKillFocus();
+ virtual void OnSetFocus();
+ virtual SkBitmap GetFavIcon() const;
+ virtual std::wstring GetTitle() const;
+
+ // Overridden from views::View:
+ virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e);
+ virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
+
+ // Overridden from views::DragController:
+ virtual void WriteDragData(View* sender,
+ const gfx::Point& press_pt,
+ OSExchangeData* data);
+ virtual int GetDragOperations(View* sender, const gfx::Point& p);
+ virtual bool CanStartDrag(View* sender,
+ const gfx::Point& press_pt,
+ const gfx::Point& p);
+
+ // Overridden from LocationBar:
+ virtual void ShowFirstRunBubble(FirstRun::BubbleType bubble_type);
+ virtual std::wstring GetInputString() const;
+ virtual WindowOpenDisposition GetWindowOpenDisposition() const;
+ virtual PageTransition::Type GetPageTransition() const;
+ virtual void AcceptInput();
+ virtual void AcceptInputWithDisposition(WindowOpenDisposition);
+ virtual void FocusLocation(bool select_all);
+ virtual void FocusSearch();
+ virtual void UpdateContentSettingsIcons();
+ virtual void UpdatePageActions();
+ virtual void InvalidatePageActions();
+ virtual void SaveStateToContents(TabContents* contents);
+ virtual void Revert();
+ virtual const AutocompleteEditView* location_entry() const {
+ return location_entry_.get();
+ }
+ virtual AutocompleteEditView* location_entry() {
+ return location_entry_.get();
+ }
+ virtual LocationBarTesting* GetLocationBarForTesting() { return this; }
+
+ // Overridden from LocationBarTesting:
+ virtual int PageActionCount() { return page_action_views_.size(); }
+ virtual int PageActionVisibleCount();
+ virtual ExtensionAction* GetPageAction(size_t index);
+ virtual ExtensionAction* GetVisiblePageAction(size_t index);
+ virtual void TestPageActionPressed(size_t index);
+
+ static const int kVertMargin;
+
+ protected:
+ void Focus();
+
+ private:
+ typedef std::vector<ContentSettingImageView*> ContentSettingViews;
+
+ friend class PageActionImageView;
+ friend class PageActionWithBadgeView;
+ typedef std::vector<PageActionWithBadgeView*> PageActionViews;
+
+ // Returns the height in pixels of the margin at the top of the bar.
+ int TopMargin() const;
+
+ // Returns the amount of horizontal space (in pixels) out of
+ // |location_bar_width| that is not taken up by the actual text in
+ // location_entry_.
+ int AvailableWidth(int location_bar_width);
+
+ // Returns whether the |available_width| is large enough to contain a view
+ // with preferred width |pref_width| at its preferred size. If this returns
+ // true, the preferred size should be used. If this returns false, the
+ // minimum size of the view should be used.
+ bool UsePref(int pref_width, int available_width);
+
+ // If View fits in the specified region, it is made visible and the
+ // bounds are adjusted appropriately. If the View does not fit, it is
+ // made invisible.
+ void LayoutView(bool leading, views::View* view, int available_width,
+ gfx::Rect* bounds);
+
+ // Update the visibility state of the Content Blocked icons to reflect what is
+ // actually blocked on the current page.
+ void RefreshContentSettingViews();
+
+ // Delete all page action views that we have created.
+ void DeletePageActionViews();
+
+ // Update the views for the Page Actions, to reflect state changes for
+ // PageActions.
+ void RefreshPageActionViews();
+
+ // Sets the visibility of view to new_vis.
+ void ToggleVisibility(bool new_vis, views::View* view);
+
+#if defined(OS_WIN)
+ // Helper for the Mouse event handlers that does all the real work.
+ void OnMouseEvent(const views::MouseEvent& event, UINT msg);
+#endif
+
+ // Helper to show the first run info bubble.
+ void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type);
+
+ // Current browser. Not owned by us.
+ Browser* browser_;
+
+ // Current profile. Not owned by us.
+ Profile* profile_;
+
+ // The Autocomplete Edit field.
+#if defined(OS_WIN)
+ scoped_ptr<AutocompleteEditViewWin> location_entry_;
+#else
+ scoped_ptr<AutocompleteEditViewGtk> location_entry_;
+#endif
+
+ // The CommandUpdater for the Browser object that corresponds to this View.
+ CommandUpdater* command_updater_;
+
+ // The model.
+ ToolbarModel* model_;
+
+ // Our delegate.
+ Delegate* delegate_;
+
+ // This is the string of text from the autocompletion session that the user
+ // entered or selected.
+ std::wstring location_input_;
+
+ // The user's desired disposition for how their input should be opened
+ WindowOpenDisposition disposition_;
+
+ // The transition type to use for the navigation
+ PageTransition::Type transition_;
+
+ // Font used by edit and some of the hints.
+ gfx::Font font_;
+
+ // An icon to the left of the edit field.
+ LocationIconView* location_icon_view_;
+
+ // A bubble displayed for EV HTTPS sites.
+ EVBubbleView* ev_bubble_view_;
+
+ // Location_entry view wrapper
+ views::NativeViewHost* location_entry_view_;
+
+ // The following views are used to provide hints and remind the user as to
+ // what is going in the edit. They are all added a children of the
+ // LocationBarView. At most one is visible at a time. Preference is
+ // given to the keyword_view_, then hint_view_.
+ // These autocollapse when the edit needs the room.
+
+ // Shown if the user has selected a keyword.
+ SelectedKeywordView* selected_keyword_view_;
+
+ // Shown if the selected url has a corresponding keyword.
+ KeywordHintView* keyword_hint_view_;
+
+ // The content setting views.
+ ContentSettingViews content_setting_views_;
+
+ // The page action icon views.
+ PageActionViews page_action_views_;
+
+ // The star.
+ StarView* star_view_;
+
+ // The mode that dictates how the bar shows.
+ Mode mode_;
+
+ // Used schedule a task for the first run info bubble.
+ ScopedRunnableMethodFactory<LocationBarView> first_run_bubble_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(LocationBarView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_BAR_VIEW_H_
diff --git a/chrome/browser/views/location_bar/location_icon_view.cc b/chrome/browser/views/location_bar/location_icon_view.cc
new file mode 100644
index 0000000..b862559
--- /dev/null
+++ b/chrome/browser/views/location_bar/location_icon_view.cc
@@ -0,0 +1,23 @@
+// 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/views/location_bar/location_icon_view.h"
+
+LocationIconView::LocationIconView(const LocationBarView* location_bar)
+ : ALLOW_THIS_IN_INITIALIZER_LIST(click_handler_(this, location_bar)) {
+}
+
+LocationIconView::~LocationIconView() {
+}
+
+bool LocationIconView::OnMousePressed(const views::MouseEvent& event) {
+ // We want to show the dialog on mouse release; that is the standard behavior
+ // for buttons.
+ return true;
+}
+
+void LocationIconView::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ click_handler_.OnMouseReleased(event, canceled);
+}
diff --git a/chrome/browser/views/location_bar/location_icon_view.h b/chrome/browser/views/location_bar/location_icon_view.h
new file mode 100644
index 0000000..dd2c3e5
--- /dev/null
+++ b/chrome/browser/views/location_bar/location_icon_view.h
@@ -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.
+
+#ifndef CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_ICON_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_ICON_VIEW_H_
+
+#include "chrome/browser/views/location_bar/click_handler.h"
+#include "views/controls/image_view.h"
+
+class LocationBarView;
+namespace views {
+class MouseEvent;
+}
+
+// LocationIconView is used to display an icon to the left of the edit field.
+// This shows the user's current action while editing, the page security
+// status on https pages, or a globe for other URLs.
+class LocationIconView : public views::ImageView {
+ public:
+ explicit LocationIconView(const LocationBarView* location_bar);
+ virtual ~LocationIconView();
+
+ // Overridden from view.
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+
+ private:
+ ClickHandler click_handler_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(LocationIconView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_LOCATION_ICON_VIEW_H_
diff --git a/chrome/browser/views/location_bar/page_action_image_view.cc b/chrome/browser/views/location_bar/page_action_image_view.cc
new file mode 100644
index 0000000..6ee90a3
--- /dev/null
+++ b/chrome/browser/views/location_bar/page_action_image_view.cc
@@ -0,0 +1,221 @@
+// 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/views/location_bar/page_action_image_view.h"
+
+#include "chrome/browser/browser_list.h"
+#include "chrome/browser/extensions/extension_browser_event_router.h"
+#include "chrome/browser/extensions/extensions_service.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/views/frame/browser_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
+#include "chrome/common/platform_util.h"
+#include "views/controls/menu/menu_2.h"
+
+PageActionImageView::PageActionImageView(LocationBarView* owner,
+ Profile* profile,
+ ExtensionAction* page_action)
+ : owner_(owner),
+ profile_(profile),
+ page_action_(page_action),
+ ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)),
+ current_tab_id_(-1),
+ preview_enabled_(false),
+ popup_(NULL) {
+ Extension* extension = profile->GetExtensionsService()->GetExtensionById(
+ page_action->extension_id(), false);
+ DCHECK(extension);
+
+ // Load all the icons declared in the manifest. This is the contents of the
+ // icons array, plus the default_icon property, if any.
+ std::vector<std::string> icon_paths(*page_action->icon_paths());
+ if (!page_action_->default_icon_path().empty())
+ icon_paths.push_back(page_action_->default_icon_path());
+
+ for (std::vector<std::string>::iterator iter = icon_paths.begin();
+ iter != icon_paths.end(); ++iter) {
+ tracker_.LoadImage(extension, extension->GetResource(*iter),
+ gfx::Size(Extension::kPageActionIconMaxSize,
+ Extension::kPageActionIconMaxSize),
+ ImageLoadingTracker::DONT_CACHE);
+ }
+}
+
+PageActionImageView::~PageActionImageView() {
+ if (popup_)
+ HidePopup();
+}
+
+void PageActionImageView::ExecuteAction(int button,
+ bool inspect_with_devtools) {
+ if (current_tab_id_ < 0) {
+ NOTREACHED() << "No current tab.";
+ return;
+ }
+
+ if (page_action_->HasPopup(current_tab_id_)) {
+ // In tests, GetLastActive could return NULL, so we need to have
+ // a fallback.
+ // TODO(erikkay): Find a better way to get the Browser that this
+ // button is in.
+ Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
+ if (!browser)
+ browser = BrowserList::FindBrowserWithProfile(profile_);
+ DCHECK(browser);
+
+ bool popup_showing = popup_ != NULL;
+
+ // Always hide the current popup. Only one popup at a time.
+ HidePopup();
+
+ // If we were already showing, then treat this click as a dismiss.
+ if (popup_showing)
+ return;
+
+ gfx::Rect screen_bounds(GetImageBounds());
+ gfx::Point origin(screen_bounds.origin());
+ View::ConvertPointToScreen(this, &origin);
+ screen_bounds.set_origin(origin);
+
+ popup_ = ExtensionPopup::Show(
+ page_action_->GetPopupUrl(current_tab_id_),
+ browser,
+ browser->profile(),
+ browser->window()->GetNativeHandle(),
+ screen_bounds,
+ BubbleBorder::TOP_RIGHT,
+ true, // Activate the popup window.
+ inspect_with_devtools,
+ ExtensionPopup::BUBBLE_CHROME,
+ this); // ExtensionPopup::Observer
+ } else {
+ ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
+ profile_, page_action_->extension_id(), page_action_->id(),
+ current_tab_id_, current_url_.spec(), button);
+ }
+}
+
+bool PageActionImageView::OnMousePressed(const views::MouseEvent& event) {
+ // We want to show the bubble on mouse release; that is the standard behavior
+ // for buttons. (Also, triggering on mouse press causes bugs like
+ // http://crbug.com/33155.)
+ return true;
+}
+
+void PageActionImageView::OnMouseReleased(const views::MouseEvent& event,
+ bool canceled) {
+ if (canceled || !HitTest(event.location()))
+ return;
+
+ int button = -1;
+ if (event.IsLeftMouseButton()) {
+ button = 1;
+ } else if (event.IsMiddleMouseButton()) {
+ button = 2;
+ } else if (event.IsRightMouseButton()) {
+ // Get the top left point of this button in screen coordinates.
+ gfx::Point menu_origin;
+ ConvertPointToScreen(this, &menu_origin);
+
+ // Make the menu appear below the button.
+ menu_origin.Offset(0, height());
+
+ Extension* extension = profile_->GetExtensionsService()->GetExtensionById(
+ page_action()->extension_id(), false);
+ Browser* browser = BrowserView::GetBrowserViewForNativeWindow(
+ platform_util::GetTopLevel(GetWidget()->GetNativeView()))->browser();
+ context_menu_contents_ =
+ new ExtensionContextMenuModel(extension, browser, this);
+ context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
+ context_menu_menu_->RunContextMenuAt(menu_origin);
+ return;
+ }
+
+ ExecuteAction(button, false); // inspect_with_devtools
+}
+
+void PageActionImageView::OnImageLoaded(
+ SkBitmap* image, ExtensionResource resource, int index) {
+ // We loaded icons()->size() icons, plus one extra if the page action had
+ // a default icon.
+ int total_icons = static_cast<int>(page_action_->icon_paths()->size());
+ if (!page_action_->default_icon_path().empty())
+ total_icons++;
+ DCHECK(index < total_icons);
+
+ // Map the index of the loaded image back to its name. If we ever get an
+ // index greater than the number of icons, it must be the default icon.
+ if (image) {
+ if (index < static_cast<int>(page_action_->icon_paths()->size()))
+ page_action_icons_[page_action_->icon_paths()->at(index)] = *image;
+ else
+ page_action_icons_[page_action_->default_icon_path()] = *image;
+ }
+
+ owner_->UpdatePageActions();
+}
+
+void PageActionImageView::UpdateVisibility(TabContents* contents,
+ const GURL& url) {
+ // Save this off so we can pass it back to the extension when the action gets
+ // executed. See PageActionImageView::OnMousePressed.
+ current_tab_id_ = ExtensionTabUtil::GetTabId(contents);
+ current_url_ = url;
+
+ bool visible =
+ preview_enabled_ || page_action_->GetIsVisible(current_tab_id_);
+ if (visible) {
+ // Set the tooltip.
+ tooltip_ = page_action_->GetTitle(current_tab_id_);
+ SetTooltipText(UTF8ToWide(tooltip_));
+
+ // Set the image.
+ // It can come from three places. In descending order of priority:
+ // - The developer can set it dynamically by path or bitmap. It will be in
+ // page_action_->GetIcon().
+ // - The developer can set it dynamically by index. It will be in
+ // page_action_->GetIconIndex().
+ // - It can be set in the manifest by path. It will be in page_action_->
+ // default_icon_path().
+
+ // First look for a dynamically set bitmap.
+ SkBitmap icon = page_action_->GetIcon(current_tab_id_);
+ if (icon.isNull()) {
+ int icon_index = page_action_->GetIconIndex(current_tab_id_);
+ std::string icon_path;
+ if (icon_index >= 0)
+ icon_path = page_action_->icon_paths()->at(icon_index);
+ else
+ icon_path = page_action_->default_icon_path();
+
+ if (!icon_path.empty()) {
+ PageActionMap::iterator iter = page_action_icons_.find(icon_path);
+ if (iter != page_action_icons_.end())
+ icon = iter->second;
+ }
+ }
+
+ if (!icon.isNull())
+ SetImage(&icon);
+ }
+ SetVisible(visible);
+}
+
+void PageActionImageView::InspectPopup(ExtensionAction* action) {
+ ExecuteAction(1, // left-click
+ true); // inspect_with_devtools
+}
+
+void PageActionImageView::ExtensionPopupClosed(ExtensionPopup* popup) {
+ DCHECK_EQ(popup_, popup);
+ // ExtensionPopup is ref-counted, so we don't need to delete it.
+ popup_ = NULL;
+}
+
+void PageActionImageView::HidePopup() {
+ if (popup_)
+ popup_->Close();
+}
+
+
diff --git a/chrome/browser/views/location_bar/page_action_image_view.h b/chrome/browser/views/location_bar/page_action_image_view.h
new file mode 100644
index 0000000..3c107e1
--- /dev/null
+++ b/chrome/browser/views/location_bar/page_action_image_view.h
@@ -0,0 +1,109 @@
+// 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_VIEWS_LOCATION_BAR_PAGE_ACTION_IMAGE_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_IMAGE_VIEW_H_
+
+#include <map>
+#include <string>
+
+#include "base/scoped_ptr.h"
+#include "chrome/browser/extensions/image_loading_tracker.h"
+#include "chrome/browser/extensions/extension_context_menu_model.h"
+#include "chrome/browser/views/extensions/extension_popup.h"
+#include "views/controls/image_view.h"
+
+class LocationBarView;
+namespace views {
+class Menu2;
+};
+
+// PageActionImageView is used by the LocationBarView to display the icon for a
+// given PageAction and notify the extension when the icon is clicked.
+class PageActionImageView : public views::ImageView,
+ public ImageLoadingTracker::Observer,
+ public ExtensionContextMenuModel::PopupDelegate,
+ public ExtensionPopup::Observer {
+ public:
+ PageActionImageView(LocationBarView* owner,
+ Profile* profile,
+ ExtensionAction* page_action);
+ virtual ~PageActionImageView();
+
+ ExtensionAction* page_action() { return page_action_; }
+
+ int current_tab_id() { return current_tab_id_; }
+
+ void set_preview_enabled(bool preview_enabled) {
+ preview_enabled_ = preview_enabled;
+ }
+
+ // Overridden from view.
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+
+ // Overridden from ImageLoadingTracker.
+ virtual void OnImageLoaded(
+ SkBitmap* image, ExtensionResource resource, int index);
+
+ // Overridden from ExtensionContextMenuModelModel::Delegate
+ virtual void InspectPopup(ExtensionAction* action);
+
+ // Overridden from ExtensionPopup::Observer
+ virtual void ExtensionPopupClosed(ExtensionPopup* popup);
+
+ // Called to notify the PageAction that it should determine whether to be
+ // visible or hidden. |contents| is the TabContents that is active, |url| is
+ // the current page URL.
+ void UpdateVisibility(TabContents* contents, const GURL& url);
+
+ // Either notify listeners or show a popup depending on the page action.
+ void ExecuteAction(int button, bool inspect_with_devtools);
+
+ private:
+ // Hides the active popup, if there is one.
+ void HidePopup();
+
+ // The location bar view that owns us.
+ LocationBarView* owner_;
+
+ // The current profile (not owned by us).
+ Profile* profile_;
+
+ // The PageAction that this view represents. The PageAction is not owned by
+ // us, it resides in the extension of this particular profile.
+ ExtensionAction* page_action_;
+
+ // A cache of bitmaps the page actions might need to show, mapped by path.
+ typedef std::map<std::string, SkBitmap> PageActionMap;
+ PageActionMap page_action_icons_;
+
+ // The context menu for this page action.
+ scoped_refptr<ExtensionContextMenuModel> context_menu_contents_;
+ scoped_ptr<views::Menu2> context_menu_menu_;
+
+ // The object that is waiting for the image loading to complete
+ // asynchronously.
+ ImageLoadingTracker tracker_;
+
+ // The tab id we are currently showing the icon for.
+ int current_tab_id_;
+
+ // The URL we are currently showing the icon for.
+ GURL current_url_;
+
+ // The string to show for a tooltip;
+ std::string tooltip_;
+
+ // This is used for post-install visual feedback. The page_action icon is
+ // briefly shown even if it hasn't been enabled by its extension.
+ bool preview_enabled_;
+
+ // The current popup and the button it came from. NULL if no popup.
+ ExtensionPopup* popup_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(PageActionImageView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_IMAGE_VIEW_H_
diff --git a/chrome/browser/views/location_bar/page_action_with_badge_view.cc b/chrome/browser/views/location_bar/page_action_with_badge_view.cc
new file mode 100644
index 0000000..6d890f9
--- /dev/null
+++ b/chrome/browser/views/location_bar/page_action_with_badge_view.cc
@@ -0,0 +1,35 @@
+// 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/views/location_bar/page_action_with_badge_view.h"
+
+#include "chrome/browser/views/location_bar/page_action_image_view.h"
+#include "chrome/common/extensions/extension.h"
+
+PageActionWithBadgeView::PageActionWithBadgeView(
+ PageActionImageView* image_view) {
+ image_view_ = image_view;
+ AddChildView(image_view_);
+}
+
+gfx::Size PageActionWithBadgeView::GetPreferredSize() {
+ return gfx::Size(Extension::kPageActionIconMaxSize,
+ Extension::kPageActionIconMaxSize);
+}
+
+void PageActionWithBadgeView::Layout() {
+ // We have 25 pixels of vertical space in the Omnibox to play with, so even
+ // sized icons (such as 16x16) have either a 5 or a 4 pixel whitespace
+ // (padding) above and below. It looks better to have the extra pixel above
+ // the icon than below it, so we add a pixel. http://crbug.com/25708.
+ const SkBitmap& image = image_view()->GetImage();
+ int y = (image.height() + 1) % 2; // Even numbers: 1px padding. Odd: 0px.
+ image_view_->SetBounds(0, y, width(), height());
+}
+
+void PageActionWithBadgeView::UpdateVisibility(TabContents* contents,
+ const GURL& url) {
+ image_view_->UpdateVisibility(contents, url);
+ SetVisible(image_view_->IsVisible());
+}
diff --git a/chrome/browser/views/location_bar/page_action_with_badge_view.h b/chrome/browser/views/location_bar/page_action_with_badge_view.h
new file mode 100644
index 0000000..2df76bb
--- /dev/null
+++ b/chrome/browser/views/location_bar/page_action_with_badge_view.h
@@ -0,0 +1,35 @@
+// 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_VIEWS_LOCATION_BAR_PAGE_ACTION_WITH_BADGE_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_WITH_BADGE_VIEW_H_
+
+#include "gfx/size.h"
+#include "views/view.h"
+
+class GURL;
+class PageActionImageView;
+class TabContents;
+
+// A container for the PageActionImageView plus its badge.
+class PageActionWithBadgeView : public views::View {
+ public:
+ explicit PageActionWithBadgeView(PageActionImageView* image_view);
+
+ PageActionImageView* image_view() { return image_view_; }
+
+ virtual gfx::Size GetPreferredSize();
+
+ void UpdateVisibility(TabContents* contents, const GURL& url);
+
+ private:
+ virtual void Layout();
+
+ // The button this view contains.
+ PageActionImageView* image_view_;
+
+ DISALLOW_COPY_AND_ASSIGN(PageActionWithBadgeView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_PAGE_ACTION_WITH_BADGE_VIEW_H_
diff --git a/chrome/browser/views/location_bar/selected_keyword_view.cc b/chrome/browser/views/location_bar/selected_keyword_view.cc
new file mode 100644
index 0000000..47779bc
--- /dev/null
+++ b/chrome/browser/views/location_bar/selected_keyword_view.cc
@@ -0,0 +1,84 @@
+// 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/views/location_bar/selected_keyword_view.h"
+
+#include "app/l10n_util.h"
+#include "base/i18n/rtl.h"
+#include "base/logging.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/views/location_bar/keyword_hint_view.h"
+#include "grit/generated_resources.h"
+
+SelectedKeywordView::SelectedKeywordView(const int background_images[],
+ int contained_image,
+ const SkColor& color,
+ Profile* profile)
+ : IconLabelBubbleView(background_images, contained_image, color),
+ profile_(profile) {
+ full_label_.SetVisible(false);
+ partial_label_.SetVisible(false);
+}
+
+SelectedKeywordView::~SelectedKeywordView() {
+}
+
+void SelectedKeywordView::SetFont(const gfx::Font& font) {
+ IconLabelBubbleView::SetFont(font);
+ full_label_.SetFont(font);
+ partial_label_.SetFont(font);
+}
+
+gfx::Size SelectedKeywordView::GetPreferredSize() {
+ gfx::Size size(GetNonLabelSize());
+ size.Enlarge(full_label_.GetPreferredSize().width(), 0);
+ return size;
+}
+
+gfx::Size SelectedKeywordView::GetMinimumSize() {
+ gfx::Size size(GetNonLabelSize());
+ size.Enlarge(partial_label_.GetMinimumSize().width(), 0);
+ return size;
+}
+
+void SelectedKeywordView::Layout() {
+ SetLabel((width() == GetPreferredSize().width()) ?
+ full_label_.GetText() : partial_label_.GetText());
+ IconLabelBubbleView::Layout();
+}
+
+void SelectedKeywordView::SetKeyword(const std::wstring& keyword) {
+ keyword_ = keyword;
+ if (keyword.empty())
+ return;
+ DCHECK(profile_);
+ if (!profile_->GetTemplateURLModel())
+ return;
+
+ const std::wstring short_name =
+ KeywordHintView::GetKeywordName(profile_, keyword);
+ full_label_.SetText(l10n_util::GetStringF(IDS_OMNIBOX_KEYWORD_TEXT,
+ short_name));
+ const std::wstring min_string = CalculateMinString(short_name);
+ partial_label_.SetText(min_string.empty() ?
+ full_label_.GetText() :
+ l10n_util::GetStringF(IDS_OMNIBOX_KEYWORD_TEXT, min_string));
+}
+
+std::wstring SelectedKeywordView::CalculateMinString(
+ const std::wstring& description) {
+ // Chop at the first '.' or whitespace.
+ const size_t dot_index = description.find(L'.');
+ const size_t ws_index = description.find_first_of(kWhitespaceWide);
+ size_t chop_index = std::min(dot_index, ws_index);
+ std::wstring min_string;
+ if (chop_index == std::wstring::npos) {
+ // No dot or whitespace, truncate to at most 3 chars.
+ min_string = l10n_util::TruncateString(description, 3);
+ } else {
+ min_string = description.substr(0, chop_index);
+ }
+ base::i18n::AdjustStringForLocaleDirection(min_string, &min_string);
+ return min_string;
+}
diff --git a/chrome/browser/views/location_bar/selected_keyword_view.h b/chrome/browser/views/location_bar/selected_keyword_view.h
new file mode 100644
index 0000000..8a3afbf
--- /dev/null
+++ b/chrome/browser/views/location_bar/selected_keyword_view.h
@@ -0,0 +1,61 @@
+// 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_VIEWS_LOCATION_BAR_SELECTED_KEYWORD_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_SELECTED_KEYWORD_VIEW_H_
+
+#include <string>
+
+#include "chrome/browser/views/location_bar/icon_label_bubble_view.h"
+#include "views/controls/label.h"
+
+class Profile;
+namespace gfx {
+class Font;
+class Size;
+}
+
+// SelectedKeywordView displays the tab-to-search UI in the location bar view.
+class SelectedKeywordView : public IconLabelBubbleView {
+ public:
+ SelectedKeywordView(const int background_images[],
+ int contained_image,
+ const SkColor& color,
+ Profile* profile);
+ virtual ~SelectedKeywordView();
+
+ void SetFont(const gfx::Font& font);
+
+ virtual gfx::Size GetPreferredSize();
+ virtual gfx::Size GetMinimumSize();
+ virtual void Layout();
+
+ // The current keyword, or an empty string if no keyword is displayed.
+ void SetKeyword(const std::wstring& keyword);
+ std::wstring keyword() const { return keyword_; }
+
+ void set_profile(Profile* profile) { profile_ = profile; }
+
+ private:
+ // Returns the truncated version of description to use.
+ std::wstring CalculateMinString(const std::wstring& description);
+
+ // The keyword we're showing. If empty, no keyword is selected.
+ // NOTE: we don't cache the TemplateURL as it is possible for it to get
+ // deleted out from under us.
+ std::wstring keyword_;
+
+ // These labels are never visible. They are used to size the view. One
+ // label contains the complete description of the keyword, the second
+ // contains a truncated version of the description, for if there is not
+ // enough room to display the complete description.
+ views::Label full_label_;
+ views::Label partial_label_;
+
+ Profile* profile_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SelectedKeywordView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_SELECTED_KEYWORD_VIEW_H_
diff --git a/chrome/browser/views/location_bar/star_view.cc b/chrome/browser/views/location_bar/star_view.cc
new file mode 100644
index 0000000..30c7888
--- /dev/null
+++ b/chrome/browser/views/location_bar/star_view.cc
@@ -0,0 +1,58 @@
+// 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/views/location_bar/star_view.h"
+
+#include "app/l10n_util.h"
+#include "app/resource_bundle.h"
+#include "chrome/app/chrome_dll_resource.h"
+#include "chrome/browser/command_updater.h"
+#include "chrome/browser/view_ids.h"
+#include "grit/generated_resources.h"
+#include "grit/theme_resources.h"
+
+StarView::StarView(CommandUpdater* command_updater)
+ : command_updater_(command_updater) {
+ SetID(VIEW_ID_STAR_BUTTON);
+ SetToggled(false);
+}
+
+StarView::~StarView() {
+}
+
+void StarView::SetToggled(bool on) {
+ SetTooltipText(l10n_util::GetString(
+ on ? IDS_TOOLTIP_STARRED : IDS_TOOLTIP_STAR));
+ // Since StarView is an ImageView, the SetTooltipText changes the accessible
+ // name. To keep the accessible name unchanged, we need to set the accessible
+ // name right after we modify the tooltip text for this view.
+ SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_STAR));
+ SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed(
+ on ? IDR_OMNIBOX_STAR_LIT : IDR_OMNIBOX_STAR));
+}
+
+bool StarView::GetAccessibleRole(AccessibilityTypes::Role* role) {
+ *role = AccessibilityTypes::ROLE_PUSHBUTTON;
+ return true;
+}
+
+bool StarView::OnMousePressed(const views::MouseEvent& event) {
+ // We want to show the bubble on mouse release; that is the standard behavior
+ // for buttons.
+ return true;
+}
+
+void StarView::OnMouseReleased(const views::MouseEvent& event, bool canceled) {
+ if (!canceled && HitTest(event.location()))
+ command_updater_->ExecuteCommand(IDC_BOOKMARK_PAGE);
+}
+
+void StarView::InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape) {
+}
+
+bool StarView::CloseOnEscape() {
+ return true;
+}
+
diff --git a/chrome/browser/views/location_bar/star_view.h b/chrome/browser/views/location_bar/star_view.h
new file mode 100644
index 0000000..f5aa62c
--- /dev/null
+++ b/chrome/browser/views/location_bar/star_view.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_VIEWS_LOCATION_BAR_STAR_VIEW_H_
+#define CHROME_BROWSER_VIEWS_LOCATION_BAR_STAR_VIEW_H_
+
+#include "chrome/browser/views/info_bubble.h"
+#include "views/controls/image_view.h"
+
+class CommandUpdater;
+class InfoBubble;
+
+namespace views {
+class MouseEvent;
+}
+
+class StarView : public views::ImageView, public InfoBubbleDelegate {
+ public:
+ explicit StarView(CommandUpdater* command_updater);
+ virtual ~StarView();
+
+ // Toggles the star on or off.
+ void SetToggled(bool on);
+
+ private:
+ // views::ImageView overrides:
+ virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
+ virtual bool OnMousePressed(const views::MouseEvent& event);
+ virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
+
+ // InfoBubbleDelegate overrides:
+ virtual void InfoBubbleClosing(InfoBubble* info_bubble,
+ bool closed_by_escape);
+ virtual bool CloseOnEscape();
+
+ // The CommandUpdater for the Browser object that owns the location bar.
+ CommandUpdater* command_updater_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StarView);
+};
+
+#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_STAR_VIEW_H_
diff --git a/chrome/browser/views/location_bar_view.cc b/chrome/browser/views/location_bar_view.cc
deleted file mode 100644
index 935598c..0000000
--- a/chrome/browser/views/location_bar_view.cc
+++ /dev/null
@@ -1,1668 +0,0 @@
-// 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/views/location_bar_view.h"
-
-#if defined(OS_LINUX)
-#include <gtk/gtk.h>
-#endif
-
-#include "app/drag_drop_types.h"
-#include "app/l10n_util.h"
-#include "app/resource_bundle.h"
-#include "app/theme_provider.h"
-#include "base/i18n/rtl.h"
-#include "base/stl_util-inl.h"
-#include "chrome/app/chrome_dll_resource.h"
-#include "chrome/browser/alternate_nav_url_fetcher.h"
-#include "chrome/browser/browser_list.h"
-#include "chrome/browser/command_updater.h"
-#include "chrome/browser/content_setting_bubble_model.h"
-#include "chrome/browser/content_setting_image_model.h"
-#include "chrome/browser/extensions/extension_browser_event_router.h"
-#include "chrome/browser/extensions/extensions_service.h"
-#include "chrome/browser/profile.h"
-#include "chrome/browser/search_engines/template_url_model.h"
-#include "chrome/browser/view_ids.h"
-#include "chrome/browser/views/browser_dialogs.h"
-#include "chrome/browser/views/content_blocked_bubble_contents.h"
-#include "chrome/browser/views/frame/browser_view.h"
-#include "chrome/common/platform_util.h"
-#include "gfx/canvas.h"
-#include "gfx/color_utils.h"
-#include "grit/generated_resources.h"
-#include "grit/theme_resources.h"
-#include "views/drag_utils.h"
-
-#if defined(OS_WIN)
-#include "chrome/browser/views/first_run_bubble.h"
-#endif
-
-using views::View;
-
-// static
-const int LocationBarView::kVertMargin = 2;
-
-// Padding between items in the location bar.
-static const int kViewPadding = 3;
-
-// Padding before the start of a bubble.
-static const int kBubblePadding = kViewPadding - 1;
-
-// Padding between the location icon and the edit, if they're adjacent.
-static const int kLocationIconEditPadding = kViewPadding - 1;
-
-static const int kEVBubbleBackgroundImages[] = {
- IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_L,
- IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_C,
- IDR_OMNIBOX_EV_BUBBLE_BACKGROUND_R,
-};
-
-static const int kSelectedKeywordBackgroundImages[] = {
- IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_L,
- IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_C,
- IDR_LOCATION_BAR_SELECTED_KEYWORD_BACKGROUND_R,
-};
-
-static const SkBitmap* kBackground = NULL;
-
-static const SkBitmap* kPopupBackground = NULL;
-
-// The tab key image.
-static const SkBitmap* kTabButtonBitmap = NULL;
-
-// Returns the short name for a keyword.
-static std::wstring GetKeywordName(Profile* profile,
- const std::wstring& keyword) {
- // Make sure the TemplateURL still exists.
- // TODO(sky): Once LocationBarView adds a listener to the TemplateURLModel
- // to track changes to the model, this should become a DCHECK.
- const TemplateURL* template_url =
- profile->GetTemplateURLModel()->GetTemplateURLForKeyword(keyword);
- if (template_url)
- return template_url->AdjustedShortNameForLocaleDirection();
- return std::wstring();
-}
-
-
-// PageActionWithBadgeView ----------------------------------------------------
-
-// A container for the PageActionImageView plus its badge.
-class LocationBarView::PageActionWithBadgeView : public views::View {
- public:
- explicit PageActionWithBadgeView(PageActionImageView* image_view);
-
- PageActionImageView* image_view() { return image_view_; }
-
- virtual gfx::Size GetPreferredSize() {
- return gfx::Size(Extension::kPageActionIconMaxSize,
- Extension::kPageActionIconMaxSize);
- }
-
- void UpdateVisibility(TabContents* contents, const GURL& url);
-
- private:
- virtual void Layout();
-
- // The button this view contains.
- PageActionImageView* image_view_;
-
- DISALLOW_COPY_AND_ASSIGN(PageActionWithBadgeView);
-};
-
-LocationBarView::PageActionWithBadgeView::PageActionWithBadgeView(
- PageActionImageView* image_view) {
- image_view_ = image_view;
- AddChildView(image_view_);
-}
-
-void LocationBarView::PageActionWithBadgeView::Layout() {
- // We have 25 pixels of vertical space in the Omnibox to play with, so even
- // sized icons (such as 16x16) have either a 5 or a 4 pixel whitespace
- // (padding) above and below. It looks better to have the extra pixel above
- // the icon than below it, so we add a pixel. http://crbug.com/25708.
- const SkBitmap& image = image_view()->GetImage();
- int y = (image.height() + 1) % 2; // Even numbers: 1px padding. Odd: 0px.
- image_view_->SetBounds(0, y, width(), height());
-}
-
-void LocationBarView::PageActionWithBadgeView::UpdateVisibility(
- TabContents* contents, const GURL& url) {
- image_view_->UpdateVisibility(contents, url);
- SetVisible(image_view_->IsVisible());
-}
-
-
-// LocationBarView -----------------------------------------------------------
-
-LocationBarView::LocationBarView(Profile* profile,
- CommandUpdater* command_updater,
- ToolbarModel* model,
- Delegate* delegate,
- bool popup_window_mode)
- : profile_(profile),
- command_updater_(command_updater),
- model_(model),
- delegate_(delegate),
- disposition_(CURRENT_TAB),
- ALLOW_THIS_IN_INITIALIZER_LIST(location_icon_view_(this)),
- ALLOW_THIS_IN_INITIALIZER_LIST(ev_bubble_view_(
- kEVBubbleBackgroundImages, IDR_OMNIBOX_HTTPS_VALID,
- GetColor(ToolbarModel::EV_SECURE, SECURITY_TEXT), this)),
- location_entry_view_(NULL),
- selected_keyword_view_(kSelectedKeywordBackgroundImages,
- IDR_OMNIBOX_SEARCH, SK_ColorBLACK, profile),
- keyword_hint_view_(profile),
- star_view_(command_updater),
- popup_window_mode_(popup_window_mode),
- ALLOW_THIS_IN_INITIALIZER_LIST(first_run_bubble_(this)) {
- DCHECK(profile_);
- SetID(VIEW_ID_LOCATION_BAR);
- SetFocusable(true);
-
- if (!kBackground) {
- ResourceBundle &rb = ResourceBundle::GetSharedInstance();
- kBackground = rb.GetBitmapNamed(IDR_LOCATIONBG);
- kPopupBackground = rb.GetBitmapNamed(IDR_LOCATIONBG_POPUPMODE_CENTER);
- }
-}
-
-LocationBarView::~LocationBarView() {
-}
-
-void LocationBarView::Init() {
- if (popup_window_mode_) {
- font_ = ResourceBundle::GetSharedInstance().GetFont(
- ResourceBundle::BaseFont);
- } else {
- // Use a larger version of the system font.
- font_ = font_.DeriveFont(3);
- }
-
- AddChildView(&location_icon_view_);
- location_icon_view_.SetVisible(true);
- location_icon_view_.SetDragController(this);
- location_icon_view_.set_parent_owned(false);
-
- AddChildView(&ev_bubble_view_);
- ev_bubble_view_.SetVisible(false);
- ev_bubble_view_.SetDragController(this);
- ev_bubble_view_.set_parent_owned(false);
-
- // URL edit field.
- // View container for URL edit field.
-#if defined(OS_WIN)
- location_entry_.reset(new AutocompleteEditViewWin(font_, this, model_, this,
- GetWidget()->GetNativeView(), profile_, command_updater_,
- popup_window_mode_, this));
-#else
- location_entry_.reset(new AutocompleteEditViewGtk(this, model_, profile_,
- command_updater_, popup_window_mode_, this));
- location_entry_->Init();
- // Make all the children of the widget visible. NOTE: this won't display
- // anything, it just toggles the visible flag.
- gtk_widget_show_all(location_entry_->GetNativeView());
- // Hide the widget. NativeViewHostGtk will make it visible again as
- // necessary.
- gtk_widget_hide(location_entry_->GetNativeView());
-#endif
- location_entry_view_ = new views::NativeViewHost;
- location_entry_view_->SetID(VIEW_ID_AUTOCOMPLETE);
- AddChildView(location_entry_view_);
- location_entry_view_->set_focus_view(this);
- location_entry_view_->Attach(location_entry_->GetNativeView());
-
- AddChildView(&selected_keyword_view_);
- selected_keyword_view_.SetFont(font_);
- selected_keyword_view_.SetVisible(false);
- selected_keyword_view_.set_parent_owned(false);
-
- SkColor dimmed_text = GetColor(ToolbarModel::NONE, DEEMPHASIZED_TEXT);
-
- AddChildView(&keyword_hint_view_);
- keyword_hint_view_.SetVisible(false);
- keyword_hint_view_.SetFont(font_);
- keyword_hint_view_.SetColor(dimmed_text);
- keyword_hint_view_.set_parent_owned(false);
-
- for (int i = 0; i < CONTENT_SETTINGS_NUM_TYPES; ++i) {
- ContentSettingImageView* content_blocked_view = new ContentSettingImageView(
- static_cast<ContentSettingsType>(i), this, profile_);
- content_setting_views_.push_back(content_blocked_view);
- AddChildView(content_blocked_view);
- content_blocked_view->SetVisible(false);
- }
-
- if (!popup_window_mode_) {
- AddChildView(&star_view_);
- star_view_.SetVisible(true);
- star_view_.set_parent_owned(false);
- }
-
- // Notify us when any ancestor is resized. In this case we want to tell the
- // AutocompleteEditView to close its popup.
- SetNotifyWhenVisibleBoundsInRootChanges(true);
-
- // Initialize the location entry. We do this to avoid a black flash which is
- // visible when the location entry has just been initialized.
- Update(NULL);
-
- OnChanged();
-}
-
-bool LocationBarView::IsInitialized() const {
- return location_entry_view_ != NULL;
-}
-
-// static
-SkColor LocationBarView::GetColor(ToolbarModel::SecurityLevel security_level,
- ColorKind kind) {
- switch (kind) {
-#if defined(OS_WIN)
- case BACKGROUND: return color_utils::GetSysSkColor(COLOR_WINDOW);
- case TEXT: return color_utils::GetSysSkColor(COLOR_WINDOWTEXT);
- case SELECTED_TEXT: return color_utils::GetSysSkColor(COLOR_HIGHLIGHTTEXT);
-#else
- // TODO(beng): source from theme provider.
- case BACKGROUND: return SK_ColorWHITE;
- case TEXT: return SK_ColorBLACK;
- case SELECTED_TEXT: return SK_ColorWHITE;
-#endif
-
- case DEEMPHASIZED_TEXT:
- return color_utils::AlphaBlend(GetColor(security_level, TEXT),
- GetColor(security_level, BACKGROUND), 128);
-
- case SECURITY_TEXT: {
- SkColor color;
- switch (security_level) {
- case ToolbarModel::EV_SECURE:
- case ToolbarModel::SECURE:
- color = SkColorSetRGB(7, 149, 0);
- break;
-
- case ToolbarModel::SECURITY_WARNING:
- return GetColor(security_level, DEEMPHASIZED_TEXT);
- break;
-
- case ToolbarModel::SECURITY_ERROR:
- color = SkColorSetRGB(162, 0, 0);
- break;
-
- default:
- NOTREACHED();
- return GetColor(security_level, TEXT);
- }
- return color_utils::GetReadableColor(color, GetColor(security_level,
- BACKGROUND));
- }
-
- default:
- NOTREACHED();
- return GetColor(security_level, TEXT);
- }
-}
-
-void LocationBarView::Update(const TabContents* tab_for_state_restoring) {
- RefreshContentSettingViews();
- RefreshPageActionViews();
- location_entry_->Update(tab_for_state_restoring);
- OnChanged();
-}
-
-void LocationBarView::UpdateContentSettingsIcons() {
- RefreshContentSettingViews();
-
- Layout();
- SchedulePaint();
-}
-
-void LocationBarView::UpdatePageActions() {
- size_t count_before = page_action_views_.size();
- RefreshPageActionViews();
- if (page_action_views_.size() != count_before) {
- NotificationService::current()->Notify(
- NotificationType::EXTENSION_PAGE_ACTION_COUNT_CHANGED,
- Source<LocationBar>(this),
- NotificationService::NoDetails());
- }
-
- Layout();
- SchedulePaint();
-}
-
-void LocationBarView::InvalidatePageActions() {
- size_t count_before = page_action_views_.size();
- DeletePageActionViews();
- if (page_action_views_.size() != count_before) {
- NotificationService::current()->Notify(
- NotificationType::EXTENSION_PAGE_ACTION_COUNT_CHANGED,
- Source<LocationBar>(this),
- NotificationService::NoDetails());
- }
-}
-
-void LocationBarView::Focus() {
- // Focus the location entry native view.
- location_entry_->SetFocus();
-}
-
-void LocationBarView::SetProfile(Profile* profile) {
- DCHECK(profile);
- if (profile_ != profile) {
- profile_ = profile;
- location_entry_->model()->SetProfile(profile);
- selected_keyword_view_.set_profile(profile);
- keyword_hint_view_.set_profile(profile);
- for (ContentSettingViews::const_iterator i(content_setting_views_.begin());
- i != content_setting_views_.end(); ++i)
- (*i)->set_profile(profile);
- }
-}
-
-TabContents* LocationBarView::GetTabContents() const {
- return delegate_->GetTabContents();
-}
-
-void LocationBarView::SetPreviewEnabledPageAction(ExtensionAction* page_action,
- bool preview_enabled) {
- if (popup_window_mode_)
- return;
-
- DCHECK(page_action);
- TabContents* contents = delegate_->GetTabContents();
-
- RefreshPageActionViews();
- PageActionWithBadgeView* page_action_view =
- static_cast<PageActionWithBadgeView*>(GetPageActionView(page_action));
- DCHECK(page_action_view);
- if (!page_action_view)
- return;
-
- page_action_view->image_view()->set_preview_enabled(preview_enabled);
- page_action_view->UpdateVisibility(contents,
- GURL(WideToUTF8(model_->GetText())));
- Layout();
- SchedulePaint();
-}
-
-views::View* LocationBarView::GetPageActionView(
- ExtensionAction *page_action) {
- DCHECK(page_action);
- for (PageActionViews::const_iterator i(page_action_views_.begin());
- i != page_action_views_.end(); ++i) {
- if ((*i)->image_view()->page_action() == page_action)
- return *i;
- }
- return NULL;
-}
-
-void LocationBarView::SetStarToggled(bool on) {
- star_view_.SetToggled(on);
-}
-
-void LocationBarView::ShowStarBubble(const GURL& url, bool newly_bookmarked) {
- gfx::Rect screen_bounds(star_view_.GetImageBounds());
- // Compensate for some built-in padding in the Star image.
- screen_bounds.Inset(1, 1, 1, 2);
- gfx::Point origin(screen_bounds.origin());
- views::View::ConvertPointToScreen(&star_view_, &origin);
- screen_bounds.set_origin(origin);
- browser::ShowBookmarkBubbleView(GetWindow(), screen_bounds, &star_view_,
- profile_, url, newly_bookmarked);
-}
-
-gfx::Size LocationBarView::GetPreferredSize() {
- return gfx::Size(0,
- (popup_window_mode_ ? kPopupBackground : kBackground)->height());
-}
-
-void LocationBarView::Layout() {
- if (!location_entry_.get())
- return;
-
- int entry_width = width() - kViewPadding;
-
- // |location_icon_view_| is visible except when |ev_bubble_view_| or
- // |selected_keyword_view_| are visible.
- int location_icon_width = 0;
- int ev_bubble_width = 0;
- location_icon_view_.SetVisible(false);
- ev_bubble_view_.SetVisible(false);
- const std::wstring keyword(location_entry_->model()->keyword());
- const bool is_keyword_hint(location_entry_->model()->is_keyword_hint());
- const bool show_selected_keyword = !keyword.empty() && !is_keyword_hint;
- if (show_selected_keyword) {
- entry_width -= kViewPadding; // Assume the keyword might be hidden.
- } else if (model_->GetSecurityLevel() == ToolbarModel::EV_SECURE) {
- ev_bubble_view_.SetVisible(true);
- ev_bubble_view_.SetLabel(model_->GetEVCertName());
- ev_bubble_width = ev_bubble_view_.GetPreferredSize().width();
- entry_width -= kBubblePadding + ev_bubble_width + kViewPadding;
- } else {
- location_icon_view_.SetVisible(true);
- location_icon_width = location_icon_view_.GetPreferredSize().width();
- entry_width -=
- kViewPadding + location_icon_width + kLocationIconEditPadding;
- }
-
- entry_width -= star_view_.GetPreferredSize().width() + kViewPadding;
- for (PageActionViews::const_iterator i(page_action_views_.begin());
- i != page_action_views_.end(); ++i) {
- if ((*i)->IsVisible())
- entry_width -= (*i)->GetPreferredSize().width() + kViewPadding;
- }
- for (ContentSettingViews::const_iterator i(content_setting_views_.begin());
- i != content_setting_views_.end(); ++i) {
- if ((*i)->IsVisible())
- entry_width -= (*i)->GetPreferredSize().width() + kViewPadding;
- }
-
-#if defined(OS_WIN)
- RECT formatting_rect;
- location_entry_->GetRect(&formatting_rect);
- RECT edit_bounds;
- location_entry_->GetClientRect(&edit_bounds);
- int max_edit_width = entry_width - formatting_rect.left -
- (edit_bounds.right - formatting_rect.right);
-#else
- int max_edit_width = entry_width;
-#endif
-
- if (max_edit_width < 0)
- return;
- const int available_width = AvailableWidth(max_edit_width);
-
- const bool show_keyword_hint = !keyword.empty() && is_keyword_hint;
- selected_keyword_view_.SetVisible(show_selected_keyword);
- keyword_hint_view_.SetVisible(show_keyword_hint);
- if (show_selected_keyword) {
- if (selected_keyword_view_.keyword() != keyword)
- selected_keyword_view_.SetKeyword(keyword);
- } else if (show_keyword_hint) {
- if (keyword_hint_view_.keyword() != keyword)
- keyword_hint_view_.SetKeyword(keyword);
- }
-
- // TODO(sky): baseline layout.
- int location_y = TopMargin();
- int location_height = std::max(height() - location_y - kVertMargin, 0);
-
- // Lay out items to the right of the edit field.
- int offset = width() - kViewPadding;
- int star_width = star_view_.GetPreferredSize().width();
- offset -= star_width;
- star_view_.SetBounds(offset, location_y, star_width, location_height);
- offset -= kViewPadding;
-
- for (PageActionViews::const_iterator i(page_action_views_.begin());
- i != page_action_views_.end(); ++i) {
- if ((*i)->IsVisible()) {
- int page_action_width = (*i)->GetPreferredSize().width();
- offset -= page_action_width;
- (*i)->SetBounds(offset, location_y, page_action_width, location_height);
- offset -= kViewPadding;
- }
- }
- // We use a reverse_iterator here because we're laying out the views from
- // right to left but in the vector they're ordered left to right.
- for (ContentSettingViews::const_reverse_iterator
- i(content_setting_views_.rbegin()); i != content_setting_views_.rend();
- ++i) {
- if ((*i)->IsVisible()) {
- int content_blocked_width = (*i)->GetPreferredSize().width();
- offset -= content_blocked_width;
- (*i)->SetBounds(offset, location_y, content_blocked_width,
- location_height);
- offset -= kViewPadding;
- }
- }
-
- // Now lay out items to the left of the edit field.
- if (location_icon_view_.IsVisible()) {
- location_icon_view_.SetBounds(kViewPadding, location_y, location_icon_width,
- location_height);
- offset = location_icon_view_.bounds().right() + kLocationIconEditPadding;
- } else if (ev_bubble_view_.IsVisible()) {
- ev_bubble_view_.SetBounds(kBubblePadding, location_y, ev_bubble_width,
- location_height);
- offset = ev_bubble_view_.bounds().right() + kViewPadding;
- } else {
- offset = show_selected_keyword ? kBubblePadding : kViewPadding;
- }
-
- // Now lay out the edit field and views that autocollapse to give it more
- // room.
- gfx::Rect location_bounds(offset, location_y, entry_width, location_height);
- if (show_selected_keyword) {
- LayoutView(true, &selected_keyword_view_, available_width,
- &location_bounds);
- if (!selected_keyword_view_.IsVisible()) {
- location_bounds.set_x(
- location_bounds.x() + kViewPadding - kBubblePadding);
- }
- } else if (show_keyword_hint) {
- LayoutView(false, &keyword_hint_view_, available_width,
- &location_bounds);
- }
-
- location_entry_view_->SetBounds(location_bounds);
-}
-
-void LocationBarView::Paint(gfx::Canvas* canvas) {
- View::Paint(canvas);
-
- const SkBitmap* background =
- popup_window_mode_ ?
- kPopupBackground :
- GetThemeProvider()->GetBitmapNamed(IDR_LOCATIONBG);
-
- canvas->TileImageInt(*background, 0, 0, 0, 0, width(), height());
- int top_margin = TopMargin();
- canvas->FillRectInt(GetColor(ToolbarModel::NONE, BACKGROUND), 0,
- top_margin, width(),
- std::max(height() - top_margin - kVertMargin, 0));
-}
-
-void LocationBarView::VisibleBoundsInRootChanged() {
- location_entry_->ClosePopup();
-}
-
-#if defined(OS_WIN)
-bool LocationBarView::OnMousePressed(const views::MouseEvent& event) {
- UINT msg;
- if (event.IsLeftMouseButton()) {
- msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ?
- WM_LBUTTONDBLCLK : WM_LBUTTONDOWN;
- } else if (event.IsMiddleMouseButton()) {
- msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ?
- WM_MBUTTONDBLCLK : WM_MBUTTONDOWN;
- } else if (event.IsRightMouseButton()) {
- msg = (event.GetFlags() & views::MouseEvent::EF_IS_DOUBLE_CLICK) ?
- WM_RBUTTONDBLCLK : WM_RBUTTONDOWN;
- } else {
- NOTREACHED();
- return false;
- }
- OnMouseEvent(event, msg);
- return true;
-}
-
-bool LocationBarView::OnMouseDragged(const views::MouseEvent& event) {
- OnMouseEvent(event, WM_MOUSEMOVE);
- return true;
-}
-
-void LocationBarView::OnMouseReleased(const views::MouseEvent& event,
- bool canceled) {
- UINT msg;
- if (canceled) {
- msg = WM_CAPTURECHANGED;
- } else if (event.IsLeftMouseButton()) {
- msg = WM_LBUTTONUP;
- } else if (event.IsMiddleMouseButton()) {
- msg = WM_MBUTTONUP;
- } else if (event.IsRightMouseButton()) {
- msg = WM_RBUTTONUP;
- } else {
- NOTREACHED();
- return;
- }
- OnMouseEvent(event, msg);
-}
-#endif
-
-void LocationBarView::OnAutocompleteAccept(
- const GURL& url,
- WindowOpenDisposition disposition,
- PageTransition::Type transition,
- const GURL& alternate_nav_url) {
- if (!url.is_valid())
- return;
-
- location_input_ = UTF8ToWide(url.spec());
- disposition_ = disposition;
- transition_ = transition;
-
- if (command_updater_) {
- if (!alternate_nav_url.is_valid()) {
- command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
- return;
- }
-
- scoped_ptr<AlternateNavURLFetcher> fetcher(
- new AlternateNavURLFetcher(alternate_nav_url));
- // The AlternateNavURLFetcher will listen for the pending navigation
- // notification that will be issued as a result of the "open URL." It
- // will automatically install itself into that navigation controller.
- command_updater_->ExecuteCommand(IDC_OPEN_CURRENT_URL);
- if (fetcher->state() == AlternateNavURLFetcher::NOT_STARTED) {
- // I'm not sure this should be reachable, but I'm not also sure enough
- // that it shouldn't to stick in a NOTREACHED(). In any case, this is
- // harmless; we can simply let the fetcher get deleted here and it will
- // clean itself up properly.
- } else {
- fetcher.release(); // The navigation controller will delete the fetcher.
- }
- }
-}
-
-void LocationBarView::OnChanged() {
- location_icon_view_.SetImage(
- ResourceBundle::GetSharedInstance().GetBitmapNamed(
- location_entry_->GetIcon()));
- Layout();
- SchedulePaint();
-}
-
-void LocationBarView::OnInputInProgress(bool in_progress) {
- delegate_->OnInputInProgress(in_progress);
-}
-
-void LocationBarView::OnKillFocus() {
-}
-
-void LocationBarView::OnSetFocus() {
- views::FocusManager* focus_manager = GetFocusManager();
- if (!focus_manager) {
- NOTREACHED();
- return;
- }
- focus_manager->SetFocusedView(this);
-}
-
-SkBitmap LocationBarView::GetFavIcon() const {
- DCHECK(delegate_);
- DCHECK(delegate_->GetTabContents());
- return delegate_->GetTabContents()->GetFavIcon();
-}
-
-std::wstring LocationBarView::GetTitle() const {
- DCHECK(delegate_);
- DCHECK(delegate_->GetTabContents());
- return UTF16ToWideHack(delegate_->GetTabContents()->GetTitle());
-}
-
-int LocationBarView::TopMargin() const {
- return std::min(kVertMargin, height());
-}
-
-int LocationBarView::AvailableWidth(int location_bar_width) {
-#if defined(OS_WIN)
- // Use font_.GetStringWidth() instead of
- // PosFromChar(location_entry_->GetTextLength()) because PosFromChar() is
- // apparently buggy. In both LTR UI and RTL UI with left-to-right layout,
- // PosFromChar(i) might return 0 when i is greater than 1.
- return std::max(
- location_bar_width - font_.GetStringWidth(location_entry_->GetText()), 0);
-#else
- return location_bar_width - location_entry_->TextWidth();
-#endif
-}
-
-bool LocationBarView::UsePref(int pref_width, int available_width) {
- return (pref_width + kViewPadding <= available_width);
-}
-
-void LocationBarView::LayoutView(bool leading,
- views::View* view,
- int available_width,
- gfx::Rect* bounds) {
- DCHECK(view && bounds);
- gfx::Size view_size = view->GetPreferredSize();
- if (!UsePref(view_size.width(), available_width))
- view_size = view->GetMinimumSize();
- if (view_size.width() + kViewPadding >= bounds->width()) {
- view->SetVisible(false);
- return;
- }
- if (leading) {
- view->SetBounds(bounds->x(), bounds->y(), view_size.width(),
- bounds->height());
- bounds->Offset(view_size.width() + kViewPadding, 0);
- } else {
- view->SetBounds(bounds->right() - view_size.width(), bounds->y(),
- view_size.width(), bounds->height());
- }
- bounds->set_width(bounds->width() - view_size.width() - kViewPadding);
- view->SetVisible(true);
-}
-
-void LocationBarView::RefreshContentSettingViews() {
- const TabContents* tab_contents = delegate_->GetTabContents();
- for (ContentSettingViews::const_iterator i(content_setting_views_.begin());
- i != content_setting_views_.end(); ++i) {
- (*i)->UpdateFromTabContents(
- model_->input_in_progress() ? NULL : tab_contents);
- }
-}
-
-void LocationBarView::DeletePageActionViews() {
- for (PageActionViews::const_iterator i(page_action_views_.begin());
- i != page_action_views_.end(); ++i)
- RemoveChildView(*i);
- STLDeleteElements(&page_action_views_);
-}
-
-void LocationBarView::RefreshPageActionViews() {
- if (popup_window_mode_)
- return;
-
- ExtensionsService* service = profile_->GetExtensionsService();
- if (!service)
- return;
-
- std::map<ExtensionAction*, bool> old_visibility;
- for (PageActionViews::const_iterator i(page_action_views_.begin());
- i != page_action_views_.end(); ++i)
- old_visibility[(*i)->image_view()->page_action()] = (*i)->IsVisible();
-
- // Remember the previous visibility of the page actions so that we can
- // notify when this changes.
- std::vector<ExtensionAction*> page_actions;
- for (size_t i = 0; i < service->extensions()->size(); ++i) {
- if (service->extensions()->at(i)->page_action())
- page_actions.push_back(service->extensions()->at(i)->page_action());
- }
-
- // On startup we sometimes haven't loaded any extensions. This makes sure
- // we catch up when the extensions (and any page actions) load.
- if (page_actions.size() != page_action_views_.size()) {
- DeletePageActionViews(); // Delete the old views (if any).
-
- page_action_views_.resize(page_actions.size());
-
- for (size_t i = 0; i < page_actions.size(); ++i) {
- page_action_views_[i] = new PageActionWithBadgeView(
- new PageActionImageView(this, profile_, page_actions[i]));
- page_action_views_[i]->SetVisible(false);
- AddChildView(page_action_views_[i]);
- }
- }
-
- TabContents* contents = delegate_->GetTabContents();
- if (!page_action_views_.empty() && contents) {
- GURL url = GURL(WideToUTF8(model_->GetText()));
-
- for (PageActionViews::const_iterator i(page_action_views_.begin());
- i != page_action_views_.end(); ++i) {
- (*i)->UpdateVisibility(contents, url);
-
- // Check if the visibility of the action changed and notify if it did.
- ExtensionAction* action = (*i)->image_view()->page_action();
- if (old_visibility.find(action) == old_visibility.end() ||
- old_visibility[action] != (*i)->IsVisible()) {
- NotificationService::current()->Notify(
- NotificationType::EXTENSION_PAGE_ACTION_VISIBILITY_CHANGED,
- Source<ExtensionAction>(action),
- Details<TabContents>(contents));
- }
- }
- }
-}
-
-#if defined(OS_WIN)
-void LocationBarView::OnMouseEvent(const views::MouseEvent& event, UINT msg) {
- UINT flags = 0;
- if (event.IsControlDown())
- flags |= MK_CONTROL;
- if (event.IsShiftDown())
- flags |= MK_SHIFT;
- if (event.IsLeftMouseButton())
- flags |= MK_LBUTTON;
- if (event.IsMiddleMouseButton())
- flags |= MK_MBUTTON;
- if (event.IsRightMouseButton())
- flags |= MK_RBUTTON;
-
- gfx::Point screen_point(event.location());
- ConvertPointToScreen(this, &screen_point);
- location_entry_->HandleExternalMsg(msg, flags, screen_point.ToPOINT());
-}
-#endif
-
-void LocationBarView::ShowFirstRunBubbleInternal(
- FirstRun::BubbleType bubble_type) {
-#if defined(OS_WIN) // First run bubble doesn't make sense for Chrome OS.
- // If the browser is no longer active, let's not show the info bubble, as this
- // would make the browser the active window again.
- if (!location_entry_view_ || !location_entry_view_->GetWidget()->IsActive())
- return;
-
- // Point at the start of the edit control; adjust to look as good as possible.
- const int kXOffset = 1; // Text looks like it actually starts 1 px in.
- const int kYOffset = -4; // Point into the omnibox, not just at its edge.
- gfx::Point origin(location_entry_view_->bounds().x() + kXOffset,
- y() + height() + kYOffset);
- // If the UI layout is RTL, the coordinate system is not transformed and
- // therefore we need to adjust the X coordinate so that bubble appears on the
- // right hand side of the location bar.
- if (UILayoutIsRightToLeft())
- origin.set_x(width() - origin.x());
- views::View::ConvertPointToScreen(this, &origin);
- FirstRunBubble::Show(profile_, GetWindow(), gfx::Rect(origin, gfx::Size()),
- bubble_type);
-#endif
-}
-
-bool LocationBarView::SkipDefaultKeyEventProcessing(const views::KeyEvent& e) {
- if (keyword_hint_view_.IsVisible() &&
- views::FocusManager::IsTabTraversalKeyEvent(e)) {
- // We want to receive tab key events when the hint is showing.
- return true;
- }
-
-#if defined(OS_WIN)
- return location_entry_->SkipDefaultKeyEventProcessing(e);
-#else
- // TODO(jcampan): We need to refactor the code of
- // AutocompleteEditViewWin::SkipDefaultKeyEventProcessing into this class so
- // it can be shared between Windows and Linux.
- // For now, we just override back-space as it is the accelerator for back
- // navigation.
- if (e.GetKeyCode() == base::VKEY_BACK)
- return true;
- return false;
-#endif
-}
-
-bool LocationBarView::GetAccessibleRole(AccessibilityTypes::Role* role) {
- DCHECK(role);
-
- *role = AccessibilityTypes::ROLE_GROUPING;
- return true;
-}
-
-
-void LocationBarView::WriteDragData(views::View* sender,
- const gfx::Point& press_pt,
- OSExchangeData* data) {
- DCHECK(GetDragOperations(sender, press_pt) != DragDropTypes::DRAG_NONE);
-
- TabContents* tab_contents = delegate_->GetTabContents();
- DCHECK(tab_contents);
- drag_utils::SetURLAndDragImage(tab_contents->GetURL(),
- UTF16ToWideHack(tab_contents->GetTitle()),
- tab_contents->GetFavIcon(), data);
-}
-
-int LocationBarView::GetDragOperations(views::View* sender,
- const gfx::Point& p) {
- DCHECK((sender == &location_icon_view_) || (sender == &ev_bubble_view_));
- TabContents* tab_contents = delegate_->GetTabContents();
- return (tab_contents && tab_contents->GetURL().is_valid() &&
- !location_entry()->IsEditingOrEmpty()) ?
- (DragDropTypes::DRAG_COPY | DragDropTypes::DRAG_LINK) :
- DragDropTypes::DRAG_NONE;
-}
-
-bool LocationBarView::CanStartDrag(View* sender,
- const gfx::Point& press_pt,
- const gfx::Point& p) {
- return true;
-}
-
-// ClickHandler ----------------------------------------------------------------
-
-LocationBarView::ClickHandler::ClickHandler(const views::View* owner,
- const LocationBarView* location_bar)
- : owner_(owner),
- location_bar_(location_bar) {
-}
-
-void LocationBarView::ClickHandler::OnMouseReleased(
- const views::MouseEvent& event,
- bool canceled) {
- if (canceled || !owner_->HitTest(event.location()))
- return;
-
- // Do not show page info if the user has been editing the location
- // bar, or the location bar is at the NTP.
- if (location_bar_->location_entry()->IsEditingOrEmpty())
- return;
-
- TabContents* tab = location_bar_->GetTabContents();
- NavigationEntry* nav_entry = tab->controller().GetActiveEntry();
- if (!nav_entry) {
- NOTREACHED();
- return;
- }
- tab->ShowPageInfo(nav_entry->url(), nav_entry->ssl(), true);
-}
-
-// LocationIconView ------------------------------------------------------------
-
-LocationBarView::LocationIconView::LocationIconView(
- const LocationBarView* location_bar)
- : ALLOW_THIS_IN_INITIALIZER_LIST(click_handler_(this, location_bar)) {
-}
-
-LocationBarView::LocationIconView::~LocationIconView() {
-}
-
-bool LocationBarView::LocationIconView::OnMousePressed(
- const views::MouseEvent& event) {
- // We want to show the dialog on mouse release; that is the standard behavior
- // for buttons.
- return true;
-}
-
-void LocationBarView::LocationIconView::OnMouseReleased(
- const views::MouseEvent& event,
- bool canceled) {
- click_handler_.OnMouseReleased(event, canceled);
-}
-
-// IconLabelBubbleView ---------------------------------------------------------
-
-// Amount to offset the image.
-static const int kImageOffset = 1;
-
-// Amount to offset the label from the image.
-static const int kLabelOffset = 3;
-
-// Amount of padding after the label.
-static const int kLabelPadding = 4;
-
-LocationBarView::IconLabelBubbleView::IconLabelBubbleView(
- const int background_images[],
- int contained_image,
- const SkColor& color)
- : background_painter_(background_images) {
- AddChildView(&image_);
- image_.set_parent_owned(false);
- image_.SetImage(
- ResourceBundle::GetSharedInstance().GetBitmapNamed(contained_image));
- AddChildView(&label_);
- label_.set_parent_owned(false);
- label_.SetColor(color);
-}
-
-LocationBarView::IconLabelBubbleView::~IconLabelBubbleView() {
-}
-
-void LocationBarView::IconLabelBubbleView::SetFont(const gfx::Font& font) {
- label_.SetFont(font);
-}
-
-void LocationBarView::IconLabelBubbleView::SetLabel(const std::wstring& label) {
- label_.SetText(label);
-}
-
-void LocationBarView::IconLabelBubbleView::Paint(gfx::Canvas* canvas) {
- int y_offset = (GetParent()->height() - height()) / 2;
- canvas->TranslateInt(0, y_offset);
- background_painter_.Paint(width(), height(), canvas);
- canvas->TranslateInt(0, -y_offset);
-}
-
-gfx::Size LocationBarView::IconLabelBubbleView::GetPreferredSize() {
- gfx::Size size(GetNonLabelSize());
- size.Enlarge(label_.GetPreferredSize().width(), 0);
- return size;
-}
-
-void LocationBarView::IconLabelBubbleView::Layout() {
- image_.SetBounds(kImageOffset, 0, image_.GetPreferredSize().width(),
- height());
- gfx::Size label_size(label_.GetPreferredSize());
- label_.SetBounds(image_.x() + image_.width() + kLabelOffset,
- (height() - label_size.height()) / 2, label_size.width(),
- label_size.height());
-}
-
-gfx::Size LocationBarView::IconLabelBubbleView::GetNonLabelSize() {
- return gfx::Size(kImageOffset + image_.GetPreferredSize().width() +
- kLabelOffset + kLabelPadding, background_painter_.height());
-}
-
-// EVBubbleView ----------------------------------------------------------------
-
-LocationBarView::EVBubbleView::EVBubbleView(const int background_images[],
- int contained_image,
- const SkColor& color,
- const LocationBarView* location_bar)
- : IconLabelBubbleView(background_images, contained_image, color),
- ALLOW_THIS_IN_INITIALIZER_LIST(click_handler_(this, location_bar)) {
-}
-
-LocationBarView::EVBubbleView::~EVBubbleView() {
-}
-
-bool LocationBarView::EVBubbleView::OnMousePressed(
- const views::MouseEvent& event) {
- // We want to show the dialog on mouse release; that is the standard behavior
- // for buttons.
- return true;
-}
-
-void LocationBarView::EVBubbleView::OnMouseReleased(
- const views::MouseEvent& event,
- bool canceled) {
- click_handler_.OnMouseReleased(event, canceled);
-}
-
-// SelectedKeywordView ---------------------------------------------------------
-
-LocationBarView::SelectedKeywordView::SelectedKeywordView(
- const int background_images[],
- int contained_image,
- const SkColor& color,
- Profile* profile)
- : IconLabelBubbleView(background_images, contained_image, color),
- profile_(profile) {
- full_label_.SetVisible(false);
- partial_label_.SetVisible(false);
-}
-
-LocationBarView::SelectedKeywordView::~SelectedKeywordView() {
-}
-
-void LocationBarView::SelectedKeywordView::SetFont(const gfx::Font& font) {
- IconLabelBubbleView::SetFont(font);
- full_label_.SetFont(font);
- partial_label_.SetFont(font);
-}
-
-gfx::Size LocationBarView::SelectedKeywordView::GetPreferredSize() {
- gfx::Size size(GetNonLabelSize());
- size.Enlarge(full_label_.GetPreferredSize().width(), 0);
- return size;
-}
-
-gfx::Size LocationBarView::SelectedKeywordView::GetMinimumSize() {
- gfx::Size size(GetNonLabelSize());
- size.Enlarge(partial_label_.GetMinimumSize().width(), 0);
- return size;
-}
-
-void LocationBarView::SelectedKeywordView::Layout() {
- SetLabel((width() == GetPreferredSize().width()) ?
- full_label_.GetText() : partial_label_.GetText());
- IconLabelBubbleView::Layout();
-}
-
-void LocationBarView::SelectedKeywordView::SetKeyword(
- const std::wstring& keyword) {
- keyword_ = keyword;
- if (keyword.empty())
- return;
- DCHECK(profile_);
- if (!profile_->GetTemplateURLModel())
- return;
-
- const std::wstring short_name = GetKeywordName(profile_, keyword);
- full_label_.SetText(l10n_util::GetStringF(IDS_OMNIBOX_KEYWORD_TEXT,
- short_name));
- const std::wstring min_string = CalculateMinString(short_name);
- partial_label_.SetText(min_string.empty() ?
- full_label_.GetText() :
- l10n_util::GetStringF(IDS_OMNIBOX_KEYWORD_TEXT, min_string));
-}
-
-std::wstring LocationBarView::SelectedKeywordView::CalculateMinString(
- const std::wstring& description) {
- // Chop at the first '.' or whitespace.
- const size_t dot_index = description.find(L'.');
- const size_t ws_index = description.find_first_of(kWhitespaceWide);
- size_t chop_index = std::min(dot_index, ws_index);
- std::wstring min_string;
- if (chop_index == std::wstring::npos) {
- // No dot or whitespace, truncate to at most 3 chars.
- min_string = l10n_util::TruncateString(description, 3);
- } else {
- min_string = description.substr(0, chop_index);
- }
- base::i18n::AdjustStringForLocaleDirection(min_string, &min_string);
- return min_string;
-}
-
-// KeywordHintView -------------------------------------------------------------
-
-// Amount of space to offset the tab image from the top of the view by.
-static const int kTabImageYOffset = 4;
-
-LocationBarView::KeywordHintView::KeywordHintView(Profile* profile)
- : profile_(profile) {
- AddChildView(&leading_label_);
- AddChildView(&trailing_label_);
-
- if (!kTabButtonBitmap) {
- kTabButtonBitmap = ResourceBundle::GetSharedInstance().
- GetBitmapNamed(IDR_LOCATION_BAR_KEYWORD_HINT_TAB);
- }
-}
-
-LocationBarView::KeywordHintView::~KeywordHintView() {
- // Labels are freed by us. Remove them so that View doesn't
- // try to free them too.
- RemoveChildView(&leading_label_);
- RemoveChildView(&trailing_label_);
-}
-
-void LocationBarView::KeywordHintView::SetFont(const gfx::Font& font) {
- leading_label_.SetFont(font);
- trailing_label_.SetFont(font);
-}
-
-void LocationBarView::KeywordHintView::SetColor(const SkColor& color) {
- leading_label_.SetColor(color);
- trailing_label_.SetColor(color);
-}
-
-void LocationBarView::KeywordHintView::SetKeyword(const std::wstring& keyword) {
- keyword_ = keyword;
- if (keyword_.empty())
- return;
- DCHECK(profile_);
- if (!profile_->GetTemplateURLModel())
- return;
-
- std::vector<size_t> content_param_offsets;
- const std::wstring keyword_hint(l10n_util::GetStringF(
- IDS_OMNIBOX_KEYWORD_HINT, std::wstring(),
- GetKeywordName(profile_, keyword), &content_param_offsets));
- if (content_param_offsets.size() == 2) {
- leading_label_.SetText(keyword_hint.substr(0,
- content_param_offsets.front()));
- trailing_label_.SetText(keyword_hint.substr(content_param_offsets.front()));
- } else {
- // See comments on an identical NOTREACHED() in search_provider.cc.
- NOTREACHED();
- }
-}
-
-void LocationBarView::KeywordHintView::Paint(gfx::Canvas* canvas) {
- int image_x = leading_label_.IsVisible() ? leading_label_.width() : 0;
-
- // Since we paint the button image directly on the canvas (instead of using a
- // child view), we must mirror the button's position manually if the locale
- // is right-to-left.
- gfx::Rect tab_button_bounds(image_x,
- kTabImageYOffset,
- kTabButtonBitmap->width(),
- kTabButtonBitmap->height());
- tab_button_bounds.set_x(MirroredLeftPointForRect(tab_button_bounds));
- canvas->DrawBitmapInt(*kTabButtonBitmap,
- tab_button_bounds.x(),
- tab_button_bounds.y());
-}
-
-gfx::Size LocationBarView::KeywordHintView::GetPreferredSize() {
- // TODO(sky): currently height doesn't matter, once baseline support is
- // added this should check baselines.
- gfx::Size prefsize = leading_label_.GetPreferredSize();
- int width = prefsize.width();
- width += kTabButtonBitmap->width();
- prefsize = trailing_label_.GetPreferredSize();
- width += prefsize.width();
- return gfx::Size(width, prefsize.height());
-}
-
-gfx::Size LocationBarView::KeywordHintView::GetMinimumSize() {
- // TODO(sky): currently height doesn't matter, once baseline support is
- // added this should check baselines.
- return gfx::Size(kTabButtonBitmap->width(), 0);
-}
-
-void LocationBarView::KeywordHintView::Layout() {
- // TODO(sky): baseline layout.
- bool show_labels = (width() != kTabButtonBitmap->width());
-
- leading_label_.SetVisible(show_labels);
- trailing_label_.SetVisible(show_labels);
- int x = 0;
- gfx::Size pref;
-
- if (show_labels) {
- pref = leading_label_.GetPreferredSize();
- leading_label_.SetBounds(x, 0, pref.width(), height());
-
- x += pref.width() + kTabButtonBitmap->width();
- pref = trailing_label_.GetPreferredSize();
- trailing_label_.SetBounds(x, 0, pref.width(), height());
- }
-}
-
-// ContentSettingImageView------------------------------------------------------
-
-LocationBarView::ContentSettingImageView::ContentSettingImageView(
- ContentSettingsType content_type,
- const LocationBarView* parent,
- Profile* profile)
- : content_setting_image_model_(
- ContentSettingImageModel::CreateContentSettingImageModel(
- content_type)),
- parent_(parent),
- profile_(profile),
- info_bubble_(NULL) {
-}
-
-LocationBarView::ContentSettingImageView::~ContentSettingImageView() {
- if (info_bubble_)
- info_bubble_->Close();
-}
-
-void LocationBarView::ContentSettingImageView::UpdateFromTabContents(
- const TabContents* tab_contents) {
- int old_icon = content_setting_image_model_->get_icon();
- content_setting_image_model_->UpdateFromTabContents(tab_contents);
- if (!content_setting_image_model_->is_visible()) {
- SetVisible(false);
- return;
- }
- if (old_icon != content_setting_image_model_->get_icon()) {
- SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed(
- content_setting_image_model_->get_icon()));
- }
- SetTooltipText(UTF8ToWide(content_setting_image_model_->get_tooltip()));
- SetVisible(true);
-}
-
-bool LocationBarView::ContentSettingImageView::OnMousePressed(
- const views::MouseEvent& event) {
- // We want to show the bubble on mouse release; that is the standard behavior
- // for buttons.
- return true;
-}
-
-void LocationBarView::ContentSettingImageView::OnMouseReleased(
- const views::MouseEvent& event,
- bool canceled) {
- if (canceled || !HitTest(event.location()))
- return;
-
- TabContents* tab_contents = parent_->GetTabContents();
- if (!tab_contents)
- return;
-
- gfx::Rect screen_bounds(GetImageBounds());
- gfx::Point origin(screen_bounds.origin());
- views::View::ConvertPointToScreen(this, &origin);
- screen_bounds.set_origin(origin);
- ContentSettingBubbleContents* bubble_contents =
- new ContentSettingBubbleContents(
- ContentSettingBubbleModel::CreateContentSettingBubbleModel(
- tab_contents, profile_,
- content_setting_image_model_->get_content_settings_type()),
- profile_, tab_contents);
- DCHECK(!info_bubble_);
- info_bubble_ =
- InfoBubble::Show(GetWindow(), screen_bounds, bubble_contents, this);
- bubble_contents->set_info_bubble(info_bubble_);
-}
-
-void LocationBarView::ContentSettingImageView::VisibilityChanged(
- View* starting_from,
- bool is_visible) {
- if (!is_visible && info_bubble_)
- info_bubble_->Close();
-}
-
-void LocationBarView::ContentSettingImageView::InfoBubbleClosing(
- InfoBubble* info_bubble,
- bool closed_by_escape) {
- info_bubble_ = NULL;
-}
-
-bool LocationBarView::ContentSettingImageView::CloseOnEscape() {
- return true;
-}
-
-// PageActionImageView----------------------------------------------------------
-
-LocationBarView::PageActionImageView::PageActionImageView(
- LocationBarView* owner,
- Profile* profile,
- ExtensionAction* page_action)
- : owner_(owner),
- profile_(profile),
- page_action_(page_action),
- ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)),
- current_tab_id_(-1),
- preview_enabled_(false),
- popup_(NULL) {
- Extension* extension = profile->GetExtensionsService()->GetExtensionById(
- page_action->extension_id(), false);
- DCHECK(extension);
-
- // Load all the icons declared in the manifest. This is the contents of the
- // icons array, plus the default_icon property, if any.
- std::vector<std::string> icon_paths(*page_action->icon_paths());
- if (!page_action_->default_icon_path().empty())
- icon_paths.push_back(page_action_->default_icon_path());
-
- for (std::vector<std::string>::iterator iter = icon_paths.begin();
- iter != icon_paths.end(); ++iter) {
- tracker_.LoadImage(extension, extension->GetResource(*iter),
- gfx::Size(Extension::kPageActionIconMaxSize,
- Extension::kPageActionIconMaxSize),
- ImageLoadingTracker::DONT_CACHE);
- }
-}
-
-LocationBarView::PageActionImageView::~PageActionImageView() {
- if (popup_)
- HidePopup();
-}
-
-void LocationBarView::PageActionImageView::ExecuteAction(int button,
- bool inspect_with_devtools) {
- if (current_tab_id_ < 0) {
- NOTREACHED() << "No current tab.";
- return;
- }
-
- if (page_action_->HasPopup(current_tab_id_)) {
- // In tests, GetLastActive could return NULL, so we need to have
- // a fallback.
- // TODO(erikkay): Find a better way to get the Browser that this
- // button is in.
- Browser* browser = BrowserList::GetLastActiveWithProfile(profile_);
- if (!browser)
- browser = BrowserList::FindBrowserWithProfile(profile_);
- DCHECK(browser);
-
- bool popup_showing = popup_ != NULL;
-
- // Always hide the current popup. Only one popup at a time.
- HidePopup();
-
- // If we were already showing, then treat this click as a dismiss.
- if (popup_showing)
- return;
-
- gfx::Rect screen_bounds(GetImageBounds());
- gfx::Point origin(screen_bounds.origin());
- View::ConvertPointToScreen(this, &origin);
- screen_bounds.set_origin(origin);
-
- popup_ = ExtensionPopup::Show(
- page_action_->GetPopupUrl(current_tab_id_),
- browser,
- browser->profile(),
- browser->window()->GetNativeHandle(),
- screen_bounds,
- BubbleBorder::TOP_RIGHT,
- true, // Activate the popup window.
- inspect_with_devtools,
- ExtensionPopup::BUBBLE_CHROME,
- this); // ExtensionPopup::Observer
- } else {
- ExtensionBrowserEventRouter::GetInstance()->PageActionExecuted(
- profile_, page_action_->extension_id(), page_action_->id(),
- current_tab_id_, current_url_.spec(), button);
- }
-}
-
-bool LocationBarView::PageActionImageView::OnMousePressed(
- const views::MouseEvent& event) {
- // We want to show the bubble on mouse release; that is the standard behavior
- // for buttons. (Also, triggering on mouse press causes bugs like
- // http://crbug.com/33155.)
- return true;
-}
-
-void LocationBarView::PageActionImageView::OnMouseReleased(
- const views::MouseEvent& event, bool canceled) {
- if (canceled || !HitTest(event.location()))
- return;
-
- int button = -1;
- if (event.IsLeftMouseButton()) {
- button = 1;
- } else if (event.IsMiddleMouseButton()) {
- button = 2;
- } else if (event.IsRightMouseButton()) {
- // Get the top left point of this button in screen coordinates.
- gfx::Point menu_origin;
- ConvertPointToScreen(this, &menu_origin);
-
- // Make the menu appear below the button.
- menu_origin.Offset(0, height());
-
- Extension* extension = profile_->GetExtensionsService()->GetExtensionById(
- page_action()->extension_id(), false);
- Browser* browser = BrowserView::GetBrowserViewForNativeWindow(
- platform_util::GetTopLevel(GetWidget()->GetNativeView()))->browser();
- context_menu_contents_ =
- new ExtensionContextMenuModel(extension, browser, this);
- context_menu_menu_.reset(new views::Menu2(context_menu_contents_.get()));
- context_menu_menu_->RunContextMenuAt(menu_origin);
- return;
- }
-
- ExecuteAction(button, false); // inspect_with_devtools
-}
-
-void LocationBarView::PageActionImageView::OnImageLoaded(
- SkBitmap* image, ExtensionResource resource, int index) {
- // We loaded icons()->size() icons, plus one extra if the page action had
- // a default icon.
- int total_icons = static_cast<int>(page_action_->icon_paths()->size());
- if (!page_action_->default_icon_path().empty())
- total_icons++;
- DCHECK(index < total_icons);
-
- // Map the index of the loaded image back to its name. If we ever get an
- // index greater than the number of icons, it must be the default icon.
- if (image) {
- if (index < static_cast<int>(page_action_->icon_paths()->size()))
- page_action_icons_[page_action_->icon_paths()->at(index)] = *image;
- else
- page_action_icons_[page_action_->default_icon_path()] = *image;
- }
-
- owner_->UpdatePageActions();
-}
-
-void LocationBarView::PageActionImageView::UpdateVisibility(
- TabContents* contents, const GURL& url) {
- // Save this off so we can pass it back to the extension when the action gets
- // executed. See PageActionImageView::OnMousePressed.
- current_tab_id_ = ExtensionTabUtil::GetTabId(contents);
- current_url_ = url;
-
- bool visible =
- preview_enabled_ || page_action_->GetIsVisible(current_tab_id_);
- if (visible) {
- // Set the tooltip.
- tooltip_ = page_action_->GetTitle(current_tab_id_);
- SetTooltipText(UTF8ToWide(tooltip_));
-
- // Set the image.
- // It can come from three places. In descending order of priority:
- // - The developer can set it dynamically by path or bitmap. It will be in
- // page_action_->GetIcon().
- // - The developer can set it dynamically by index. It will be in
- // page_action_->GetIconIndex().
- // - It can be set in the manifest by path. It will be in page_action_->
- // default_icon_path().
-
- // First look for a dynamically set bitmap.
- SkBitmap icon = page_action_->GetIcon(current_tab_id_);
- if (icon.isNull()) {
- int icon_index = page_action_->GetIconIndex(current_tab_id_);
- std::string icon_path;
- if (icon_index >= 0)
- icon_path = page_action_->icon_paths()->at(icon_index);
- else
- icon_path = page_action_->default_icon_path();
-
- if (!icon_path.empty()) {
- PageActionMap::iterator iter = page_action_icons_.find(icon_path);
- if (iter != page_action_icons_.end())
- icon = iter->second;
- }
- }
-
- if (!icon.isNull())
- SetImage(&icon);
- }
- SetVisible(visible);
-}
-
-void LocationBarView::PageActionImageView::InspectPopup(
- ExtensionAction* action) {
- ExecuteAction(1, // left-click
- true); // inspect_with_devtools
-}
-
-void LocationBarView::PageActionImageView::ExtensionPopupClosed(
- ExtensionPopup* popup) {
- DCHECK_EQ(popup_, popup);
- // ExtensionPopup is ref-counted, so we don't need to delete it.
- popup_ = NULL;
-}
-
-void LocationBarView::PageActionImageView::HidePopup() {
- if (popup_)
- popup_->Close();
-}
-
-// StarView---------------------------------------------------------------------
-
-LocationBarView::StarView::StarView(CommandUpdater* command_updater)
- : command_updater_(command_updater) {
- SetID(VIEW_ID_STAR_BUTTON);
- SetToggled(false);
-}
-
-LocationBarView::StarView::~StarView() {
-}
-
-void LocationBarView::StarView::SetToggled(bool on) {
- SetTooltipText(l10n_util::GetString(
- on ? IDS_TOOLTIP_STARRED : IDS_TOOLTIP_STAR));
- // Since StarView is an ImageView, the SetTooltipText changes the accessible
- // name. To keep the accessible name unchanged, we need to set the accessible
- // name right after we modify the tooltip text for this view.
- SetAccessibleName(l10n_util::GetString(IDS_ACCNAME_STAR));
- SetImage(ResourceBundle::GetSharedInstance().GetBitmapNamed(
- on ? IDR_OMNIBOX_STAR_LIT : IDR_OMNIBOX_STAR));
-}
-
-bool LocationBarView::StarView::GetAccessibleRole(
- AccessibilityTypes::Role* role) {
- *role = AccessibilityTypes::ROLE_PUSHBUTTON;
- return true;
-}
-
-bool LocationBarView::StarView::OnMousePressed(const views::MouseEvent& event) {
- // We want to show the bubble on mouse release; that is the standard behavior
- // for buttons.
- return true;
-}
-
-void LocationBarView::StarView::OnMouseReleased(const views::MouseEvent& event,
- bool canceled) {
- if (!canceled && HitTest(event.location()))
- command_updater_->ExecuteCommand(IDC_BOOKMARK_PAGE);
-}
-
-void LocationBarView::StarView::InfoBubbleClosing(InfoBubble* info_bubble,
- bool closed_by_escape) {
-}
-
-bool LocationBarView::StarView::CloseOnEscape() {
- return true;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// LocationBarView, LocationBar implementation:
-
-void LocationBarView::ShowFirstRunBubble(FirstRun::BubbleType bubble_type) {
- // We wait 30 milliseconds to open. It allows less flicker.
- Task* task = first_run_bubble_.NewRunnableMethod(
- &LocationBarView::ShowFirstRunBubbleInternal, bubble_type);
- MessageLoop::current()->PostDelayedTask(FROM_HERE, task, 30);
-}
-
-std::wstring LocationBarView::GetInputString() const {
- return location_input_;
-}
-
-WindowOpenDisposition LocationBarView::GetWindowOpenDisposition() const {
- return disposition_;
-}
-
-PageTransition::Type LocationBarView::GetPageTransition() const {
- return transition_;
-}
-
-void LocationBarView::AcceptInput() {
- location_entry_->model()->AcceptInput(CURRENT_TAB, false);
-}
-
-void LocationBarView::AcceptInputWithDisposition(WindowOpenDisposition disp) {
- location_entry_->model()->AcceptInput(disp, false);
-}
-
-void LocationBarView::FocusLocation(bool select_all) {
- location_entry_->SetFocus();
- if (select_all)
- location_entry_->SelectAll(true);
-}
-
-void LocationBarView::FocusSearch() {
- location_entry_->SetFocus();
- location_entry_->SetForcedQuery();
-}
-
-void LocationBarView::SaveStateToContents(TabContents* contents) {
- location_entry_->SaveStateToTab(contents);
-}
-
-void LocationBarView::Revert() {
- location_entry_->RevertAll();
-}
-
-int LocationBarView::PageActionVisibleCount() {
- int result = 0;
- for (size_t i = 0; i < page_action_views_.size(); i++) {
- if (page_action_views_[i]->IsVisible())
- ++result;
- }
- return result;
-}
-
-ExtensionAction* LocationBarView::GetPageAction(size_t index) {
- if (index < page_action_views_.size())
- return page_action_views_[index]->image_view()->page_action();
-
- NOTREACHED();
- return NULL;
-}
-
-ExtensionAction* LocationBarView::GetVisiblePageAction(size_t index) {
- size_t current = 0;
- for (size_t i = 0; i < page_action_views_.size(); ++i) {
- if (page_action_views_[i]->IsVisible()) {
- if (current == index)
- return page_action_views_[i]->image_view()->page_action();
-
- ++current;
- }
- }
-
- NOTREACHED();
- return NULL;
-}
-
-void LocationBarView::TestPageActionPressed(size_t index) {
- size_t current = 0;
- for (size_t i = 0; i < page_action_views_.size(); ++i) {
- if (page_action_views_[i]->IsVisible()) {
- if (current == index) {
- const int kLeftMouseButton = 1;
- page_action_views_[i]->image_view()->ExecuteAction(kLeftMouseButton,
- false); // inspect_with_devtools
- return;
- }
- ++current;
- }
- }
-
- NOTREACHED();
-}
diff --git a/chrome/browser/views/location_bar_view.h b/chrome/browser/views/location_bar_view.h
deleted file mode 100644
index 91e1e89..0000000
--- a/chrome/browser/views/location_bar_view.h
+++ /dev/null
@@ -1,645 +0,0 @@
-// 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_VIEWS_LOCATION_BAR_VIEW_H_
-#define CHROME_BROWSER_VIEWS_LOCATION_BAR_VIEW_H_
-
-#include <string>
-#include <map>
-#include <vector>
-
-#include "base/task.h"
-#include "chrome/browser/autocomplete/autocomplete_edit.h"
-#include "chrome/browser/extensions/extension_context_menu_model.h"
-#include "chrome/browser/extensions/image_loading_tracker.h"
-#include "chrome/browser/first_run.h"
-#include "chrome/browser/location_bar.h"
-#include "chrome/browser/tab_contents/tab_contents.h"
-#include "chrome/browser/toolbar_model.h"
-#include "chrome/browser/views/browser_bubble.h"
-#include "chrome/browser/views/extensions/extension_popup.h"
-#include "chrome/browser/views/info_bubble.h"
-#include "chrome/common/content_settings_types.h"
-#include "chrome/common/notification_observer.h"
-#include "chrome/common/notification_registrar.h"
-#include "gfx/font.h"
-#include "gfx/rect.h"
-#include "views/controls/image_view.h"
-#include "views/controls/label.h"
-#include "views/controls/menu/menu_2.h"
-#include "views/controls/native/native_view_host.h"
-#include "views/painter.h"
-
-#if defined(OS_WIN)
-#include "chrome/browser/autocomplete/autocomplete_edit_view_win.h"
-#else
-#include "chrome/browser/autocomplete/autocomplete_edit_view_gtk.h"
-#endif
-
-class Browser;
-class CommandUpdater;
-class ContentSettingImageModel;
-class ExtensionAction;
-class ExtensionPopup;
-class GURL;
-class Profile;
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// LocationBarView class
-//
-// The LocationBarView class is a View subclass that paints the background
-// of the URL bar strip and contains its content.
-//
-/////////////////////////////////////////////////////////////////////////////
-class LocationBarView : public LocationBar,
- public LocationBarTesting,
- public views::View,
- public views::DragController,
- public AutocompleteEditController {
- public:
- class Delegate {
- public:
- // Should return the current tab contents.
- virtual TabContents* GetTabContents() = 0;
-
- // Called by the location bar view when the user starts typing in the edit.
- // This forces our security style to be UNKNOWN for the duration of the
- // editing.
- virtual void OnInputInProgress(bool in_progress) = 0;
- };
-
- enum ColorKind {
- BACKGROUND = 0,
- TEXT,
- SELECTED_TEXT,
- DEEMPHASIZED_TEXT,
- SECURITY_TEXT,
- };
-
- LocationBarView(Profile* profile,
- CommandUpdater* command_updater,
- ToolbarModel* model,
- Delegate* delegate,
- bool popup_window_mode);
- virtual ~LocationBarView();
-
- void Init();
-
- // Returns whether this instance has been initialized by callin Init. Init can
- // only be called when the receiving instance is attached to a view container.
- bool IsInitialized() const;
-
- // Returns the appropriate color for the desired kind, based on the user's
- // system theme.
- static SkColor GetColor(ToolbarModel::SecurityLevel security_level,
- ColorKind kind);
-
- // Updates the location bar. We also reset the bar's permanent text and
- // security style, and, if |tab_for_state_restoring| is non-NULL, also restore
- // saved state that the tab holds.
- void Update(const TabContents* tab_for_state_restoring);
-
- void SetProfile(Profile* profile);
- Profile* profile() const { return profile_; }
-
- // Returns the current TabContents.
- TabContents* GetTabContents() const;
-
- // Sets |preview_enabled| for the PageAction View associated with this
- // |page_action|. If |preview_enabled| is true, the view will display the
- // PageActions icon even though it has not been activated by the extension.
- // This is used by the ExtensionInstalledBubble to preview what the icon
- // will look like for the user upon installation of the extension.
- void SetPreviewEnabledPageAction(ExtensionAction *page_action,
- bool preview_enabled);
-
- // Retrieves the PageAction View which is associated with |page_action|.
- views::View* GetPageActionView(ExtensionAction* page_action);
-
- // Toggles the star on or off.
- void SetStarToggled(bool on);
-
- // Shows the bookmark bubble.
- void ShowStarBubble(const GURL& url, bool newly_bookmarked);
-
- // Sizing functions
- virtual gfx::Size GetPreferredSize();
-
- // Layout and Painting functions
- virtual void Layout();
- virtual void Paint(gfx::Canvas* canvas);
-
- // No focus border for the location bar, the caret is enough.
- virtual void PaintFocusBorder(gfx::Canvas* canvas) { }
-
- // Called when any ancestor changes its size, asks the AutocompleteEditModel
- // to close its popup.
- virtual void VisibleBoundsInRootChanged();
-
-#if defined(OS_WIN)
- // Event Handlers
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual bool OnMouseDragged(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
-#endif
-
- // AutocompleteEditController
- virtual void OnAutocompleteAccept(const GURL& url,
- WindowOpenDisposition disposition,
- PageTransition::Type transition,
- const GURL& alternate_nav_url);
- virtual void OnChanged();
- virtual void OnInputInProgress(bool in_progress);
- virtual void OnKillFocus();
- virtual void OnSetFocus();
- virtual SkBitmap GetFavIcon() const;
- virtual std::wstring GetTitle() const;
-
- // Overridden from views::View:
- virtual bool SkipDefaultKeyEventProcessing(const views::KeyEvent& e);
- virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
-
- // Overridden from views::DragController:
- virtual void WriteDragData(View* sender,
- const gfx::Point& press_pt,
- OSExchangeData* data);
- virtual int GetDragOperations(View* sender, const gfx::Point& p);
- virtual bool CanStartDrag(View* sender,
- const gfx::Point& press_pt,
- const gfx::Point& p);
-
- // Overridden from LocationBar:
- virtual void ShowFirstRunBubble(FirstRun::BubbleType bubble_type);
- virtual std::wstring GetInputString() const;
- virtual WindowOpenDisposition GetWindowOpenDisposition() const;
- virtual PageTransition::Type GetPageTransition() const;
- virtual void AcceptInput();
- virtual void AcceptInputWithDisposition(WindowOpenDisposition);
- virtual void FocusLocation(bool select_all);
- virtual void FocusSearch();
- virtual void UpdateContentSettingsIcons();
- virtual void UpdatePageActions();
- virtual void InvalidatePageActions();
- virtual void SaveStateToContents(TabContents* contents);
- virtual void Revert();
- virtual const AutocompleteEditView* location_entry() const {
- return location_entry_.get();
- }
- virtual AutocompleteEditView* location_entry() {
- return location_entry_.get();
- }
- virtual LocationBarTesting* GetLocationBarForTesting() { return this; }
-
- // Overridden from LocationBarTesting:
- virtual int PageActionCount() { return page_action_views_.size(); }
- virtual int PageActionVisibleCount();
- virtual ExtensionAction* GetPageAction(size_t index);
- virtual ExtensionAction* GetVisiblePageAction(size_t index);
- virtual void TestPageActionPressed(size_t index);
-
- static const int kVertMargin;
-
- protected:
- void Focus();
-
- private:
- // This helper class is kept as a member by classes that need to show the Page
- // Info dialog on click, to encapsulate that logic in one place.
- class ClickHandler {
- public:
- explicit ClickHandler(const views::View* owner,
- const LocationBarView* location_bar);
-
- void OnMouseReleased(const views::MouseEvent& event, bool canceled);
-
- private:
- const views::View* owner_;
- const LocationBarView* location_bar_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(ClickHandler);
- };
-
- // LocationIconView is used to display an icon to the left of the edit field.
- // This shows the user's current action while editing, the page security
- // status on https pages, or a globe for other URLs.
- class LocationIconView : public views::ImageView {
- public:
- explicit LocationIconView(const LocationBarView* location_bar);
- virtual ~LocationIconView();
-
- // Overridden from view.
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
-
- private:
- ClickHandler click_handler_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(LocationIconView);
- };
-
- // View used to draw a bubble to the left of the address, containing an icon
- // and a label. We use this as a base for the classes that handle the EV
- // bubble and tab-to-search UI.
- class IconLabelBubbleView : public views::View {
- public:
- IconLabelBubbleView(const int background_images[],
- int contained_image,
- const SkColor& color);
- virtual ~IconLabelBubbleView();
-
- void SetFont(const gfx::Font& font);
- void SetLabel(const std::wstring& label);
-
- virtual void Paint(gfx::Canvas* canvas);
- virtual gfx::Size GetPreferredSize();
- virtual void Layout();
-
- protected:
- gfx::Size GetNonLabelSize();
-
- private:
- // For painting the background.
- views::HorizontalPainter background_painter_;
-
- // The contents of the bubble.
- views::ImageView image_;
- views::Label label_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(IconLabelBubbleView);
- };
-
- // EVBubbleView displays the EV Bubble.
- class EVBubbleView : public IconLabelBubbleView {
- public:
- EVBubbleView(const int background_images[],
- int contained_image,
- const SkColor& color,
- const LocationBarView* location_bar);
- virtual ~EVBubbleView();
-
- // Overridden from view.
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
-
- private:
- ClickHandler click_handler_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(EVBubbleView);
- };
-
- // SelectedKeywordView displays the tab-to-search UI.
- class SelectedKeywordView : public IconLabelBubbleView {
- public:
- SelectedKeywordView(const int background_images[],
- int contained_image,
- const SkColor& color,
- Profile* profile);
- virtual ~SelectedKeywordView();
-
- void SetFont(const gfx::Font& font);
-
- virtual gfx::Size GetPreferredSize();
- virtual gfx::Size GetMinimumSize();
- virtual void Layout();
-
- // The current keyword, or an empty string if no keyword is displayed.
- void SetKeyword(const std::wstring& keyword);
- std::wstring keyword() const { return keyword_; }
-
- void set_profile(Profile* profile) { profile_ = profile; }
-
- private:
- // Returns the truncated version of description to use.
- std::wstring CalculateMinString(const std::wstring& description);
-
- // The keyword we're showing. If empty, no keyword is selected.
- // NOTE: we don't cache the TemplateURL as it is possible for it to get
- // deleted out from under us.
- std::wstring keyword_;
-
- // These labels are never visible. They are used to size the view. One
- // label contains the complete description of the keyword, the second
- // contains a truncated version of the description, for if there is not
- // enough room to display the complete description.
- views::Label full_label_;
- views::Label partial_label_;
-
- Profile* profile_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(SelectedKeywordView);
- };
-
- // KeywordHintView is used to display a hint to the user when the selected
- // url has a corresponding keyword.
- //
- // Internally KeywordHintView uses two labels to render the text, and draws
- // the tab image itself.
- //
- // NOTE: This should really be called LocationBarKeywordHintView, but I
- // couldn't bring myself to use such a long name.
- class KeywordHintView : public views::View {
- public:
- explicit KeywordHintView(Profile* profile);
- virtual ~KeywordHintView();
-
- void SetFont(const gfx::Font& font);
-
- void SetColor(const SkColor& color);
-
- void SetKeyword(const std::wstring& keyword);
- std::wstring keyword() const { return keyword_; }
-
- virtual void Paint(gfx::Canvas* canvas);
- virtual gfx::Size GetPreferredSize();
- // The minimum size is just big enough to show the tab.
- virtual gfx::Size GetMinimumSize();
- virtual void Layout();
-
- void set_profile(Profile* profile) { profile_ = profile; }
-
- private:
- views::Label leading_label_;
- views::Label trailing_label_;
-
- // The keyword.
- std::wstring keyword_;
-
- Profile* profile_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(KeywordHintView);
- };
-
- class ContentSettingImageView : public views::ImageView,
- public InfoBubbleDelegate {
- public:
- ContentSettingImageView(ContentSettingsType content_type,
- const LocationBarView* parent,
- Profile* profile);
- virtual ~ContentSettingImageView();
-
- void set_profile(Profile* profile) { profile_ = profile; }
- void UpdateFromTabContents(const TabContents* tab_contents);
-
- private:
- // views::ImageView overrides:
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
- virtual void VisibilityChanged(View* starting_from, bool is_visible);
-
- // InfoBubbleDelegate overrides:
- virtual void InfoBubbleClosing(InfoBubble* info_bubble,
- bool closed_by_escape);
- virtual bool CloseOnEscape();
-
- scoped_ptr<ContentSettingImageModel> content_setting_image_model_;
-
- // The owning LocationBarView.
- const LocationBarView* parent_;
-
- // The currently active profile.
- Profile* profile_;
-
- // The currently shown info bubble if any.
- InfoBubble* info_bubble_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(ContentSettingImageView);
- };
- typedef std::vector<ContentSettingImageView*> ContentSettingViews;
-
- // PageActionImageView is used to display the icon for a given PageAction
- // and notify the extension when the icon is clicked.
- class PageActionImageView : public views::ImageView,
- public ImageLoadingTracker::Observer,
- public ExtensionContextMenuModel::PopupDelegate,
- public ExtensionPopup::Observer {
- public:
- PageActionImageView(LocationBarView* owner,
- Profile* profile,
- ExtensionAction* page_action);
- virtual ~PageActionImageView();
-
- ExtensionAction* page_action() { return page_action_; }
-
- int current_tab_id() { return current_tab_id_; }
-
- void set_preview_enabled(bool preview_enabled) {
- preview_enabled_ = preview_enabled;
- }
-
- // Overridden from view.
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
-
- // Overridden from ImageLoadingTracker.
- virtual void OnImageLoaded(
- SkBitmap* image, ExtensionResource resource, int index);
-
- // Overridden from ExtensionContextMenuModelModel::Delegate
- virtual void InspectPopup(ExtensionAction* action);
-
- // Overridden from ExtensionPopup::Observer
- virtual void ExtensionPopupClosed(ExtensionPopup* popup);
-
- // Called to notify the PageAction that it should determine whether to be
- // visible or hidden. |contents| is the TabContents that is active, |url|
- // is the current page URL.
- void UpdateVisibility(TabContents* contents, const GURL& url);
-
- // Either notify listeners or show a popup depending on the page action.
- void ExecuteAction(int button, bool inspect_with_devtools);
-
- private:
- // Hides the active popup, if there is one.
- void HidePopup();
-
- // The location bar view that owns us.
- LocationBarView* owner_;
-
- // The current profile (not owned by us).
- Profile* profile_;
-
- // The PageAction that this view represents. The PageAction is not owned by
- // us, it resides in the extension of this particular profile.
- ExtensionAction* page_action_;
-
- // A cache of bitmaps the page actions might need to show, mapped by path.
- typedef std::map<std::string, SkBitmap> PageActionMap;
- PageActionMap page_action_icons_;
-
- // The context menu for this page action.
- scoped_refptr<ExtensionContextMenuModel> context_menu_contents_;
- scoped_ptr<views::Menu2> context_menu_menu_;
-
- // The object that is waiting for the image loading to complete
- // asynchronously.
- ImageLoadingTracker tracker_;
-
- // The tab id we are currently showing the icon for.
- int current_tab_id_;
-
- // The URL we are currently showing the icon for.
- GURL current_url_;
-
- // The string to show for a tooltip;
- std::string tooltip_;
-
- // This is used for post-install visual feedback. The page_action icon
- // is briefly shown even if it hasn't been enabled by it's extension.
- bool preview_enabled_;
-
- // The current popup and the button it came from. NULL if no popup.
- ExtensionPopup* popup_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(PageActionImageView);
- };
- friend class PageActionImageView;
-
- class PageActionWithBadgeView;
- friend class PageActionWithBadgeView;
- typedef std::vector<PageActionWithBadgeView*> PageActionViews;
-
- class StarView : public views::ImageView, public InfoBubbleDelegate {
- public:
- explicit StarView(CommandUpdater* command_updater);
- virtual ~StarView();
-
- // Toggles the star on or off.
- void SetToggled(bool on);
-
- private:
- // views::ImageView overrides:
- virtual bool GetAccessibleRole(AccessibilityTypes::Role* role);
- virtual bool OnMousePressed(const views::MouseEvent& event);
- virtual void OnMouseReleased(const views::MouseEvent& event, bool canceled);
-
- // InfoBubbleDelegate overrides:
- virtual void InfoBubbleClosing(InfoBubble* info_bubble,
- bool closed_by_escape);
- virtual bool CloseOnEscape();
-
- // The CommandUpdater for the Browser object that owns the location bar.
- CommandUpdater* command_updater_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(StarView);
- };
-
- // Returns the height in pixels of the margin at the top of the bar.
- int TopMargin() const;
-
- // Returns the amount of horizontal space (in pixels) out of
- // |location_bar_width| that is not taken up by the actual text in
- // location_entry_.
- int AvailableWidth(int location_bar_width);
-
- // Returns whether the |available_width| is large enough to contain a view
- // with preferred width |pref_width| at its preferred size. If this returns
- // true, the preferred size should be used. If this returns false, the
- // minimum size of the view should be used.
- bool UsePref(int pref_width, int available_width);
-
- // If View fits in the specified region, it is made visible and the
- // bounds are adjusted appropriately. If the View does not fit, it is
- // made invisible.
- void LayoutView(bool leading, views::View* view, int available_width,
- gfx::Rect* bounds);
-
- // Update the visibility state of the Content Blocked icons to reflect what is
- // actually blocked on the current page.
- void RefreshContentSettingViews();
-
- // Delete all page action views that we have created.
- void DeletePageActionViews();
-
- // Update the views for the Page Actions, to reflect state changes for
- // PageActions.
- void RefreshPageActionViews();
-
- // Sets the visibility of view to new_vis.
- void ToggleVisibility(bool new_vis, views::View* view);
-
-#if defined(OS_WIN)
- // Helper for the Mouse event handlers that does all the real work.
- void OnMouseEvent(const views::MouseEvent& event, UINT msg);
-#endif
-
- // Helper to show the first run info bubble.
- void ShowFirstRunBubbleInternal(FirstRun::BubbleType bubble_type);
-
- // Current browser. Not owned by us.
- Browser* browser_;
-
- // Current profile. Not owned by us.
- Profile* profile_;
-
- // The Autocomplete Edit field.
-#if defined(OS_WIN)
- scoped_ptr<AutocompleteEditViewWin> location_entry_;
-#else
- scoped_ptr<AutocompleteEditViewGtk> location_entry_;
-#endif
-
- // The CommandUpdater for the Browser object that corresponds to this View.
- CommandUpdater* command_updater_;
-
- // The model.
- ToolbarModel* model_;
-
- // Our delegate.
- Delegate* delegate_;
-
- // This is the string of text from the autocompletion session that the user
- // entered or selected.
- std::wstring location_input_;
-
- // The user's desired disposition for how their input should be opened
- WindowOpenDisposition disposition_;
-
- // The transition type to use for the navigation
- PageTransition::Type transition_;
-
- // Font used by edit and some of the hints.
- gfx::Font font_;
-
- // An icon to the left of the edit field.
- LocationIconView location_icon_view_;
-
- // A bubble displayed for EV HTTPS sites.
- EVBubbleView ev_bubble_view_;
-
- // Location_entry view wrapper
- views::NativeViewHost* location_entry_view_;
-
- // The following views are used to provide hints and remind the user as to
- // what is going in the edit. They are all added a children of the
- // LocationBarView. At most one is visible at a time. Preference is
- // given to the keyword_view_, then hint_view_.
- // These autocollapse when the edit needs the room.
-
- // Shown if the user has selected a keyword.
- SelectedKeywordView selected_keyword_view_;
-
- // Shown if the selected url has a corresponding keyword.
- KeywordHintView keyword_hint_view_;
-
- // The content setting views.
- ContentSettingViews content_setting_views_;
-
- // The page action icon views.
- PageActionViews page_action_views_;
-
- // The star.
- StarView star_view_;
-
- // When true, the location bar view is read only and also is has a slightly
- // different presentation (font size / color). This is used for popups.
- bool popup_window_mode_;
-
- // Used schedule a task for the first run info bubble.
- ScopedRunnableMethodFactory<LocationBarView> first_run_bubble_;
-
- DISALLOW_IMPLICIT_CONSTRUCTORS(LocationBarView);
-};
-
-#endif // CHROME_BROWSER_VIEWS_LOCATION_BAR_VIEW_H_
diff --git a/chrome/browser/views/toolbar_view.cc b/chrome/browser/views/toolbar_view.cc
index 3b2ce98..5d445a9 100644
--- a/chrome/browser/views/toolbar_view.cc
+++ b/chrome/browser/views/toolbar_view.cc
@@ -599,8 +599,8 @@ void ToolbarView::CreateCenterStack(Profile *profile) {
reload_->SetID(VIEW_ID_RELOAD_BUTTON);
location_bar_ = new LocationBarView(profile, browser_->command_updater(),
- model_, this,
- display_mode_ == DISPLAYMODE_LOCATION);
+ model_, this, (display_mode_ == DISPLAYMODE_LOCATION) ?
+ LocationBarView::POPUP : LocationBarView::NORMAL);
// The Go button.
go_ = new GoButton(location_bar_, browser_);
diff --git a/chrome/browser/views/toolbar_view.h b/chrome/browser/views/toolbar_view.h
index 734da7f..cdd3318 100644
--- a/chrome/browser/views/toolbar_view.h
+++ b/chrome/browser/views/toolbar_view.h
@@ -16,11 +16,12 @@
#include "chrome/browser/pref_member.h"
#include "chrome/browser/views/accessible_toolbar_view.h"
#include "chrome/browser/views/go_button.h"
-#include "chrome/browser/views/location_bar_view.h"
+#include "chrome/browser/views/location_bar/location_bar_view.h"
#include "views/controls/button/menu_button.h"
#include "views/controls/menu/menu.h"
#include "views/controls/menu/menu_wrapper.h"
#include "views/controls/menu/view_menu_delegate.h"
+#include "views/focus/focus_manager.h"
#include "views/view.h"
class BrowserActionsContainer;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 332e351..a47c61b 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -2313,8 +2313,28 @@
'browser/views/local_storage_info_view.h',
'browser/views/local_storage_set_item_info_view.cc',
'browser/views/local_storage_set_item_info_view.h',
- 'browser/views/location_bar_view.cc',
- 'browser/views/location_bar_view.h',
+ 'browser/views/location_bar/click_handler.cc',
+ 'browser/views/location_bar/click_handler.h',
+ 'browser/views/location_bar/content_setting_image_view.cc',
+ 'browser/views/location_bar/content_setting_image_view.h',
+ 'browser/views/location_bar/ev_bubble_view.cc',
+ 'browser/views/location_bar/ev_bubble_view.h',
+ 'browser/views/location_bar/icon_label_bubble_view.h',
+ 'browser/views/location_bar/icon_label_bubble_view.cc',
+ 'browser/views/location_bar/keyword_hint_view.cc',
+ 'browser/views/location_bar/keyword_hint_view.h',
+ 'browser/views/location_bar/location_icon_view.cc',
+ 'browser/views/location_bar/location_icon_view.h',
+ 'browser/views/location_bar/location_bar_view.cc',
+ 'browser/views/location_bar/location_bar_view.h',
+ 'browser/views/location_bar/page_action_image_view.cc',
+ 'browser/views/location_bar/page_action_image_view.h',
+ 'browser/views/location_bar/page_action_with_badge_view.cc',
+ 'browser/views/location_bar/page_action_with_badge_view.h',
+ 'browser/views/location_bar/selected_keyword_view.h',
+ 'browser/views/location_bar/selected_keyword_view.cc',
+ 'browser/views/location_bar/star_view.cc',
+ 'browser/views/location_bar/star_view.h',
'browser/views/login_view.cc',
'browser/views/login_view.h',
'browser/views/modal_dialog_delegate.cc',
@@ -2907,6 +2927,28 @@
['include', '^browser/views/infobars/*'],
['include', '^browser/views/info_bubble.cc'],
['include', '^browser/views/info_bubble.h'],
+ ['include', '^browser/views/location_bar/click_handler.cc'],
+ ['include', '^browser/views/location_bar/click_handler.h'],
+ ['include', '^browser/views/location_bar/content_setting_image_view.cc'],
+ ['include', '^browser/views/location_bar/content_setting_image_view.h'],
+ ['include', '^browser/views/location_bar/ev_bubble_view.cc'],
+ ['include', '^browser/views/location_bar/ev_bubble_view.h'],
+ ['include', '^browser/views/location_bar/icon_label_bubble_view.h'],
+ ['include', '^browser/views/location_bar/icon_label_bubble_view.cc'],
+ ['include', '^browser/views/location_bar/keyword_hint_view.cc'],
+ ['include', '^browser/views/location_bar/keyword_hint_view.h'],
+ ['include', '^browser/views/location_bar/location_icon_view.cc'],
+ ['include', '^browser/views/location_bar/location_icon_view.h'],
+ ['include', '^browser/views/location_bar/location_bar_view.cc'],
+ ['include', '^browser/views/location_bar/location_bar_view.h'],
+ ['include', '^browser/views/location_bar/page_action_image_view.cc'],
+ ['include', '^browser/views/location_bar/page_action_image_view.h'],
+ ['include', '^browser/views/location_bar/page_action_with_badge_view.h'],
+ ['include', '^browser/views/location_bar/page_action_with_badge_view.cc'],
+ ['include', '^browser/views/location_bar/selected_keyword_view.h'],
+ ['include', '^browser/views/location_bar/selected_keyword_view.cc'],
+ ['include', '^browser/views/location_bar/star_view.cc'],
+ ['include', '^browser/views/location_bar/star_view.h'],
['include', '^browser/views/location_bar_view.cc'],
['include', '^browser/views/location_bar_view.h'],
['include', '^browser/views/options/options_page_view.cc'],