| Index: chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc
|
| diff --git a/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..36a9ec50d7c1c28716ef9b456770de0b6d0f368b
|
| --- /dev/null
|
| +++ b/chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.cc
|
| @@ -0,0 +1,650 @@
|
| +// Copyright 2014 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 "chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_tab.h"
|
| +
|
| +#include <vector>
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/command_line.h"
|
| +#include "base/strings/utf_string_conversions.h"
|
| +#include "chrome/browser/extensions/extension_service.h"
|
| +#include "chrome/browser/extensions/extension_util.h"
|
| +#include "chrome/browser/extensions/image_loader.h"
|
| +#include "chrome/browser/extensions/launch_util.h"
|
| +#include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/ui/browser_dialogs.h"
|
| +#include "chrome/browser/ui/browser_navigator.h"
|
| +#include "chrome/common/chrome_switches.h"
|
| +#include "chrome/common/extensions/extension_constants.h"
|
| +#include "chrome/common/extensions/manifest_url_handler.h"
|
| +#include "extensions/browser/extension_prefs.h"
|
| +#include "extensions/browser/extension_system.h"
|
| +#include "extensions/common/constants.h"
|
| +#include "extensions/common/extension.h"
|
| +#include "extensions/common/extension_icon_set.h"
|
| +#include "extensions/common/manifest_handlers/icons_handler.h"
|
| +#include "extensions/common/manifest_handlers/shared_module_info.h"
|
| +#include "grit/generated_resources.h"
|
| +#include "net/base/url_util.h"
|
| +#include "ui/base/l10n/l10n_util.h"
|
| +#include "ui/base/resource/resource_bundle.h"
|
| +#include "ui/gfx/geometry/size.h"
|
| +#include "ui/gfx/image/image.h"
|
| +#include "ui/gfx/image/image_skia.h"
|
| +#include "ui/views/controls/button/label_button.h"
|
| +#include "ui/views/controls/combobox/combobox.h"
|
| +#include "ui/views/controls/image_view.h"
|
| +#include "ui/views/controls/label.h"
|
| +#include "ui/views/controls/link.h"
|
| +#include "ui/views/layout/box_layout.h"
|
| +#include "ui/views/layout/grid_layout.h"
|
| +#include "ui/views/layout/layout_constants.h"
|
| +#include "ui/views/widget/widget.h"
|
| +#include "url/gurl.h"
|
| +
|
| +// Size of extension icon in top left of dialog.
|
| +const int kIconSize = 64;
|
| +
|
| +namespace {
|
| +
|
| +// A small summary panel with the app's name, icon, version, and a link to the
|
| +// web store (if they exist).
|
| +class AppInfoSummaryPanel : public views::View,
|
| + public views::LinkListener,
|
| + public base::SupportsWeakPtr<AppInfoSummaryPanel> {
|
| + public:
|
| + AppInfoSummaryPanel(Profile* profile, const extensions::Extension* app);
|
| + virtual ~AppInfoSummaryPanel();
|
| +
|
| + private:
|
| + void CreateControls();
|
| + void LayoutAppNameAndVersionInto(views::View* parent_view);
|
| + void LayoutViews();
|
| +
|
| + // Overridden from views::LinkListener:
|
| + virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
|
| +
|
| + // Load the app icon asynchronously. For the response, check OnAppImageLoaded.
|
| + void LoadAppImageAsync();
|
| + // Called when the app's icon is loaded.
|
| + void OnAppImageLoaded(const gfx::Image& image);
|
| +
|
| + // Opens the app in the web store. Must only be called if
|
| + // CanShowAppInWebStore() returns true.
|
| + void ShowAppInWebStore() const;
|
| + bool CanShowAppInWebStore() const;
|
| +
|
| + views::ImageView* app_icon_;
|
| + views::Label* app_name_label_;
|
| + views::Label* app_version_label_;
|
| + views::Link* view_in_store_link_;
|
| +
|
| + Profile* profile_;
|
| + const extensions::Extension* app_;
|
| +
|
| + base::WeakPtrFactory<AppInfoSummaryPanel> weak_ptr_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(AppInfoSummaryPanel);
|
| +};
|
| +
|
| +AppInfoSummaryPanel::AppInfoSummaryPanel(Profile* profile,
|
| + const extensions::Extension* app)
|
| + : app_icon_(NULL),
|
| + app_name_label_(NULL),
|
| + app_version_label_(NULL),
|
| + view_in_store_link_(NULL),
|
| + profile_(profile),
|
| + app_(app),
|
| + weak_ptr_factory_(this) {
|
| + CreateControls();
|
| +
|
| + // Layout elements.
|
| + SetLayoutManager(
|
| + new views::BoxLayout(views::BoxLayout::kHorizontal,
|
| + 0,
|
| + 0,
|
| + views::kRelatedControlHorizontalSpacing));
|
| +
|
| + AddChildView(app_icon_);
|
| +
|
| + if (!app_version_label_ && !view_in_store_link_) {
|
| + // If there's no link to the webstore _and_ no version, allow the app's name
|
| + // to take up multiple lines.
|
| + app_name_label_->SetMultiLine(true);
|
| + AddChildView(app_name_label_);
|
| + } else {
|
| + // Create a vertical container to store the app's name and info.
|
| + views::View* vertical_container = new views::View();
|
| + views::BoxLayout* vertical_container_layout =
|
| + new views::BoxLayout(views::BoxLayout::kVertical, 0, 0, 0);
|
| + vertical_container_layout->set_main_axis_alignment(
|
| + views::BoxLayout::MAIN_AXIS_ALIGNMENT_CENTER);
|
| + vertical_container->SetLayoutManager(vertical_container_layout);
|
| +
|
| + if (app_version_label_ && view_in_store_link_) {
|
| + // First line: title and version, Second line: web store link.
|
| + LayoutAppNameAndVersionInto(vertical_container);
|
| + vertical_container->AddChildView(view_in_store_link_);
|
| + } else {
|
| + // Put the title on the first line, and whatever other information we have
|
| + // on the second line.
|
| + vertical_container->AddChildView(app_name_label_);
|
| +
|
| + if (app_version_label_) {
|
| + vertical_container->AddChildView(app_version_label_);
|
| + } else if (view_in_store_link_) {
|
| + vertical_container->AddChildView(view_in_store_link_);
|
| + }
|
| + }
|
| +
|
| + AddChildView(vertical_container);
|
| + }
|
| +}
|
| +
|
| +AppInfoSummaryPanel::~AppInfoSummaryPanel() {
|
| +}
|
| +
|
| +void AppInfoSummaryPanel::CreateControls() {
|
| + app_name_label_ =
|
| + new views::Label(base::UTF8ToUTF16(app_->name()),
|
| + ui::ResourceBundle::GetSharedInstance().GetFontList(
|
| + ui::ResourceBundle::BoldFont));
|
| + app_name_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| +
|
| + // The version number doesn't make sense for bookmarked apps.
|
| + if (!app_->from_bookmark()) {
|
| + app_version_label_ =
|
| + new views::Label(base::UTF8ToUTF16(app_->VersionString()));
|
| + app_version_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| + }
|
| +
|
| + app_icon_ = new views::ImageView();
|
| + app_icon_->SetImageSize(gfx::Size(kIconSize, kIconSize));
|
| + LoadAppImageAsync();
|
| +
|
| + if (CanShowAppInWebStore()) {
|
| + view_in_store_link_ = new views::Link(
|
| + l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_WEB_STORE_LINK));
|
| + view_in_store_link_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| + view_in_store_link_->set_listener(this);
|
| + }
|
| +}
|
| +
|
| +void AppInfoSummaryPanel::LayoutAppNameAndVersionInto(
|
| + views::View* parent_view) {
|
| + views::View* view = new views::View();
|
| + // We need a horizontal BoxLayout here to ensure that the GridLayout does
|
| + // not stretch beyond the size of its content.
|
| + view->SetLayoutManager(
|
| + new views::BoxLayout(views::BoxLayout::kHorizontal, 0, 0, 0));
|
| +
|
| + views::View* container_view = new views::View();
|
| + view->AddChildView(container_view);
|
| + views::GridLayout* layout = new views::GridLayout(container_view);
|
| + container_view->SetLayoutManager(layout);
|
| +
|
| + static const int kColumnId = 1;
|
| + views::ColumnSet* column_set = layout->AddColumnSet(kColumnId);
|
| + column_set->AddColumn(views::GridLayout::LEADING,
|
| + views::GridLayout::LEADING,
|
| + 1, // Stretch the title to as wide as needed
|
| + views::GridLayout::USE_PREF,
|
| + 0,
|
| + 0);
|
| + column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
|
| + column_set->AddColumn(views::GridLayout::LEADING,
|
| + views::GridLayout::LEADING,
|
| + 0, // Do not stretch the version
|
| + views::GridLayout::USE_PREF,
|
| + 0,
|
| + 0);
|
| +
|
| + layout->StartRow(1, kColumnId);
|
| + layout->AddView(app_name_label_);
|
| + if (app_version_label_)
|
| + layout->AddView(app_version_label_);
|
| +
|
| + parent_view->AddChildView(view);
|
| +}
|
| +
|
| +void AppInfoSummaryPanel::LinkClicked(views::Link* source, int event_flags) {
|
| + if (source == view_in_store_link_) {
|
| + ShowAppInWebStore();
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| +void AppInfoSummaryPanel::LoadAppImageAsync() {
|
| + extensions::ExtensionResource image = extensions::IconsInfo::GetIconResource(
|
| + app_,
|
| + extension_misc::EXTENSION_ICON_LARGE,
|
| + ExtensionIconSet::MATCH_BIGGER);
|
| + int pixel_size =
|
| + static_cast<int>(kIconSize * gfx::ImageSkia::GetMaxSupportedScale());
|
| + extensions::ImageLoader::Get(profile_)->LoadImageAsync(
|
| + app_,
|
| + image,
|
| + gfx::Size(pixel_size, pixel_size),
|
| + base::Bind(&AppInfoSummaryPanel::OnAppImageLoaded, AsWeakPtr()));
|
| +}
|
| +
|
| +void AppInfoSummaryPanel::OnAppImageLoaded(const gfx::Image& image) {
|
| + const SkBitmap* bitmap;
|
| + if (image.IsEmpty()) {
|
| + bitmap = &extensions::util::GetDefaultAppIcon()
|
| + .GetRepresentation(gfx::ImageSkia::GetMaxSupportedScale())
|
| + .sk_bitmap();
|
| + } else {
|
| + bitmap = image.ToSkBitmap();
|
| + }
|
| +
|
| + app_icon_->SetImage(gfx::ImageSkia::CreateFrom1xBitmap(*bitmap));
|
| +}
|
| +
|
| +void AppInfoSummaryPanel::ShowAppInWebStore() const {
|
| + DCHECK(CanShowAppInWebStore());
|
| + const GURL url = extensions::ManifestURL::GetDetailsURL(app_);
|
| + DCHECK_NE(url, GURL::EmptyGURL());
|
| + chrome::NavigateParams params(
|
| + profile_,
|
| + net::AppendQueryParameter(url,
|
| + extension_urls::kWebstoreSourceField,
|
| + extension_urls::kLaunchSourceAppListInfoDialog),
|
| + content::PAGE_TRANSITION_LINK);
|
| + chrome::Navigate(¶ms);
|
| +}
|
| +
|
| +bool AppInfoSummaryPanel::CanShowAppInWebStore() const {
|
| + return app_->from_webstore();
|
| +}
|
| +
|
| +// A small summary panel with a list of the app's imported modules, and a link
|
| +// to each of their options pages.
|
| +class AppInfoImportedModulesPanel : public views::View,
|
| + public views::LinkListener {
|
| + public:
|
| + AppInfoImportedModulesPanel(Profile* profile,
|
| + const extensions::Extension* app);
|
| + virtual ~AppInfoImportedModulesPanel();
|
| +
|
| + private:
|
| + // Overridden from views::LinkListener:
|
| + virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
|
| +
|
| + Profile* profile_;
|
| + const extensions::Extension* app_;
|
| + std::map<views::Link*, GURL> about_links_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(AppInfoImportedModulesPanel);
|
| +};
|
| +
|
| +AppInfoImportedModulesPanel::AppInfoImportedModulesPanel(
|
| + Profile* profile,
|
| + const extensions::Extension* app)
|
| + : profile_(profile), app_(app) {
|
| + // Create controls.
|
| + views::Label* title =
|
| + new views::Label(l10n_util::GetStringUTF16(
|
| + IDS_APPLICATION_INFO_IMPORTED_MODULES_TITLE_TEXT),
|
| + ui::ResourceBundle::GetSharedInstance().GetFontList(
|
| + ui::ResourceBundle::BoldFont));
|
| + title->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| +
|
| + // Layout elements.
|
| + views::GridLayout* layout = new views::GridLayout(this);
|
| + SetLayoutManager(layout);
|
| +
|
| + static const int kTitleColumnSetId = 1;
|
| + views::ColumnSet* title_column_set = layout->AddColumnSet(kTitleColumnSetId);
|
| + title_column_set->AddColumn(views::GridLayout::LEADING,
|
| + views::GridLayout::LEADING,
|
| + 1, // Stretch the title to as wide as needed
|
| + views::GridLayout::USE_PREF,
|
| + 0,
|
| + 0);
|
| +
|
| + static const int kModulesListColumnSetId = 2;
|
| + views::ColumnSet* column_set = layout->AddColumnSet(kModulesListColumnSetId);
|
| + column_set->AddColumn(views::GridLayout::LEADING,
|
| + views::GridLayout::LEADING,
|
| + 1, // Stretch the title to as wide as needed
|
| + views::GridLayout::USE_PREF,
|
| + 0,
|
| + 0);
|
| + column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
|
| + column_set->AddColumn(views::GridLayout::LEADING,
|
| + views::GridLayout::LEADING,
|
| + 0, // Do not stretch the 'about' link
|
| + views::GridLayout::USE_PREF,
|
| + 0,
|
| + 0);
|
| +
|
| + layout->StartRow(0, kTitleColumnSetId);
|
| + layout->AddView(title);
|
| +
|
| + // Find all the shared modules for this app, and display them in a list.
|
| + // TODO(sashab): Revisit UI layout once shared module usage becomes more
|
| + // common.
|
| + ExtensionService* service =
|
| + extensions::ExtensionSystem::Get(profile_)->extension_service();
|
| + DCHECK(service);
|
| + const std::vector<extensions::SharedModuleInfo::ImportInfo>& imports =
|
| + extensions::SharedModuleInfo::GetImports(app_);
|
| + for (size_t i = 0; i < imports.size(); ++i) {
|
| + const extensions::Extension* imported_module =
|
| + service->GetExtensionById(imports[i].extension_id, true);
|
| + DCHECK(imported_module);
|
| + views::Label* name_label =
|
| + new views::Label(base::UTF8ToUTF16(imported_module->name()));
|
| + name_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| +
|
| + layout->StartRow(0, kModulesListColumnSetId);
|
| + layout->AddView(name_label);
|
| +
|
| + // If this app has an options page, display it as an 'about' link.
|
| + GURL options_page =
|
| + extensions::ManifestURL::GetOptionsPage(imported_module);
|
| + if (options_page != GURL::EmptyGURL()) {
|
| + views::Link* about_link = new views::Link(l10n_util::GetStringUTF16(
|
| + IDS_APPLICATION_INFO_IMPORTED_MODULES_ABOUT_LINK_TEXT));
|
| + about_link->set_listener(this);
|
| + about_links_[about_link] = options_page;
|
| + layout->AddView(about_link);
|
| + }
|
| + }
|
| +}
|
| +
|
| +AppInfoImportedModulesPanel::~AppInfoImportedModulesPanel() {
|
| +}
|
| +
|
| +void AppInfoImportedModulesPanel::LinkClicked(views::Link* source,
|
| + int event_flags) {
|
| + chrome::NavigateParams params(
|
| + profile_, about_links_[source], content::PAGE_TRANSITION_LINK);
|
| + chrome::Navigate(¶ms);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +// A model for a combobox selecting the launch options for a hosted app.
|
| +// Displays different options depending on the host OS.
|
| +class LaunchOptionsComboboxModel : public ui::ComboboxModel {
|
| + public:
|
| + LaunchOptionsComboboxModel();
|
| + virtual ~LaunchOptionsComboboxModel();
|
| +
|
| + extensions::LaunchType GetLaunchTypeAtIndex(int index) const;
|
| + int GetIndexForLaunchType(extensions::LaunchType launch_type) const;
|
| +
|
| + // Overridden from ui::ComboboxModel:
|
| + virtual int GetItemCount() const OVERRIDE;
|
| + virtual base::string16 GetItemAt(int index) OVERRIDE;
|
| +
|
| + private:
|
| + // A list of the launch types available in the combobox, in order.
|
| + std::vector<extensions::LaunchType> launch_types_;
|
| +
|
| + // A list of the messages to display in the combobox, in order. The indexes in
|
| + // this list correspond to the indexes in launch_types_.
|
| + std::vector<base::string16> launch_type_messages_;
|
| +};
|
| +
|
| +LaunchOptionsComboboxModel::LaunchOptionsComboboxModel() {
|
| + if (CommandLine::ForCurrentProcess()->HasSwitch(
|
| + switches::kEnableStreamlinedHostedApps)) {
|
| + // Streamlined hosted apps can only toggle between LAUNCH_TYPE_WINDOW and
|
| + // LAUNCH_TYPE_REGULAR.
|
| + // TODO(sashab): Use a checkbox for this choice instead of combobox.
|
| + launch_types_.push_back(extensions::LAUNCH_TYPE_REGULAR);
|
| + launch_type_messages_.push_back(
|
| + l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_TAB));
|
| +
|
| + // Although LAUNCH_TYPE_WINDOW doesn't work on Mac, the streamlined hosted
|
| + // apps flag isn't available on Mac, so we must be on a non-Mac OS.
|
| + launch_types_.push_back(extensions::LAUNCH_TYPE_WINDOW);
|
| + launch_type_messages_.push_back(
|
| + l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
|
| + } else {
|
| + launch_types_.push_back(extensions::LAUNCH_TYPE_REGULAR);
|
| + launch_type_messages_.push_back(
|
| + l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR));
|
| +
|
| + launch_types_.push_back(extensions::LAUNCH_TYPE_PINNED);
|
| + launch_type_messages_.push_back(
|
| + l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED));
|
| +
|
| +#if defined(OS_MACOSX)
|
| + // Mac does not support standalone web app browser windows or maximize.
|
| + launch_types_.push_back(extensions::LAUNCH_TYPE_FULLSCREEN);
|
| + launch_type_messages_.push_back(
|
| + l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN));
|
| +#else
|
| + launch_types_.push_back(extensions::LAUNCH_TYPE_WINDOW);
|
| + launch_type_messages_.push_back(
|
| + l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
|
| +
|
| + // Even though the launch type is Full Screen, it is more accurately
|
| + // described as Maximized in non-Mac OSs.
|
| + launch_types_.push_back(extensions::LAUNCH_TYPE_FULLSCREEN);
|
| + launch_type_messages_.push_back(
|
| + l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED));
|
| +#endif
|
| + }
|
| +}
|
| +
|
| +LaunchOptionsComboboxModel::~LaunchOptionsComboboxModel() {}
|
| +
|
| +extensions::LaunchType LaunchOptionsComboboxModel::GetLaunchTypeAtIndex(
|
| + int index) const {
|
| + return launch_types_[index];
|
| +}
|
| +
|
| +int LaunchOptionsComboboxModel::GetIndexForLaunchType(
|
| + extensions::LaunchType launch_type) const {
|
| + for (size_t i = 0; i < launch_types_.size(); i++) {
|
| + if (launch_types_[i] == launch_type) {
|
| + return i;
|
| + }
|
| + }
|
| + // If the requested launch type is not available, just select the first one.
|
| + LOG(WARNING) << "Unavailable launch type " << launch_type << " selected.";
|
| + return 0;
|
| +}
|
| +
|
| +int LaunchOptionsComboboxModel::GetItemCount() const {
|
| + return launch_types_.size();
|
| +}
|
| +
|
| +base::string16 LaunchOptionsComboboxModel::GetItemAt(int index) {
|
| + return launch_type_messages_[index];
|
| +}
|
| +
|
| +AppInfoSummaryTab::AppInfoSummaryTab(gfx::NativeWindow parent_window,
|
| + Profile* profile,
|
| + const extensions::Extension* app,
|
| + const base::Closure& close_callback)
|
| + : AppInfoTab(parent_window, profile, app, close_callback),
|
| + app_summary_panel_(NULL),
|
| + app_description_label_(NULL),
|
| + create_shortcuts_button_(NULL),
|
| + uninstall_button_(NULL),
|
| + launch_options_combobox_(NULL) {
|
| + // Create UI elements.
|
| + app_summary_panel_ = new AppInfoSummaryPanel(profile_, app_);
|
| + CreateDescriptionControl();
|
| + CreateLaunchOptionControl();
|
| + CreateButtons();
|
| +
|
| + // Layout elements.
|
| + SetLayoutManager(
|
| + new views::BoxLayout(views::BoxLayout::kVertical,
|
| + views::kButtonHEdgeMarginNew,
|
| + views::kPanelVertMargin,
|
| + views::kUnrelatedControlVerticalSpacing));
|
| +
|
| + AddChildView(app_summary_panel_);
|
| +
|
| + if (app_description_label_)
|
| + AddChildView(app_description_label_);
|
| +
|
| + if (launch_options_combobox_)
|
| + AddChildView(launch_options_combobox_);
|
| +
|
| + if (HasImportedModules())
|
| + AddChildView(new AppInfoImportedModulesPanel(profile_, app_));
|
| +
|
| + LayoutButtons();
|
| +}
|
| +
|
| +AppInfoSummaryTab::~AppInfoSummaryTab() {
|
| + // Destroy view children before their models.
|
| + RemoveAllChildViews(true);
|
| +}
|
| +
|
| +void AppInfoSummaryTab::CreateDescriptionControl() {
|
| + if (!app_->description().empty()) {
|
| + const size_t kMaxLength = 400;
|
| +
|
| + base::string16 text = base::UTF8ToUTF16(app_->description());
|
| + if (text.length() > kMaxLength) {
|
| + text = text.substr(0, kMaxLength);
|
| + text += base::ASCIIToUTF16(" ... ");
|
| + }
|
| +
|
| + app_description_label_ = new views::Label(text);
|
| + app_description_label_->SetMultiLine(true);
|
| + app_description_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
|
| + }
|
| +}
|
| +
|
| +void AppInfoSummaryTab::CreateLaunchOptionControl() {
|
| + if (CanSetLaunchType()) {
|
| + launch_options_combobox_model_.reset(new LaunchOptionsComboboxModel());
|
| + launch_options_combobox_ =
|
| + new views::Combobox(launch_options_combobox_model_.get());
|
| +
|
| + launch_options_combobox_->set_listener(this);
|
| + launch_options_combobox_->SetSelectedIndex(
|
| + launch_options_combobox_model_->GetIndexForLaunchType(GetLaunchType()));
|
| + }
|
| +}
|
| +
|
| +void AppInfoSummaryTab::CreateButtons() {
|
| + if (CanCreateShortcuts()) {
|
| + create_shortcuts_button_ = new views::LabelButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(
|
| + IDS_APPLICATION_INFO_CREATE_SHORTCUTS_BUTTON_TEXT));
|
| + create_shortcuts_button_->SetStyle(views::Button::STYLE_BUTTON);
|
| + }
|
| +
|
| + if (CanUninstallApp()) {
|
| + uninstall_button_ = new views::LabelButton(
|
| + this,
|
| + l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_UNINSTALL_BUTTON_TEXT));
|
| + uninstall_button_->SetStyle(views::Button::STYLE_BUTTON);
|
| + }
|
| +}
|
| +
|
| +void AppInfoSummaryTab::LayoutButtons() {
|
| + views::View* app_buttons = new views::View();
|
| + app_buttons->SetLayoutManager(
|
| + new views::BoxLayout(views::BoxLayout::kHorizontal,
|
| + 0,
|
| + 0,
|
| + views::kRelatedControlVerticalSpacing));
|
| +
|
| + if (create_shortcuts_button_)
|
| + app_buttons->AddChildView(create_shortcuts_button_);
|
| +
|
| + if (uninstall_button_)
|
| + app_buttons->AddChildView(uninstall_button_);
|
| +
|
| + AddChildView(app_buttons);
|
| +}
|
| +
|
| +void AppInfoSummaryTab::OnPerformAction(views::Combobox* combobox) {
|
| + if (combobox == launch_options_combobox_) {
|
| + SetLaunchType(launch_options_combobox_model_->GetLaunchTypeAtIndex(
|
| + launch_options_combobox_->selected_index()));
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| +void AppInfoSummaryTab::ButtonPressed(views::Button* sender,
|
| + const ui::Event& event) {
|
| + if (sender == uninstall_button_) {
|
| + UninstallApp();
|
| + } else if (sender == create_shortcuts_button_) {
|
| + CreateShortcuts();
|
| + } else {
|
| + NOTREACHED();
|
| + }
|
| +}
|
| +
|
| +void AppInfoSummaryTab::ExtensionUninstallAccepted() {
|
| + ExtensionService* service =
|
| + extensions::ExtensionSystem::Get(profile_)->extension_service();
|
| + service->UninstallExtension(app_->id(), false, NULL);
|
| +
|
| + // Close the App Info dialog as well (which will free the dialog too).
|
| + GetWidget()->Close();
|
| +}
|
| +
|
| +void AppInfoSummaryTab::ExtensionUninstallCanceled() {
|
| + extension_uninstall_dialog_.reset();
|
| +}
|
| +
|
| +extensions::LaunchType AppInfoSummaryTab::GetLaunchType() const {
|
| + return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_),
|
| + app_);
|
| +}
|
| +
|
| +void AppInfoSummaryTab::SetLaunchType(
|
| + extensions::LaunchType launch_type) const {
|
| + DCHECK(CanSetLaunchType());
|
| + ExtensionService* service =
|
| + extensions::ExtensionSystem::Get(profile_)->extension_service();
|
| + extensions::SetLaunchType(service, app_->id(), launch_type);
|
| +}
|
| +
|
| +bool AppInfoSummaryTab::CanSetLaunchType() const {
|
| + // V2 apps don't have a launch type.
|
| + return !app_->is_platform_app();
|
| +}
|
| +
|
| +void AppInfoSummaryTab::UninstallApp() {
|
| + DCHECK(CanUninstallApp());
|
| + extension_uninstall_dialog_.reset(
|
| + extensions::ExtensionUninstallDialog::Create(profile_, NULL, this));
|
| + extension_uninstall_dialog_->ConfirmUninstall(app_);
|
| +}
|
| +
|
| +bool AppInfoSummaryTab::CanUninstallApp() const {
|
| + return extensions::ExtensionSystem::Get(profile_)
|
| + ->management_policy()
|
| + ->UserMayModifySettings(app_, NULL);
|
| +}
|
| +
|
| +void AppInfoSummaryTab::CreateShortcuts() {
|
| + DCHECK(CanCreateShortcuts());
|
| + chrome::ShowCreateChromeAppShortcutsDialog(
|
| + parent_window_, profile_, app_, base::Callback<void(bool)>());
|
| +}
|
| +
|
| +bool AppInfoSummaryTab::CanCreateShortcuts() const {
|
| + // ChromeOS can pin apps to the app launcher, but can't create shortcuts.
|
| +#if defined(OS_CHROMEOS)
|
| + return false;
|
| +#else
|
| + return true;
|
| +#endif
|
| +}
|
| +
|
| +bool AppInfoSummaryTab::HasImportedModules() {
|
| + return extensions::SharedModuleInfo::ImportsModules(app_);
|
| +}
|
|
|