Home | History | Annotate | Download | only in notifications
      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 "chrome/browser/ui/cocoa/notifications/message_center_tray_bridge.h"
      6 
      7 #include "base/bind.h"
      8 #include "base/i18n/number_formatting.h"
      9 #include "base/message_loop/message_loop.h"
     10 #include "chrome/browser/browser_process.h"
     11 #include "grit/chromium_strings.h"
     12 #include "grit/generated_resources.h"
     13 #include "grit/ui_strings.h"
     14 #include "ui/base/l10n/l10n_util.h"
     15 #import "ui/base/l10n/l10n_util_mac.h"
     16 #import "ui/message_center/cocoa/popup_collection.h"
     17 #import "ui/message_center/cocoa/status_item_view.h"
     18 #import "ui/message_center/cocoa/tray_controller.h"
     19 #import "ui/message_center/cocoa/tray_view_controller.h"
     20 #include "ui/message_center/message_center.h"
     21 #include "ui/message_center/message_center_tray.h"
     22 
     23 namespace message_center {
     24 
     25 MessageCenterTrayDelegate* CreateMessageCenterTray() {
     26   return new MessageCenterTrayBridge(g_browser_process->message_center());
     27 }
     28 
     29 }  // namespace message_center
     30 
     31 MessageCenterTrayBridge::MessageCenterTrayBridge(
     32     message_center::MessageCenter* message_center)
     33     : message_center_(message_center),
     34       tray_(new message_center::MessageCenterTray(this, message_center)),
     35       weak_ptr_factory_(this) {
     36 }
     37 
     38 MessageCenterTrayBridge::~MessageCenterTrayBridge() {
     39   [status_item_view_ removeItem];
     40 }
     41 
     42 void MessageCenterTrayBridge::OnMessageCenterTrayChanged() {
     43   // Update the status item on the next run of the message loop so that if a
     44   // popup is displayed, the item doesn't flash the unread count.
     45   base::MessageLoop::current()->PostTask(FROM_HERE,
     46       base::Bind(&MessageCenterTrayBridge::UpdateStatusItem,
     47                  weak_ptr_factory_.GetWeakPtr()));
     48 
     49   [tray_controller_ onMessageCenterTrayChanged];
     50 }
     51 
     52 bool MessageCenterTrayBridge::ShowPopups() {
     53   popup_collection_.reset(
     54       [[MCPopupCollection alloc] initWithMessageCenter:message_center_]);
     55   return true;
     56 }
     57 
     58 void MessageCenterTrayBridge::HidePopups() {
     59   popup_collection_.reset();
     60 }
     61 
     62 bool MessageCenterTrayBridge::ShowMessageCenter() {
     63   if (tray_controller_)
     64     return false;
     65 
     66   OpenTrayWindow();
     67   return true;
     68 }
     69 
     70 void MessageCenterTrayBridge::HideMessageCenter() {
     71   [status_item_view_ setHighlight:NO];
     72   [tray_controller_ close];
     73   tray_controller_.autorelease();
     74   UpdateStatusItem();
     75 }
     76 
     77 bool MessageCenterTrayBridge::ShowNotifierSettings() {
     78   // This method needs to be implemented when the context menu of each
     79   // notification is ready and it contains 'settings' menu item.
     80   return false;
     81 }
     82 
     83 message_center::MessageCenterTray*
     84 MessageCenterTrayBridge::GetMessageCenterTray() {
     85   return tray_.get();
     86 }
     87 
     88 void MessageCenterTrayBridge::UpdateStatusItem() {
     89   if (!status_item_view_) {
     90     status_item_view_.reset([[MCStatusItemView alloc] init]);
     91     [status_item_view_ setCallback:^{ tray_->ToggleMessageCenterBubble(); }];
     92   }
     93 
     94   // We want a static message center icon while it's visible.
     95   if (message_center()->IsMessageCenterVisible())
     96     return;
     97 
     98   size_t unread_count = message_center_->UnreadNotificationCount();
     99   bool quiet_mode = message_center_->IsQuietMode();
    100   [status_item_view_ setUnreadCount:unread_count withQuietMode:quiet_mode];
    101 
    102   if (unread_count > 0) {
    103     string16 unread_count_string = base::FormatNumber(unread_count);
    104     [status_item_view_ setToolTip:
    105         l10n_util::GetNSStringF(IDS_MESSAGE_CENTER_TOOLTIP_UNREAD,
    106             unread_count_string)];
    107   } else {
    108     [status_item_view_ setToolTip:
    109         l10n_util::GetNSString(IDS_MESSAGE_CENTER_TOOLTIP)];
    110   }
    111 }
    112 
    113 void MessageCenterTrayBridge::OpenTrayWindow() {
    114   DCHECK(!tray_controller_);
    115   tray_controller_.reset(
    116       [[MCTrayController alloc] initWithMessageCenterTray:tray_.get()]);
    117   [[tray_controller_ viewController] setTrayTitle:
    118       l10n_util::GetNSStringF(IDS_MESSAGE_CENTER_FOOTER_WITH_PRODUCT_TITLE,
    119           l10n_util::GetStringUTF16(IDS_SHORT_PRODUCT_NAME))];
    120 
    121   UpdateStatusItem();
    122 
    123   [status_item_view_ setHighlight:YES];
    124   NSRect frame = [[status_item_view_ window] frame];
    125   [tray_controller_ showTrayAtRightOf:NSMakePoint(NSMinX(frame),
    126                                                   NSMinY(frame))
    127                              atLeftOf:NSMakePoint(NSMaxX(frame),
    128                                                   NSMinY(frame))];
    129 }
    130