1 // Copyright 2014 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.
5 #include "chrome/browser/ui/views/apps/app_info_dialog/app_info_summary_panel.h"
9 #include "base/callback_forward.h"
10 #include "base/command_line.h"
11 #include "base/logging.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/launch_util.h"
15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/common/chrome_switches.h"
17 #include "extensions/browser/extension_prefs.h"
18 #include "extensions/browser/extension_system.h"
19 #include "extensions/common/extension.h"
20 #include "grit/generated_resources.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/models/combobox_model.h"
23 #include "ui/views/controls/combobox/combobox.h"
24 #include "ui/views/controls/label.h"
25 #include "ui/views/layout/box_layout.h"
26 #include "ui/views/layout/layout_constants.h"
27 #include "ui/views/view.h"
28 #include "ui/views/widget/widget.h"
30 // A model for a combobox selecting the launch options for a hosted app.
31 // Displays different options depending on the host OS.
32 class LaunchOptionsComboboxModel : public ui::ComboboxModel {
34 LaunchOptionsComboboxModel();
35 virtual ~LaunchOptionsComboboxModel();
37 extensions::LaunchType GetLaunchTypeAtIndex(int index) const;
38 int GetIndexForLaunchType(extensions::LaunchType launch_type) const;
40 // Overridden from ui::ComboboxModel:
41 virtual int GetItemCount() const OVERRIDE;
42 virtual base::string16 GetItemAt(int index) OVERRIDE;
45 // A list of the launch types available in the combobox, in order.
46 std::vector<extensions::LaunchType> launch_types_;
48 // A list of the messages to display in the combobox, in order. The indexes in
49 // this list correspond to the indexes in launch_types_.
50 std::vector<base::string16> launch_type_messages_;
53 LaunchOptionsComboboxModel::LaunchOptionsComboboxModel() {
54 if (CommandLine::ForCurrentProcess()->HasSwitch(
55 switches::kEnableStreamlinedHostedApps)) {
56 // Streamlined hosted apps can only toggle between LAUNCH_TYPE_WINDOW and
57 // LAUNCH_TYPE_REGULAR.
58 // TODO(sashab): Use a checkbox for this choice instead of combobox.
59 launch_types_.push_back(extensions::LAUNCH_TYPE_REGULAR);
60 launch_type_messages_.push_back(
61 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_TAB));
63 // Although LAUNCH_TYPE_WINDOW doesn't work on Mac, the streamlined hosted
64 // apps flag isn't available on Mac, so we must be on a non-Mac OS.
65 launch_types_.push_back(extensions::LAUNCH_TYPE_WINDOW);
66 launch_type_messages_.push_back(
67 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
69 launch_types_.push_back(extensions::LAUNCH_TYPE_REGULAR);
70 launch_type_messages_.push_back(
71 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_REGULAR));
73 launch_types_.push_back(extensions::LAUNCH_TYPE_PINNED);
74 launch_type_messages_.push_back(
75 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_PINNED));
77 #if defined(OS_MACOSX)
78 // Mac does not support standalone web app browser windows or maximize.
79 launch_types_.push_back(extensions::LAUNCH_TYPE_FULLSCREEN);
80 launch_type_messages_.push_back(
81 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_FULLSCREEN));
83 launch_types_.push_back(extensions::LAUNCH_TYPE_WINDOW);
84 launch_type_messages_.push_back(
85 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_WINDOW));
87 // Even though the launch type is Full Screen, it is more accurately
88 // described as Maximized in non-Mac OSs.
89 launch_types_.push_back(extensions::LAUNCH_TYPE_FULLSCREEN);
90 launch_type_messages_.push_back(
91 l10n_util::GetStringUTF16(IDS_APP_CONTEXT_MENU_OPEN_MAXIMIZED));
96 LaunchOptionsComboboxModel::~LaunchOptionsComboboxModel() {
99 extensions::LaunchType LaunchOptionsComboboxModel::GetLaunchTypeAtIndex(
101 return launch_types_[index];
104 int LaunchOptionsComboboxModel::GetIndexForLaunchType(
105 extensions::LaunchType launch_type) const {
106 for (size_t i = 0; i < launch_types_.size(); i++) {
107 if (launch_types_[i] == launch_type) {
111 // If the requested launch type is not available, just select the first one.
112 LOG(WARNING) << "Unavailable launch type " << launch_type << " selected.";
116 int LaunchOptionsComboboxModel::GetItemCount() const {
117 return launch_types_.size();
120 base::string16 LaunchOptionsComboboxModel::GetItemAt(int index) {
121 return launch_type_messages_[index];
124 AppInfoSummaryPanel::AppInfoSummaryPanel(Profile* profile,
125 const extensions::Extension* app)
126 : AppInfoPanel(profile, app),
127 description_heading_(NULL),
128 description_label_(NULL),
129 launch_options_combobox_(NULL) {
130 // Create UI elements.
131 CreateDescriptionControl();
132 CreateLaunchOptionControl();
136 new views::BoxLayout(views::BoxLayout::kVertical,
139 views::kUnrelatedControlVerticalSpacing));
141 LayoutDescriptionControl();
143 if (launch_options_combobox_)
144 AddChildView(launch_options_combobox_);
147 AppInfoSummaryPanel::~AppInfoSummaryPanel() {
148 // Destroy view children before their models.
149 RemoveAllChildViews(true);
152 void AppInfoSummaryPanel::CreateDescriptionControl() {
153 if (!app_->description().empty()) {
154 const size_t kMaxLength = 400;
156 base::string16 text = base::UTF8ToUTF16(app_->description());
157 if (text.length() > kMaxLength) {
158 text = text.substr(0, kMaxLength);
159 text += base::ASCIIToUTF16(" ... ");
162 description_heading_ = CreateHeading(
163 l10n_util::GetStringUTF16(IDS_APPLICATION_INFO_DESCRIPTION_TITLE));
164 description_label_ = new views::Label(text);
165 description_label_->SetMultiLine(true);
166 description_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
170 void AppInfoSummaryPanel::CreateLaunchOptionControl() {
171 if (CanSetLaunchType()) {
172 launch_options_combobox_model_.reset(new LaunchOptionsComboboxModel());
173 launch_options_combobox_ =
174 new views::Combobox(launch_options_combobox_model_.get());
176 launch_options_combobox_->set_listener(this);
177 launch_options_combobox_->SetSelectedIndex(
178 launch_options_combobox_model_->GetIndexForLaunchType(GetLaunchType()));
182 void AppInfoSummaryPanel::LayoutDescriptionControl() {
183 if (description_label_) {
184 DCHECK(description_heading_);
185 views::View* vertical_stack = CreateVerticalStack();
186 vertical_stack->AddChildView(description_heading_);
187 vertical_stack->AddChildView(description_label_);
188 AddChildView(vertical_stack);
192 void AppInfoSummaryPanel::OnPerformAction(views::Combobox* combobox) {
193 if (combobox == launch_options_combobox_) {
194 SetLaunchType(launch_options_combobox_model_->GetLaunchTypeAtIndex(
195 launch_options_combobox_->selected_index()));
201 extensions::LaunchType AppInfoSummaryPanel::GetLaunchType() const {
202 return extensions::GetLaunchType(extensions::ExtensionPrefs::Get(profile_),
206 void AppInfoSummaryPanel::SetLaunchType(
207 extensions::LaunchType launch_type) const {
208 DCHECK(CanSetLaunchType());
209 ExtensionService* service =
210 extensions::ExtensionSystem::Get(profile_)->extension_service();
211 extensions::SetLaunchType(service, app_->id(), launch_type);
214 bool AppInfoSummaryPanel::CanSetLaunchType() const {
215 // V2 apps don't have a launch type.
216 return !app_->is_platform_app();