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