diff options
Diffstat (limited to 'chrome')
36 files changed, 2723 insertions, 2495 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..a1a6bac 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,19 +21,9 @@ #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 namespace { @@ -69,146 +58,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 +81,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 +118,7 @@ InfoBubbleContentsView::~InfoBubbleContentsView() { } void InfoBubbleContentsView::BubbleShown() { - navigation_bar_->RequestFocus(); + location_bar_->RequestFocus(); } void InfoBubbleContentsView::ViewHierarchyChanged( @@ -266,8 +136,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 +163,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 +241,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'], |