diff options
author | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-03 01:36:00 +0000 |
---|---|---|
committer | ben@chromium.org <ben@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-12-03 01:36:00 +0000 |
commit | 5855df7de77eee7ad51cdac73f7d294525d75faf (patch) | |
tree | 9231cdfe54737935a63620b894e895cba69bbb33 /chrome | |
parent | f82a64d15a03c6db10ea33449c34d496a145b08e (diff) | |
download | chromium_src-5855df7de77eee7ad51cdac73f7d294525d75faf.zip chromium_src-5855df7de77eee7ad51cdac73f7d294525d75faf.tar.gz chromium_src-5855df7de77eee7ad51cdac73f7d294525d75faf.tar.bz2 |
Convert Alternate NavURL Fetcher to use the new infobar framework.
http://crbug.com/4620
Review URL: http://codereview.chromium.org/13070
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@6268 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/alternate_nav_url_fetcher.cc | 69 | ||||
-rw-r--r-- | chrome/browser/alternate_nav_url_fetcher.h | 17 | ||||
-rw-r--r-- | chrome/browser/browser_init.cc | 4 | ||||
-rw-r--r-- | chrome/browser/infobar_delegate.cc | 21 | ||||
-rw-r--r-- | chrome/browser/infobar_delegate.h | 64 | ||||
-rw-r--r-- | chrome/browser/password_manager.cc | 6 | ||||
-rw-r--r-- | chrome/browser/plugin_installer.cc | 4 | ||||
-rw-r--r-- | chrome/browser/ssl_manager.cc | 7 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.cc | 108 | ||||
-rw-r--r-- | chrome/browser/views/infobars/infobars.h | 24 |
10 files changed, 275 insertions, 49 deletions
diff --git a/chrome/browser/alternate_nav_url_fetcher.cc b/chrome/browser/alternate_nav_url_fetcher.cc index d20e999..6533dba 100644 --- a/chrome/browser/alternate_nav_url_fetcher.cc +++ b/chrome/browser/alternate_nav_url_fetcher.cc @@ -6,16 +6,20 @@ #include "chrome/browser/navigation_controller.h" #include "chrome/browser/navigation_entry.h" -#include "chrome/browser/views/info_bar_alternate_nav_url_view.h" #include "chrome/browser/web_contents.h" -#include "chrome/browser/web_contents_view.h" +#include "chrome/common/l10n_util.h" +#include "chrome/common/resource_bundle.h" + +#include "generated_resources.h" AlternateNavURLFetcher::AlternateNavURLFetcher( const std::wstring& alternate_nav_url) - : alternate_nav_url_(alternate_nav_url), + : LinkInfoBarDelegate(NULL), + alternate_nav_url_(alternate_nav_url), controller_(NULL), state_(NOT_STARTED), - navigated_to_entry_(false) { + navigated_to_entry_(false), + infobar_contents_(NULL) { registrar_.Add(this, NOTIFY_NAV_ENTRY_PENDING, NotificationService::AllSources()); } @@ -52,7 +56,6 @@ void AlternateNavURLFetcher::Observe(NotificationType type, Source<NavigationController>(controller_)); navigated_to_entry_ = true; ShowInfobarIfPossible(); - // DON'T DO ANYTHING AFTER HERE SINCE |this| MAY BE DELETED! break; case NOTIFY_TAB_CLOSED: @@ -80,31 +83,51 @@ void AlternateNavURLFetcher::OnURLFetchComplete(const URLFetcher* source, (response_code == 401) || (response_code == 407))) { state_ = SUCCEEDED; ShowInfobarIfPossible(); - // DON'T DO ANYTHING AFTER HERE SINCE |this| MAY BE DELETED! } else { state_ = FAILED; } } +std::wstring AlternateNavURLFetcher::GetMessageTextWithOffset( + size_t* link_offset) const { + const std::wstring label = l10n_util::GetStringF( + IDS_ALTERNATE_NAV_URL_VIEW_LABEL, std::wstring(), link_offset); + DCHECK(*link_offset != std::wstring::npos); + return label; +} + +std::wstring AlternateNavURLFetcher::GetLinkText() const { + return alternate_nav_url_; +} + +SkBitmap* AlternateNavURLFetcher::GetIcon() const { + return ResourceBundle::GetSharedInstance().GetBitmapNamed( + IDR_INFOBAR_ALT_NAV_URL); +} + +bool AlternateNavURLFetcher::LinkClicked(WindowOpenDisposition disposition) { + infobar_contents_->OpenURL( + GURL(alternate_nav_url_), GURL(), disposition, + // Pretend the user typed this URL, so that navigating to + // it will be the default action when it's typed again in + // the future. + PageTransition::TYPED); + + // We should always close, even if the navigation did not occur within this + // TabContents. + return true; +} + +void AlternateNavURLFetcher::InfoBarClosed() { + delete this; +} + void AlternateNavURLFetcher::ShowInfobarIfPossible() { if (!navigated_to_entry_ || state_ != SUCCEEDED) return; - const NavigationEntry* const entry = controller_->GetActiveEntry(); - DCHECK(entry); - if (entry->tab_type() != TAB_CONTENTS_WEB) - return; - TabContents* tab_contents = - controller_->GetTabContents(TAB_CONTENTS_WEB); - DCHECK(tab_contents); - WebContents* web_contents = tab_contents->AsWebContents(); - // The infobar will auto-expire this view on the next user-initiated - // navigation, so we don't need to keep track of it. - web_contents->view()->GetInfoBarView()->AddChildView( - new InfoBarAlternateNavURLView(alternate_nav_url_)); - - // Now we're no longer referencing the navigation controller or the url fetch, - // so our job is done. - delete this; + infobar_contents_ = controller_->active_contents(); + StoreActiveEntryUniqueID(infobar_contents_); + // We will be deleted when the InfoBar is destroyed. (See InfoBarClosed). + infobar_contents_->AddInfoBar(this); } - diff --git a/chrome/browser/alternate_nav_url_fetcher.h b/chrome/browser/alternate_nav_url_fetcher.h index b28b48f0..501bed4 100644 --- a/chrome/browser/alternate_nav_url_fetcher.h +++ b/chrome/browser/alternate_nav_url_fetcher.h @@ -7,6 +7,7 @@ #include <string> +#include "chrome/browser/infobar_delegate.h" #include "chrome/browser/url_fetcher.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/notification_service.h" @@ -26,7 +27,8 @@ class NavigationController; // We'll do this when the load commits, or when the navigation controller // itself is deleted. class AlternateNavURLFetcher : public NotificationObserver, - public URLFetcher::Delegate { + public URLFetcher::Delegate, + public LinkInfoBarDelegate { public: enum State { NOT_STARTED, @@ -52,10 +54,16 @@ class AlternateNavURLFetcher : public NotificationObserver, const ResponseCookies& cookies, const std::string& data); + // LinkInfoBarDelegate + virtual std::wstring GetMessageTextWithOffset(size_t* link_offset) const; + virtual std::wstring GetLinkText() const; + virtual SkBitmap* GetIcon() const; + virtual bool LinkClicked(WindowOpenDisposition disposition); + virtual void InfoBarClosed(); + private: // Displays the infobar if all conditions are met (the page has loaded and - // the fetch of the alternate URL succeeded). If the infobar is displayed, - // this object is no longer necessary and this function WILL DELETE |this|!. + // the fetch of the alternate URL succeeded). void ShowInfobarIfPossible(); std::wstring alternate_nav_url_; @@ -63,6 +71,9 @@ class AlternateNavURLFetcher : public NotificationObserver, NavigationController* controller_; State state_; bool navigated_to_entry_; + + // The TabContents the InfoBarDelegate was added to. + TabContents* infobar_contents_; NotificationRegistrar registrar_; diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc index f1a709a..ddc3861 100644 --- a/chrome/browser/browser_init.cc +++ b/chrome/browser/browser_init.cc @@ -55,8 +55,8 @@ namespace { class SessionCrashedInfoBarDelegate : public ConfirmInfoBarDelegate { public: explicit SessionCrashedInfoBarDelegate(TabContents* contents) - : profile_(contents->profile()), - ConfirmInfoBarDelegate(contents) { + : ConfirmInfoBarDelegate(contents), + profile_(contents->profile()) { } // Overridden from ConfirmInfoBarDelegate: diff --git a/chrome/browser/infobar_delegate.cc b/chrome/browser/infobar_delegate.cc index c974948c..44e9cc4 100644 --- a/chrome/browser/infobar_delegate.cc +++ b/chrome/browser/infobar_delegate.cc @@ -22,8 +22,13 @@ bool InfoBarDelegate::ShouldExpire( return is_reload || (contents_unique_id_ != details.entry->unique_id()); } -InfoBarDelegate::InfoBarDelegate(TabContents* contents) { - // Initialize the unique id that we use to expire. +InfoBarDelegate::InfoBarDelegate(TabContents* contents) + : contents_unique_id_(0) { + if (contents) + StoreActiveEntryUniqueID(contents); +} + +void InfoBarDelegate::StoreActiveEntryUniqueID(TabContents* contents) { NavigationEntry* active_entry = contents->controller()->GetActiveEntry(); contents_unique_id_ = active_entry ? active_entry->unique_id() : 0; } @@ -42,6 +47,12 @@ AlertInfoBarDelegate::AlertInfoBarDelegate(TabContents* contents) : InfoBarDelegate(contents) { } +// LinkInfoBarDelegate: -------------------------------------------------------- + +LinkInfoBarDelegate::LinkInfoBarDelegate(TabContents* contents) + : InfoBarDelegate(contents) { +} + // ConfirmInfoBarDelegate: ----------------------------------------------------- std::wstring ConfirmInfoBarDelegate::GetButtonLabel( @@ -64,9 +75,9 @@ SimpleAlertInfoBarDelegate::SimpleAlertInfoBarDelegate( TabContents* contents, const std::wstring& message, SkBitmap* icon) - : message_(message), - icon_(icon), - AlertInfoBarDelegate(contents) { + : AlertInfoBarDelegate(contents), + message_(message), + icon_(icon) { } std::wstring SimpleAlertInfoBarDelegate::GetMessageText() const { diff --git a/chrome/browser/infobar_delegate.h b/chrome/browser/infobar_delegate.h index f23dea6..523bc20 100644 --- a/chrome/browser/infobar_delegate.h +++ b/chrome/browser/infobar_delegate.h @@ -14,6 +14,7 @@ class AlertInfoBarDelegate; class ConfirmInfoBarDelegate; class InfoBar; +class LinkInfoBarDelegate; // An interface implemented by objects wishing to control an InfoBar. // Implementing this interface is not sufficient to use an InfoBar, since it @@ -46,25 +47,33 @@ class InfoBarDelegate { // platform-specific. virtual InfoBar* CreateInfoBar() = 0; - // Returns a pointer to the ConfirmInfoBarDelegate interface, if implemented. + // Returns a pointer to the AlertInfoBarDelegate interface, if implemented. virtual AlertInfoBarDelegate* AsAlertInfoBarDelegate() { return NULL; } + // Returns a pointer to the LinkInfoBarDelegate interface, if implemented. + virtual LinkInfoBarDelegate* AsLinkInfoBarDelegate() { + return NULL; + } + // Returns a pointer to the ConfirmInfoBarDelegate interface, if implemented. virtual ConfirmInfoBarDelegate* AsConfirmInfoBarDelegate() { return NULL; } protected: - // Constructs the InfoBarDelegate for the specified TabContents' - // NavigationController. + // Provided to subclasses as a convenience to initialize the state of this + // object. If |contents| is non-NULL, its active entry's unique ID will be + // stored using StoreActiveEntryUniqueID automatically. explicit InfoBarDelegate(TabContents* contents); - - private: - // The TabContents this InfoBarDelegate was added to. - TabContents* contents_; + // Store the unique id for the active entry in the specified TabContents, to + // be used later upon navigation to determine if this InfoBarDelegate should + // be expired from |contents_|. + void StoreActiveEntryUniqueID(TabContents* contents); + + private: // The unique id of the active NavigationEntry of the TabContents taht we were // opened for. Used to help expire on navigations. int contents_unique_id_; @@ -95,6 +104,47 @@ class AlertInfoBarDelegate : public InfoBarDelegate { }; // An interface derived from InfoBarDelegate implemented by objects wishing to +// control a LinkInfoBar. +class LinkInfoBarDelegate : public InfoBarDelegate { + public: + // Returns the message string to be displayed in the InfoBar. |link_offset| + // is the position where the link should be inserted. If |link_offset| is set + // to std::wstring::npos (it is by default), the link is right aligned within + // the InfoBar rather than being embedded in the message text. + virtual std::wstring GetMessageTextWithOffset(size_t* link_offset) const { + *link_offset = std::wstring::npos; + return std::wstring(); + } + + // Returns the text of the link to be displayed. + virtual std::wstring GetLinkText() const = 0; + + // Returns the icon that should be shown for this InfoBar, or NULL if there is + // none. + virtual SkBitmap* GetIcon() const { return NULL; } + + // Called when the Link is clicked. The |disposition| specifies how the + // resulting document should be loaded (based on the event flags present when + // the link was clicked). This function returns true if the InfoBar should be + // closed now or false if it should remain until the user explicitly closes + // it. + virtual bool LinkClicked(WindowOpenDisposition disposition) { + return true; + } + + // Overridden from InfoBarDelegate: + virtual InfoBar* CreateInfoBar(); + virtual LinkInfoBarDelegate* AsLinkInfoBarDelegate() { + return this; + } + + protected: + explicit LinkInfoBarDelegate(TabContents* contents); + + DISALLOW_COPY_AND_ASSIGN(LinkInfoBarDelegate); +}; + +// An interface derived from InfoBarDelegate implemented by objects wishing to // control a ConfirmInfoBar. class ConfirmInfoBarDelegate : public AlertInfoBarDelegate { public: diff --git a/chrome/browser/password_manager.cc b/chrome/browser/password_manager.cc index 3edd0fea..74b4d44 100644 --- a/chrome/browser/password_manager.cc +++ b/chrome/browser/password_manager.cc @@ -24,10 +24,10 @@ void PasswordManager::RegisterUserPrefs(PrefService* prefs) { } PasswordManager::PasswordManager(WebContents* web_contents) - : web_contents_(web_contents), + : ConfirmInfoBarDelegate(web_contents), + web_contents_(web_contents), observer_(NULL), - login_managers_deleter_(&pending_login_managers_), - ConfirmInfoBarDelegate(web_contents) { + login_managers_deleter_(&pending_login_managers_) { password_manager_enabled_.Init(prefs::kPasswordManagerEnabled, web_contents->profile()->GetPrefs(), NULL); } diff --git a/chrome/browser/plugin_installer.cc b/chrome/browser/plugin_installer.cc index 444ff2d..683c77a 100644 --- a/chrome/browser/plugin_installer.cc +++ b/chrome/browser/plugin_installer.cc @@ -14,8 +14,8 @@ #include "generated_resources.h" PluginInstaller::PluginInstaller(WebContents* web_contents) - : web_contents_(web_contents), - ConfirmInfoBarDelegate(web_contents) { + : ConfirmInfoBarDelegate(web_contents), + web_contents_(web_contents) { } PluginInstaller::~PluginInstaller() { diff --git a/chrome/browser/ssl_manager.cc b/chrome/browser/ssl_manager.cc index 46a5546..1881fdf 100644 --- a/chrome/browser/ssl_manager.cc +++ b/chrome/browser/ssl_manager.cc @@ -43,10 +43,10 @@ class SSLInfoBarDelegate : public ConfirmInfoBarDelegate { const std::wstring message, const std::wstring& button_label, Task* task) - : message_(message), + : ConfirmInfoBarDelegate(contents), + message_(message), button_label_(button_label), - task_(task), - ConfirmInfoBarDelegate(contents) { + task_(task) { } virtual ~SSLInfoBarDelegate() {} @@ -74,7 +74,6 @@ class SSLInfoBarDelegate : public ConfirmInfoBarDelegate { } return true; } - private: // Labels for the InfoBar's message and button. diff --git a/chrome/browser/views/infobars/infobars.cc b/chrome/browser/views/infobars/infobars.cc index 52fcf55..475b7ea 100644 --- a/chrome/browser/views/infobars/infobars.cc +++ b/chrome/browser/views/infobars/infobars.cc @@ -5,6 +5,7 @@ #include "chrome/browser/views/infobars/infobars.h" #include "chrome/app/theme/theme_resources.h" +#include "chrome/browser/views/event_utils.h" #include "chrome/browser/views/infobars/infobar_container.h" #include "chrome/common/l10n_util.h" #include "chrome/common/resource_bundle.h" @@ -24,6 +25,7 @@ static const int kVerticalPadding = 3; static const int kHorizontalPadding = 3; static const int kIconLabelSpacing = 5; static const int kButtonSpacing = 5; +static const int kWordSpacing = 2; static const SkColor kBackgroundColorTop = SkColorSetRGB(255, 242, 183); static const SkColor kBackgroundColorBottom = SkColorSetRGB(250, 230, 145); @@ -262,6 +264,106 @@ AlertInfoBarDelegate* AlertInfoBar::GetDelegate() { return delegate()->AsAlertInfoBarDelegate(); } +// LinkInfoBar, public: -------------------------------------------------------- + +LinkInfoBar::LinkInfoBar(LinkInfoBarDelegate* delegate) + : icon_(new views::ImageView), + label_1_(new views::Label), + label_2_(new views::Label), + link_(new views::Link), + InfoBar(delegate) { + // Set up the icon. + if (delegate->GetIcon()) + icon_->SetImage(delegate->GetIcon()); + AddChildView(icon_); + + // Set up the labels. + size_t offset; + std::wstring message_text = delegate->GetMessageTextWithOffset(&offset); + if (offset != std::wstring::npos) { + label_1_->SetText(message_text.substr(0, offset)); + label_2_->SetText(message_text.substr(offset)); + } else { + label_1_->SetText(message_text); + } + ResourceBundle& rb = ResourceBundle::GetSharedInstance(); + label_1_->SetFont(rb.GetFont(ResourceBundle::MediumFont)); + label_2_->SetFont(rb.GetFont(ResourceBundle::MediumFont)); + label_1_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + label_2_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + AddChildView(label_1_); + AddChildView(label_2_); + + // Set up the link. + link_->SetText(delegate->GetLinkText()); + link_->SetFont(rb.GetFont(ResourceBundle::MediumFont)); + link_->SetHorizontalAlignment(views::Label::ALIGN_LEFT); + link_->SetController(this); + AddChildView(link_); +} + +LinkInfoBar::~LinkInfoBar() { +} + +// LinkInfoBar, views::LinkController implementation: -------------------------- + +void LinkInfoBar::LinkActivated(views::Link* source, int event_flags) { + DCHECK(source == link_); + if (GetDelegate()->LinkClicked( + event_utils::DispositionFromEventFlags(event_flags))) { + RemoveInfoBar(); + } +} + +// LinkInfoBar, views::View overrides: ----------------------------------------- + +void LinkInfoBar::Layout() { + // Layout the close button. + InfoBar::Layout(); + + // Layout the icon. + gfx::Size icon_ps = icon_->GetPreferredSize(); + icon_->SetBounds(kHorizontalPadding, OffsetY(this, icon_ps), icon_ps.width(), + icon_ps.height()); + + int label_1_x = icon_->bounds().right() + kIconLabelSpacing; + + // Figure out the amount of space available to the rest of the content now + // that the close button and the icon have been positioned. + int available_width = GetAvailableWidth() - label_1_x; + + // Layout the left label. + gfx::Size label_1_ps = label_1_->GetPreferredSize(); + label_1_->SetBounds(label_1_x, OffsetY(this, label_1_ps), label_1_ps.width(), + label_1_ps.height()); + + // Layout the link. + gfx::Size link_ps = link_->GetPreferredSize(); + bool has_second_label = !label_2_->GetText().empty(); + if (has_second_label) { + // Embed the link in the text string between the two labels. + link_->SetBounds(label_1_->bounds().right() + kWordSpacing, + OffsetY(this, link_ps), link_ps.width(), link_ps.height()); + } else { + // Right-align the link toward the edge of the InfoBar. + link_->SetBounds(label_1_x + available_width - link_ps.width(), + OffsetY(this, link_ps), link_ps.width(), link_ps.height()); + } + + // Layout the right label (we do this regardless of whether or not it has + // text). + gfx::Size label_2_ps = label_2_->GetPreferredSize(); + label_2_->SetBounds(link_->bounds().right() + kWordSpacing, + OffsetY(this, label_2_ps), label_2_ps.width(), + label_2_ps.height()); +} + +// LinkInfoBar, private: ------------------------------------------------------- + +LinkInfoBarDelegate* LinkInfoBar::GetDelegate() { + return delegate()->AsLinkInfoBarDelegate(); +} + // ConfirmInfoBar, public: ----------------------------------------------------- ConfirmInfoBar::ConfirmInfoBar(ConfirmInfoBarDelegate* delegate) @@ -361,6 +463,12 @@ InfoBar* AlertInfoBarDelegate::CreateInfoBar() { return new AlertInfoBar(this); } +// LinkInfoBarDelegate, InfoBarDelegate overrides: ----------------------------- + +InfoBar* LinkInfoBarDelegate::CreateInfoBar() { + return new LinkInfoBar(this); +} + // ConfirmInfoBarDelegate, InfoBarDelegate overrides: -------------------------- InfoBar* ConfirmInfoBarDelegate::CreateInfoBar() { diff --git a/chrome/browser/views/infobars/infobars.h b/chrome/browser/views/infobars/infobars.h index 028632b..e0ae487 100644 --- a/chrome/browser/views/infobars/infobars.h +++ b/chrome/browser/views/infobars/infobars.h @@ -7,6 +7,7 @@ #include "chrome/browser/infobar_delegate.h" #include "chrome/views/base_button.h" +#include "chrome/views/link.h" #include "chrome/views/native_button.h" class InfoBarContainer; @@ -133,6 +134,29 @@ class AlertInfoBar : public InfoBar { DISALLOW_COPY_AND_ASSIGN(AlertInfoBar); }; +class LinkInfoBar : public InfoBar, + public views::LinkController { + public: + explicit LinkInfoBar(LinkInfoBarDelegate* delegate); + virtual ~LinkInfoBar(); + + // Overridden from views::LinkController: + virtual void LinkActivated(views::Link* source, int event_flags); + + // Overridden from views::View: + virtual void Layout(); + + private: + LinkInfoBarDelegate* GetDelegate(); + + views::ImageView* icon_; + views::Label* label_1_; + views::Label* label_2_; + views::Link* link_; + + DISALLOW_COPY_AND_ASSIGN(LinkInfoBar); +}; + class ConfirmInfoBar : public AlertInfoBar, public views::NativeButton::Listener { public: |