1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "ui/message_center/message_center_tray.h" 6 7 #include "base/observer_list.h" 8 #include "base/strings/utf_string_conversions.h" 9 #include "grit/ui_strings.h" 10 #include "ui/base/l10n/l10n_util.h" 11 #include "ui/base/models/simple_menu_model.h" 12 #include "ui/message_center/message_center.h" 13 #include "ui/message_center/message_center_tray_delegate.h" 14 #include "ui/message_center/message_center_types.h" 15 #include "ui/message_center/notification_blocker.h" 16 17 namespace message_center { 18 19 namespace { 20 21 // Menu constants 22 const int kTogglePermissionCommand = 0; 23 const int kShowSettingsCommand = 1; 24 25 // The model of the context menu for a notification card. 26 class NotificationMenuModel : public ui::SimpleMenuModel, 27 public ui::SimpleMenuModel::Delegate { 28 public: 29 NotificationMenuModel(MessageCenterTray* tray, 30 const NotifierId& notifier_id, 31 const base::string16& display_source); 32 virtual ~NotificationMenuModel(); 33 34 // Overridden from ui::SimpleMenuModel::Delegate: 35 virtual bool IsCommandIdChecked(int command_id) const OVERRIDE; 36 virtual bool IsCommandIdEnabled(int command_id) const OVERRIDE; 37 virtual bool GetAcceleratorForCommandId( 38 int command_id, 39 ui::Accelerator* accelerator) OVERRIDE; 40 virtual void ExecuteCommand(int command_id, int event_flags) OVERRIDE; 41 42 private: 43 MessageCenterTray* tray_; 44 NotifierId notifier_id_; 45 DISALLOW_COPY_AND_ASSIGN(NotificationMenuModel); 46 }; 47 48 NotificationMenuModel::NotificationMenuModel( 49 MessageCenterTray* tray, 50 const NotifierId& notifier_id, 51 const base::string16& display_source) 52 : ui::SimpleMenuModel(this), 53 tray_(tray), 54 notifier_id_(notifier_id) { 55 // Add 'disable notifications' menu item. 56 if (!display_source.empty()) { 57 AddItem(kTogglePermissionCommand, 58 l10n_util::GetStringFUTF16(IDS_MESSAGE_CENTER_NOTIFIER_DISABLE, 59 display_source)); 60 } 61 // Add settings menu item. 62 AddItem(kShowSettingsCommand, 63 l10n_util::GetStringUTF16(IDS_MESSAGE_CENTER_SETTINGS)); 64 } 65 66 NotificationMenuModel::~NotificationMenuModel() { 67 } 68 69 bool NotificationMenuModel::IsCommandIdChecked(int command_id) const { 70 return false; 71 } 72 73 bool NotificationMenuModel::IsCommandIdEnabled(int command_id) const { 74 return tray_->delegate()->IsContextMenuEnabled(); 75 } 76 77 bool NotificationMenuModel::GetAcceleratorForCommandId( 78 int command_id, 79 ui::Accelerator* accelerator) { 80 return false; 81 } 82 83 void NotificationMenuModel::ExecuteCommand(int command_id, int event_flags) { 84 switch (command_id) { 85 case kTogglePermissionCommand: 86 tray_->message_center()->DisableNotificationsByNotifier(notifier_id_); 87 break; 88 case kShowSettingsCommand: 89 tray_->ShowNotifierSettingsBubble(); 90 break; 91 default: 92 NOTREACHED(); 93 } 94 } 95 96 } // namespace 97 98 MessageCenterTray::MessageCenterTray( 99 MessageCenterTrayDelegate* delegate, 100 message_center::MessageCenter* message_center) 101 : message_center_(message_center), 102 message_center_visible_(false), 103 popups_visible_(false), 104 delegate_(delegate) { 105 message_center_->AddObserver(this); 106 } 107 108 MessageCenterTray::~MessageCenterTray() { 109 message_center_->RemoveObserver(this); 110 } 111 112 bool MessageCenterTray::ShowMessageCenterBubble() { 113 if (message_center_visible_) 114 return true; 115 116 HidePopupBubbleInternal(); 117 118 message_center_visible_ = delegate_->ShowMessageCenter(); 119 message_center_->SetVisibility(message_center::VISIBILITY_MESSAGE_CENTER); 120 NotifyMessageCenterTrayChanged(); 121 return message_center_visible_; 122 } 123 124 bool MessageCenterTray::HideMessageCenterBubble() { 125 if (!message_center_visible_) 126 return false; 127 delegate_->HideMessageCenter(); 128 MarkMessageCenterHidden(); 129 return true; 130 } 131 132 void MessageCenterTray::MarkMessageCenterHidden() { 133 if (!message_center_visible_) 134 return; 135 message_center_visible_ = false; 136 message_center_->SetVisibility(message_center::VISIBILITY_TRANSIENT); 137 138 // Some notifications (like system ones) should appear as popups again 139 // after the message center is closed. 140 if (message_center_->HasPopupNotifications()) { 141 ShowPopupBubble(); 142 return; 143 } 144 145 NotifyMessageCenterTrayChanged(); 146 } 147 148 void MessageCenterTray::ToggleMessageCenterBubble() { 149 if (message_center_visible_) 150 HideMessageCenterBubble(); 151 else 152 ShowMessageCenterBubble(); 153 } 154 155 void MessageCenterTray::ShowPopupBubble() { 156 if (message_center_visible_) 157 return; 158 159 if (popups_visible_) { 160 NotifyMessageCenterTrayChanged(); 161 return; 162 } 163 164 if (!message_center_->HasPopupNotifications()) 165 return; 166 167 popups_visible_ = delegate_->ShowPopups(); 168 169 NotifyMessageCenterTrayChanged(); 170 } 171 172 bool MessageCenterTray::HidePopupBubble() { 173 if (!popups_visible_) 174 return false; 175 HidePopupBubbleInternal(); 176 NotifyMessageCenterTrayChanged(); 177 178 return true; 179 } 180 181 void MessageCenterTray::HidePopupBubbleInternal() { 182 if (!popups_visible_) 183 return; 184 185 delegate_->HidePopups(); 186 popups_visible_ = false; 187 } 188 189 void MessageCenterTray::ShowNotifierSettingsBubble() { 190 if (popups_visible_) 191 HidePopupBubbleInternal(); 192 193 message_center_visible_ = delegate_->ShowNotifierSettings(); 194 message_center_->SetVisibility(message_center::VISIBILITY_SETTINGS); 195 196 NotifyMessageCenterTrayChanged(); 197 } 198 199 scoped_ptr<ui::MenuModel> MessageCenterTray::CreateNotificationMenuModel( 200 const NotifierId& notifier_id, 201 const base::string16& display_source) { 202 return scoped_ptr<ui::MenuModel>(new NotificationMenuModel( 203 this, notifier_id, display_source)); 204 } 205 206 void MessageCenterTray::OnNotificationAdded( 207 const std::string& notification_id) { 208 OnMessageCenterChanged(); 209 } 210 211 void MessageCenterTray::OnNotificationRemoved( 212 const std::string& notification_id, 213 bool by_user) { 214 OnMessageCenterChanged(); 215 } 216 217 void MessageCenterTray::OnNotificationUpdated( 218 const std::string& notification_id) { 219 OnMessageCenterChanged(); 220 } 221 222 void MessageCenterTray::OnNotificationClicked( 223 const std::string& notification_id) { 224 if (popups_visible_) 225 OnMessageCenterChanged(); 226 } 227 228 void MessageCenterTray::OnNotificationButtonClicked( 229 const std::string& notification_id, 230 int button_index) { 231 if (popups_visible_) 232 OnMessageCenterChanged(); 233 } 234 235 void MessageCenterTray::OnNotificationDisplayed( 236 const std::string& notification_id, 237 const DisplaySource source) { 238 NotifyMessageCenterTrayChanged(); 239 } 240 241 void MessageCenterTray::OnQuietModeChanged(bool in_quiet_mode) { 242 NotifyMessageCenterTrayChanged(); 243 } 244 245 void MessageCenterTray::OnBlockingStateChanged(NotificationBlocker* blocker) { 246 OnMessageCenterChanged(); 247 } 248 249 void MessageCenterTray::OnMessageCenterChanged() { 250 if (message_center_visible_ && message_center_->NotificationCount() == 0) 251 HideMessageCenterBubble(); 252 253 if (popups_visible_ && !message_center_->HasPopupNotifications()) 254 HidePopupBubbleInternal(); 255 else if (!popups_visible_ && message_center_->HasPopupNotifications()) 256 ShowPopupBubble(); 257 258 NotifyMessageCenterTrayChanged(); 259 } 260 261 void MessageCenterTray::NotifyMessageCenterTrayChanged() { 262 delegate_->OnMessageCenterTrayChanged(); 263 } 264 265 } // namespace message_center 266