blob: fa3f11ad0fe8654f8a4585e66a4e79b4c6fbcc65 [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/i18n/rtl.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/bundle_installer.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
#include "chrome/grit/generated_resources.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/resources/grit/ui_resources.h"
#include "ui/views/bubble/bubble_delegate.h"
#include "ui/views/controls/button/image_button.h"
#include "ui/views/controls/image_view.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/grid_layout.h"
#include "ui/views/layout/layout_constants.h"
using extensions::BundleInstaller;
using views::GridLayout;
namespace {
// The ID of the column set for the bubble.
const int kColumnSetId = 0;
// The width of the left column.
const int kLeftColumnWidth = 325;
class BundleInstalledBubble : public views::BubbleDelegateView,
public views::ButtonListener {
public:
BundleInstalledBubble(const BundleInstaller* bundle,
View* anchor_view,
views::BubbleBorder::Arrow arrow)
: views::BubbleDelegateView(anchor_view, arrow) {
GridLayout* layout = GridLayout::CreatePanel(this);
SetLayoutManager(layout);
views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId);
column_set->AddColumn(GridLayout::LEADING,
GridLayout::FILL,
0, // no resizing
GridLayout::USE_PREF,
0, // no fixed with
kLeftColumnWidth);
column_set->AddPaddingColumn(0, views::kPanelHorizMargin);
column_set->AddColumn(GridLayout::LEADING,
GridLayout::LEADING,
0, // no resizing
GridLayout::USE_PREF,
0, // no fixed width
0); // no min width (only holds close button)
layout->StartRow(0, kColumnSetId);
AddContent(layout, bundle);
}
virtual ~BundleInstalledBubble() {}
private:
void AddContent(GridLayout* layout, const BundleInstaller* bundle) {
base::string16 installed_heading = bundle->GetHeadingTextFor(
BundleInstaller::Item::STATE_INSTALLED);
base::string16 failed_heading = bundle->GetHeadingTextFor(
BundleInstaller::Item::STATE_FAILED);
// Insert the list of installed items.
if (!installed_heading.empty()) {
layout->StartRow(0, kColumnSetId);
AddHeading(layout, installed_heading);
AddCloseButton(layout, this);
AddItemList(layout, bundle->GetItemsWithState(
BundleInstaller::Item::STATE_INSTALLED));
// Insert a line of padding if we're showing both sections.
if (!failed_heading.empty())
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
}
// Insert the list of failed items.
if (!failed_heading.empty()) {
layout->StartRow(0, kColumnSetId);
AddHeading(layout, failed_heading);
// The close button should be in the second column of the first row, so
// we add it here if there was no installed items section.
if (installed_heading.empty())
AddCloseButton(layout, this);
AddItemList(layout, bundle->GetItemsWithState(
BundleInstaller::Item::STATE_FAILED));
}
views::BubbleDelegateView::CreateBubble(this)->Show();
}
void AddItemList(GridLayout* layout, const BundleInstaller::ItemList& items) {
for (size_t i = 0; i < items.size(); ++i) {
base::string16 extension_name =
base::UTF8ToUTF16(items[i].localized_name);
base::i18n::AdjustStringForLocaleDirection(&extension_name);
layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
layout->StartRow(0, kColumnSetId);
views::Label* extension_label = new views::Label(
l10n_util::GetStringFUTF16(
IDS_EXTENSION_PERMISSION_LINE, extension_name));
extension_label->SetMultiLine(true);
extension_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
extension_label->SizeToFit(kLeftColumnWidth);
layout->AddView(extension_label);
}
}
void AddCloseButton(GridLayout* layout, views::ButtonListener* listener) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
views::ImageButton* button = new views::ImageButton(listener);
button->SetImage(views::CustomButton::STATE_NORMAL,
rb.GetImageSkiaNamed(IDR_CLOSE_2));
button->SetImage(views::CustomButton::STATE_HOVERED,
rb.GetImageSkiaNamed(IDR_CLOSE_2_H));
button->SetImage(views::CustomButton::STATE_PRESSED,
rb.GetImageSkiaNamed(IDR_CLOSE_2_P));
layout->AddView(button);
}
void AddHeading(GridLayout* layout, const base::string16& heading) {
ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance();
views::Label* heading_label = new views::Label(
heading, rb.GetFontList(ui::ResourceBundle::MediumFont));
heading_label->SetMultiLine(true);
heading_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
heading_label->SizeToFit(kLeftColumnWidth);
layout->AddView(heading_label);
}
// views::ButtonListener implementation:
virtual void ButtonPressed(views::Button* sender,
const ui::Event& event) override {
GetWidget()->Close();
}
DISALLOW_COPY_AND_ASSIGN(BundleInstalledBubble);
};
} // namespace
void BundleInstaller::ShowInstalledBubble(
const BundleInstaller* bundle, Browser* browser) {
BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
views::View* anchor = browser_view->GetToolbarView()->app_menu();
new BundleInstalledBubble(bundle, anchor, views::BubbleBorder::TOP_RIGHT);
}