- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / views / extensions / bundle_installed_bubble.cc
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 "base/i18n/rtl.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "chrome/browser/extensions/bundle_installer.h"
8 #include "chrome/browser/ui/browser.h"
9 #include "chrome/browser/ui/views/frame/browser_view.h"
10 #include "chrome/browser/ui/views/toolbar_view.h"
11 #include "grit/chromium_strings.h"
12 #include "grit/generated_resources.h"
13 #include "grit/theme_resources.h"
14 #include "grit/ui_resources.h"
15 #include "ui/base/l10n/l10n_util.h"
16 #include "ui/base/resource/resource_bundle.h"
17 #include "ui/views/bubble/bubble_delegate.h"
18 #include "ui/views/controls/button/image_button.h"
19 #include "ui/views/controls/image_view.h"
20 #include "ui/views/controls/label.h"
21 #include "ui/views/layout/grid_layout.h"
22 #include "ui/views/layout/layout_constants.h"
23
24 using extensions::BundleInstaller;
25 using views::GridLayout;
26
27 namespace {
28
29 // The ID of the column set for the bubble.
30 const int kColumnSetId = 0;
31
32 // The width of the left column.
33 const int kLeftColumnWidth = 325;
34
35 class BundleInstalledBubble : public views::BubbleDelegateView,
36                               public views::ButtonListener {
37  public:
38   BundleInstalledBubble(const BundleInstaller* bundle,
39                         View* anchor_view,
40                         views::BubbleBorder::Arrow arrow)
41       : views::BubbleDelegateView(anchor_view, arrow) {
42     GridLayout* layout = GridLayout::CreatePanel(this);
43     SetLayoutManager(layout);
44     views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId);
45
46     column_set->AddColumn(GridLayout::LEADING,
47                           GridLayout::FILL,
48                           0,  // no resizing
49                           GridLayout::USE_PREF,
50                           0,  // no fixed with
51                           kLeftColumnWidth);
52     column_set->AddPaddingColumn(0, views::kPanelHorizMargin);
53     column_set->AddColumn(GridLayout::LEADING,
54                           GridLayout::LEADING,
55                           0,  // no resizing
56                           GridLayout::USE_PREF,
57                           0,  // no fixed width
58                           0); // no min width (only holds close button)
59
60     layout->StartRow(0, kColumnSetId);
61
62     AddContent(layout, bundle);
63   }
64
65   virtual ~BundleInstalledBubble() {}
66
67  private:
68   void AddContent(GridLayout* layout, const BundleInstaller* bundle) {
69     string16 installed_heading = bundle->GetHeadingTextFor(
70         BundleInstaller::Item::STATE_INSTALLED);
71     string16 failed_heading = bundle->GetHeadingTextFor(
72         BundleInstaller::Item::STATE_FAILED);
73
74     // Insert the list of installed items.
75     if (!installed_heading.empty()) {
76       layout->StartRow(0, kColumnSetId);
77       AddHeading(layout, installed_heading);
78       AddCloseButton(layout, this);
79       AddItemList(layout, bundle->GetItemsWithState(
80           BundleInstaller::Item::STATE_INSTALLED));
81
82       // Insert a line of padding if we're showing both sections.
83       if (!failed_heading.empty())
84         layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
85     }
86
87     // Insert the list of failed items.
88     if (!failed_heading.empty()) {
89       layout->StartRow(0, kColumnSetId);
90       AddHeading(layout, failed_heading);
91
92       // The close button should be in the second column of the first row, so
93       // we add it here if there was no installed items section.
94       if (installed_heading.empty())
95         AddCloseButton(layout, this);
96
97       AddItemList(layout, bundle->GetItemsWithState(
98           BundleInstaller::Item::STATE_FAILED));
99     }
100
101     views::BubbleDelegateView::CreateBubble(this);
102     StartFade(true);
103   }
104
105   void AddItemList(GridLayout* layout, const BundleInstaller::ItemList& items) {
106     for (size_t i = 0; i < items.size(); ++i) {
107       string16 extension_name = UTF8ToUTF16(items[i].localized_name);
108       base::i18n::AdjustStringForLocaleDirection(&extension_name);
109       layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
110       layout->StartRow(0, kColumnSetId);
111       views::Label* extension_label = new views::Label(
112           l10n_util::GetStringFUTF16(
113               IDS_EXTENSION_PERMISSION_LINE, extension_name));
114       extension_label->SetMultiLine(true);
115       extension_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
116       extension_label->SizeToFit(kLeftColumnWidth);
117       layout->AddView(extension_label);
118     }
119   }
120
121   void AddCloseButton(GridLayout* layout, views::ButtonListener* listener) {
122     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
123
124     views::ImageButton* button = new views::ImageButton(listener);
125     button->SetImage(views::CustomButton::STATE_NORMAL,
126                      rb.GetImageSkiaNamed(IDR_CLOSE_2));
127     button->SetImage(views::CustomButton::STATE_HOVERED,
128                      rb.GetImageSkiaNamed(IDR_CLOSE_2_H));
129     button->SetImage(views::CustomButton::STATE_PRESSED,
130                      rb.GetImageSkiaNamed(IDR_CLOSE_2_P));
131     layout->AddView(button);
132   }
133
134   void AddHeading(GridLayout* layout, const string16& heading) {
135     ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
136     views::Label* heading_label = new views::Label(
137         heading, rb.GetFont(ui::ResourceBundle::MediumFont));
138     heading_label->SetMultiLine(true);
139     heading_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
140     heading_label->SizeToFit(kLeftColumnWidth);
141     layout->AddView(heading_label);
142   }
143
144   // views::ButtonListener implementation:
145   virtual void ButtonPressed(views::Button* sender,
146                              const ui::Event& event) OVERRIDE {
147     StartFade(false);
148   }
149
150   DISALLOW_COPY_AND_ASSIGN(BundleInstalledBubble);
151 };
152
153 }  // namespace
154
155 void BundleInstaller::ShowInstalledBubble(
156     const BundleInstaller* bundle, Browser* browser) {
157   BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
158   views::View* anchor = browser_view->GetToolbarView()->app_menu();
159   new BundleInstalledBubble(bundle, anchor, views::BubbleBorder::TOP_RIGHT);
160 }