diff options
author | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-10 06:27:38 +0000 |
---|---|---|
committer | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-10 06:27:38 +0000 |
commit | 9429e976325c93329fd5d35e18699b8c47411f84 (patch) | |
tree | 4cd2048ae521a351b92d8b50863c52eb97489947 | |
parent | 0c98d920fa52263e940683fea1c8bb2d870f42bb (diff) | |
download | chromium_src-9429e976325c93329fd5d35e18699b8c47411f84.zip chromium_src-9429e976325c93329fd5d35e18699b8c47411f84.tar.gz chromium_src-9429e976325c93329fd5d35e18699b8c47411f84.tar.bz2 |
Adds an options menu to the frame of the desktop notification, for now with the single option of revoking permissions from that origin.
The renderer side change is a related issue that the full URL was being sent as the "source" of the notification rather than only the origin.
BUG=26690
TEST=open a notification
Review URL: http://codereview.chromium.org/363011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31547 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 7 | ||||
-rw-r--r-- | chrome/browser/views/notifications/balloon_view.cc | 81 | ||||
-rw-r--r-- | chrome/browser/views/notifications/balloon_view.h | 32 | ||||
-rw-r--r-- | chrome/renderer/notification_provider.cc | 4 |
4 files changed, 119 insertions, 5 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index eb330ee..1729d19 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -5687,6 +5687,13 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_NOTIFICATION_PERMISSION_NO" desc="The label of the 'deny' button on the notification permission infobar."> Deny </message> + <message name="IDS_NOTIFICATION_OPTIONS_MENU_LABEL" desc="Text for the menu option"> + Options + </message> + <message name="IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE" desc="Text for the menu option to revoke notification permission."> + Disable notifications from <ph name="site">$1<ex>mail.google.com</ex></ph> + </message> + <!-- New Tab Page Promotional messages --> <message name="IDS_NTP_PROMOTION_NEW" desc="Beginning of promotional message; a word in special red font signaling something new is coming."> diff --git a/chrome/browser/views/notifications/balloon_view.cc b/chrome/browser/views/notifications/balloon_view.cc index 48cf346..694ee2b 100644 --- a/chrome/browser/views/notifications/balloon_view.cc +++ b/chrome/browser/views/notifications/balloon_view.cc @@ -16,6 +16,8 @@ #include "base/string_util.h" #include "chrome/browser/browser_theme_provider.h" #include "chrome/browser/notifications/balloon.h" +#include "chrome/browser/notifications/desktop_notification_service.h" +#include "chrome/browser/profile.h" #include "chrome/browser/views/notifications/balloon_view_host.h" #include "chrome/common/notification_details.h" #include "chrome/common/notification_source.h" @@ -45,6 +47,10 @@ const int kShelfBorderTopOverlap = 2; const int kDismissButtonWidth = 46; const int kDismissButtonHeight = 20; +// Properties of the options menu. +const int kOptionsMenuWidth = 48; +const int kOptionsMenuHeight = 20; + // Properties of the origin label. const int kLeftLabelMargin = 5; @@ -61,6 +67,9 @@ const bool kAnimateEnabled = true; // with changes in the default font size. const int kDefaultShelfHeight = 22; +// Menu commands +const int kRevokePermissionCommand = 0; + } // namespace class BalloonCloseButtonListener : public views::ButtonListener { @@ -89,6 +98,9 @@ BalloonViewImpl::BalloonViewImpl() close_button_(NULL), close_button_listener_(NULL), animation_(NULL), + options_menu_contents_(NULL), + options_menu_menu_(NULL), + options_menu_button_(NULL), method_factory_(this) { // This object is not to be deleted by the views hierarchy, // as it is owned by the balloon. @@ -116,6 +128,10 @@ void BalloonViewImpl::Close(bool by_user) { &BalloonViewImpl::DelayedClose, by_user)); } +void BalloonViewImpl::RunMenu(views::View* source, const gfx::Point& pt) { + RunOptionsMenu(pt); +} + void BalloonViewImpl::DelayedClose(bool by_user) { html_contents_->Shutdown(); html_container_->CloseNow(); @@ -239,6 +255,23 @@ void BalloonViewImpl::Show(Balloon* balloon) { kDismissButtonHeight); AddChildView(close_button_); + const std::wstring options_text = + l10n_util::GetString(IDS_NOTIFICATION_OPTIONS_MENU_LABEL); + options_menu_button_ = new views::MenuButton(NULL, options_text, this, false); + options_menu_button_->SetFont( + ResourceBundle::GetSharedInstance().GetFont(ResourceBundle::SmallFont)); + options_menu_button_->SetEnabledColor( + BrowserThemeProvider::kDefaultColorTabText); + options_menu_button_->SetBounds(width() - kDismissButtonWidth + - kOptionsMenuWidth + - kRightMargin, + height() - kOptionsMenuHeight + - kShelfBorderTopOverlap + - kBottomMargin, + kOptionsMenuWidth, + kOptionsMenuHeight); + AddChildView(options_menu_button_); + const std::wstring source_label_text = l10n_util::GetStringF( IDS_NOTIFICATION_BALLOON_SOURCE_LABEL, ASCIIToWide(this->balloon_->notification().origin_url().spec())); @@ -253,6 +286,7 @@ void BalloonViewImpl::Show(Balloon* balloon) { - kShelfBorderTopOverlap - kBottomMargin, width() - kDismissButtonWidth + - kOptionsMenuWidth - kRightMargin, kDismissButtonHeight); AddChildView(source_label); @@ -265,6 +299,24 @@ void BalloonViewImpl::Show(Balloon* balloon) { NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon)); } +void BalloonViewImpl::RunOptionsMenu(const gfx::Point& pt) { + CreateOptionsMenu(); + options_menu_menu_->RunMenuAt(pt, views::Menu2::ALIGN_TOPRIGHT); +} + +void BalloonViewImpl::CreateOptionsMenu() { + if (options_menu_contents_.get()) + return; + + const std::wstring label_text = l10n_util::GetStringF( + IDS_NOTIFICATION_BALLOON_REVOKE_MESSAGE, + ASCIIToWide(this->balloon_->notification().origin_url().spec())); + + options_menu_contents_.reset(new views::SimpleMenuModel(this)); + options_menu_contents_->AddItem(kRevokePermissionCommand, label_text); + + options_menu_menu_.reset(new views::Menu2(options_menu_contents_.get())); +} void BalloonViewImpl::GetContentsMask(const gfx::Rect& rect, gfx::Path* path) const { @@ -339,6 +391,35 @@ void BalloonViewImpl::Paint(gfx::Canvas* canvas) { View::Paint(canvas); } +// SimpleMenuModel::Delegate methods +bool BalloonViewImpl::IsCommandIdChecked(int /* command_id */) const { + // Nothing in the menu is checked. + return false; +} + +bool BalloonViewImpl::IsCommandIdEnabled(int /* command_id */) const { + // All the menu options are always enabled. + return true; +} + +bool BalloonViewImpl::GetAcceleratorForCommandId( + int /* command_id */, views::Accelerator* /* accelerator */) { + // Currently no accelerators. + return false; +} + +void BalloonViewImpl::ExecuteCommand(int command_id) { + DesktopNotificationService* service = + balloon_->profile()->GetDesktopNotificationService(); + switch (command_id) { + case kRevokePermissionCommand: + service->DenyPermission(balloon_->notification().origin_url()); + break; + default: + NOTIMPLEMENTED(); + } +} + void BalloonViewImpl::Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details) { diff --git a/chrome/browser/views/notifications/balloon_view.h b/chrome/browser/views/notifications/balloon_view.h index 0d7dd0a..3f5c751 100644 --- a/chrome/browser/views/notifications/balloon_view.h +++ b/chrome/browser/views/notifications/balloon_view.h @@ -18,6 +18,9 @@ #include "chrome/browser/notifications/balloon.h" #include "chrome/common/notification_registrar.h" #include "chrome/common/notification_service.h" +#include "views/controls/button/menu_button.h" +#include "views/controls/menu/simple_menu_model.h" +#include "views/controls/menu/view_menu_delegate.h" #include "views/view.h" namespace views { @@ -36,6 +39,8 @@ class SlideAnimation; // It draws a border, and within the border an HTML renderer. class BalloonViewImpl : public BalloonView, public views::View, + public views::ViewMenuDelegate, + public views::SimpleMenuModel::Delegate, public NotificationObserver, public AnimationDelegate { public: @@ -48,7 +53,7 @@ class BalloonViewImpl : public BalloonView, void Close(bool by_user); private: - // Overridden from views::View. + // views::View interface. virtual void Paint(gfx::Canvas* canvas); virtual void DidChangeBounds(const gfx::Rect& previous, const gfx::Rect& current); @@ -56,14 +61,30 @@ class BalloonViewImpl : public BalloonView, return gfx::Size(1000, 1000); } - // NotificationObserver method. + // views::ViewMenuDelegate interface. + void RunMenu(views::View* source, const gfx::Point& pt); + + // views::SimpleMenuModel::Delegate interface. + virtual bool IsCommandIdChecked(int command_id) const; + virtual bool IsCommandIdEnabled(int command_id) const; + virtual bool GetAcceleratorForCommandId(int command_id, + views::Accelerator* accelerator); + virtual void ExecuteCommand(int command_id); + + // NotificationObserver interface. virtual void Observe(NotificationType type, const NotificationSource& source, const NotificationDetails& details); - // AnimationDelegate method. + // AnimationDelegate interface. virtual void AnimationProgressed(const Animation* animation); + // Launches the options menu at screen coordinates |pt|. + void RunOptionsMenu(const gfx::Point& pt); + + // Initializes the options menu. + void CreateOptionsMenu(); + // How to mask the balloon contents to fit within the frame. // Populates |path| with the outline. void GetContentsMask(const gfx::Rect& contents_rect, gfx::Path* path) const; @@ -126,6 +147,11 @@ class BalloonViewImpl : public BalloonView, gfx::Rect anim_frame_start_; gfx::Rect anim_frame_end_; + // The options menu. + scoped_ptr<views::SimpleMenuModel> options_menu_contents_; + scoped_ptr<views::Menu2> options_menu_menu_; + views::MenuButton* options_menu_button_; + NotificationRegistrar notification_registrar_; DISALLOW_COPY_AND_ASSIGN(BalloonViewImpl); diff --git a/chrome/renderer/notification_provider.cc b/chrome/renderer/notification_provider.cc index 6d142fe..2862e4a 100644 --- a/chrome/renderer/notification_provider.cc +++ b/chrome/renderer/notification_provider.cc @@ -78,7 +78,7 @@ bool NotificationProvider::ShowHTML(const WebNotification& notification, int id) { DCHECK(notification.isHTML()); return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(), - GURL(view_->webview()->mainFrame()->url()), + GURL(view_->webview()->mainFrame()->url()).GetOrigin(), notification.url(), id)); } @@ -86,7 +86,7 @@ bool NotificationProvider::ShowText(const WebNotification& notification, int id) { DCHECK(!notification.isHTML()); return Send(new ViewHostMsg_ShowDesktopNotificationText(view_->routing_id(), - GURL(view_->webview()->mainFrame()->url()), + GURL(view_->webview()->mainFrame()->url()).GetOrigin(), GURL(notification.icon()), notification.title(), notification.body(), id)); } |