summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjohnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-10 06:27:38 +0000
committerjohnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-10 06:27:38 +0000
commit9429e976325c93329fd5d35e18699b8c47411f84 (patch)
tree4cd2048ae521a351b92d8b50863c52eb97489947
parent0c98d920fa52263e940683fea1c8bb2d870f42bb (diff)
downloadchromium_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.grd7
-rw-r--r--chrome/browser/views/notifications/balloon_view.cc81
-rw-r--r--chrome/browser/views/notifications/balloon_view.h32
-rw-r--r--chrome/renderer/notification_provider.cc4
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));
}