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