Home | History | Annotate | Download | only in date
      1 // Copyright (c) 2012 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 "ash/system/date/tray_date.h"
      6 
      7 #include "ash/metrics/user_metrics_recorder.h"
      8 #include "ash/session_state_delegate.h"
      9 #include "ash/shell.h"
     10 #include "ash/shell_delegate.h"
     11 #include "ash/system/date/date_view.h"
     12 #include "ash/system/tray/system_tray.h"
     13 #include "ash/system/tray/system_tray_delegate.h"
     14 #include "ash/system/tray/system_tray_notifier.h"
     15 #include "ash/system/tray/tray_constants.h"
     16 #include "ash/system/tray/tray_item_view.h"
     17 #include "ash/system/tray/tray_popup_header_button.h"
     18 #include "base/i18n/time_formatting.h"
     19 #include "base/strings/stringprintf.h"
     20 #include "base/strings/utf_string_conversions.h"
     21 #include "base/time/time.h"
     22 #include "base/timer/timer.h"
     23 #include "grit/ash_resources.h"
     24 #include "grit/ash_strings.h"
     25 #include "third_party/icu/source/i18n/unicode/datefmt.h"
     26 #include "third_party/icu/source/i18n/unicode/fieldpos.h"
     27 #include "third_party/icu/source/i18n/unicode/fmtable.h"
     28 #include "third_party/skia/include/core/SkRect.h"
     29 #include "ui/base/l10n/l10n_util.h"
     30 #include "ui/base/resource/resource_bundle.h"
     31 #include "ui/gfx/image/image.h"
     32 #include "ui/gfx/image/image_skia.h"
     33 #include "ui/gfx/size.h"
     34 #include "ui/views/controls/button/button.h"
     35 #include "ui/views/controls/image_view.h"
     36 #include "ui/views/controls/label.h"
     37 #include "ui/views/layout/box_layout.h"
     38 #include "ui/views/layout/fill_layout.h"
     39 #include "ui/views/painter.h"
     40 #include "ui/views/view.h"
     41 #include "ui/views/widget/widget.h"
     42 
     43 #if defined(OS_CHROMEOS)
     44 #include "ash/system/chromeos/system_clock_observer.h"
     45 #endif
     46 
     47 namespace {
     48 
     49 const int kPaddingVertical = 19;
     50 
     51 }  // namespace
     52 
     53 namespace ash {
     54 namespace internal {
     55 
     56 class DateDefaultView : public views::View,
     57                         public views::ButtonListener {
     58  public:
     59   explicit DateDefaultView(ash::user::LoginStatus login)
     60       : help_(NULL),
     61         shutdown_(NULL),
     62         lock_(NULL),
     63         date_view_(NULL) {
     64     SetLayoutManager(new views::FillLayout);
     65 
     66     date_view_ = new tray::DateView();
     67     date_view_->set_border(views::Border::CreateEmptyBorder(kPaddingVertical,
     68         ash::kTrayPopupPaddingHorizontal,
     69         0,
     70         0));
     71     SpecialPopupRow* view = new SpecialPopupRow();
     72     view->SetContent(date_view_);
     73     AddChildView(view);
     74 
     75     if (login == ash::user::LOGGED_IN_LOCKED ||
     76         login == ash::user::LOGGED_IN_NONE)
     77       return;
     78 
     79     date_view_->SetActionable(true);
     80 
     81     help_ = new TrayPopupHeaderButton(this,
     82         IDR_AURA_UBER_TRAY_HELP,
     83         IDR_AURA_UBER_TRAY_HELP,
     84         IDR_AURA_UBER_TRAY_HELP_HOVER,
     85         IDR_AURA_UBER_TRAY_HELP_HOVER,
     86         IDS_ASH_STATUS_TRAY_HELP);
     87     help_->SetTooltipText(l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_HELP));
     88     view->AddButton(help_);
     89 
     90 #if !defined(OS_WIN)
     91     if (login != ash::user::LOGGED_IN_LOCKED &&
     92         login != ash::user::LOGGED_IN_RETAIL_MODE) {
     93       shutdown_ = new TrayPopupHeaderButton(this,
     94           IDR_AURA_UBER_TRAY_SHUTDOWN,
     95           IDR_AURA_UBER_TRAY_SHUTDOWN,
     96           IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER,
     97           IDR_AURA_UBER_TRAY_SHUTDOWN_HOVER,
     98           IDS_ASH_STATUS_TRAY_SHUTDOWN);
     99       shutdown_->SetTooltipText(
    100           l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_SHUTDOWN));
    101       view->AddButton(shutdown_);
    102     }
    103 
    104     if (ash::Shell::GetInstance()->session_state_delegate()->CanLockScreen()) {
    105       lock_ = new TrayPopupHeaderButton(this,
    106           IDR_AURA_UBER_TRAY_LOCKSCREEN,
    107           IDR_AURA_UBER_TRAY_LOCKSCREEN,
    108           IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER,
    109           IDR_AURA_UBER_TRAY_LOCKSCREEN_HOVER,
    110           IDS_ASH_STATUS_TRAY_LOCK);
    111       lock_->SetTooltipText(
    112           l10n_util::GetStringUTF16(IDS_ASH_STATUS_TRAY_LOCK));
    113       view->AddButton(lock_);
    114     }
    115 #endif  // !defined(OS_WIN)
    116   }
    117 
    118   virtual ~DateDefaultView() {}
    119 
    120   views::View* GetHelpButtonView() const {
    121     return help_;
    122   }
    123 
    124   tray::DateView* GetDateView() const {
    125     return date_view_;
    126   }
    127 
    128  private:
    129   // Overridden from views::ButtonListener.
    130   virtual void ButtonPressed(views::Button* sender,
    131                              const ui::Event& event) OVERRIDE {
    132     ash::Shell* shell = ash::Shell::GetInstance();
    133     ash::SystemTrayDelegate* tray_delegate = shell->system_tray_delegate();
    134     if (sender == help_) {
    135       shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_HELP);
    136       tray_delegate->ShowHelp();
    137     } else if (sender == shutdown_) {
    138       shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_SHUT_DOWN);
    139       tray_delegate->ShutDown();
    140     } else if (sender == lock_) {
    141       shell->metrics()->RecordUserMetricsAction(ash::UMA_TRAY_LOCK_SCREEN);
    142       tray_delegate->RequestLockScreen();
    143     } else {
    144       NOTREACHED();
    145     }
    146   }
    147 
    148   TrayPopupHeaderButton* help_;
    149   TrayPopupHeaderButton* shutdown_;
    150   TrayPopupHeaderButton* lock_;
    151   tray::DateView* date_view_;
    152 
    153   DISALLOW_COPY_AND_ASSIGN(DateDefaultView);
    154 };
    155 
    156 TrayDate::TrayDate(SystemTray* system_tray)
    157     : SystemTrayItem(system_tray),
    158       time_tray_(NULL),
    159       default_view_(NULL) {
    160 #if defined(OS_CHROMEOS)
    161   system_clock_observer_.reset(new SystemClockObserver());
    162 #endif
    163   Shell::GetInstance()->system_tray_notifier()->AddClockObserver(this);
    164 }
    165 
    166 TrayDate::~TrayDate() {
    167   Shell::GetInstance()->system_tray_notifier()->RemoveClockObserver(this);
    168 }
    169 
    170 views::View* TrayDate::GetHelpButtonView() const {
    171   if (!default_view_)
    172     return NULL;
    173   return default_view_->GetHelpButtonView();
    174 }
    175 
    176 views::View* TrayDate::CreateTrayView(user::LoginStatus status) {
    177   CHECK(time_tray_ == NULL);
    178   ClockLayout clock_layout =
    179       (system_tray()->shelf_alignment() == SHELF_ALIGNMENT_BOTTOM ||
    180        system_tray()->shelf_alignment() == SHELF_ALIGNMENT_TOP) ?
    181           HORIZONTAL_CLOCK : VERTICAL_CLOCK;
    182   time_tray_ = new tray::TimeView(clock_layout);
    183   views::View* view = new TrayItemView(this);
    184   view->AddChildView(time_tray_);
    185   return view;
    186 }
    187 
    188 views::View* TrayDate::CreateDefaultView(user::LoginStatus status) {
    189   default_view_ = new DateDefaultView(status);
    190   return default_view_;
    191 }
    192 
    193 views::View* TrayDate::CreateDetailedView(user::LoginStatus status) {
    194   return NULL;
    195 }
    196 
    197 void TrayDate::DestroyTrayView() {
    198   time_tray_ = NULL;
    199 }
    200 
    201 void TrayDate::DestroyDefaultView() {
    202   default_view_ = NULL;
    203 }
    204 
    205 void TrayDate::DestroyDetailedView() {
    206 }
    207 
    208 void TrayDate::UpdateAfterLoginStatusChange(user::LoginStatus status) {
    209 }
    210 
    211 void TrayDate::UpdateAfterShelfAlignmentChange(ShelfAlignment alignment) {
    212   if (time_tray_) {
    213     ClockLayout clock_layout = (alignment == SHELF_ALIGNMENT_BOTTOM ||
    214         alignment == SHELF_ALIGNMENT_TOP) ?
    215             HORIZONTAL_CLOCK : VERTICAL_CLOCK;
    216     time_tray_->UpdateClockLayout(clock_layout);
    217   }
    218 }
    219 
    220 void TrayDate::OnDateFormatChanged() {
    221   if (time_tray_)
    222     time_tray_->UpdateTimeFormat();
    223   if (default_view_)
    224     default_view_->GetDateView()->UpdateTimeFormat();
    225 }
    226 
    227 void TrayDate::OnSystemClockTimeUpdated() {
    228   if (time_tray_)
    229     time_tray_->UpdateTimeFormat();
    230   if (default_view_)
    231     default_view_->GetDateView()->UpdateTimeFormat();
    232 }
    233 
    234 void TrayDate::Refresh() {
    235   if (time_tray_)
    236     time_tray_->UpdateText();
    237 }
    238 
    239 }  // namespace internal
    240 }  // namespace ash
    241