Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / chrome / browser / ui / views / extensions / bookmark_app_bubble_view.cc
blobb6c32eb892f889075febc49ec18dc618cbee01c6
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/extensions/bookmark_app_bubble_view.h"
7 #include "base/strings/string16.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "chrome/browser/extensions/app_icon_loader_impl.h"
10 #include "chrome/browser/extensions/bookmark_app_helper.h"
11 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/browser/extensions/launch_util.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "extensions/browser/pref_names.h"
15 #include "grit/generated_resources.h"
16 #include "grit/theme_resources.h"
17 #include "ui/base/l10n/l10n_util.h"
18 #include "ui/base/resource/resource_bundle.h"
19 #include "ui/events/keycodes/keyboard_codes.h"
20 #include "ui/views/controls/button/checkbox.h"
21 #include "ui/views/controls/button/label_button.h"
22 #include "ui/views/controls/image_view.h"
23 #include "ui/views/controls/label.h"
24 #include "ui/views/controls/textfield/textfield.h"
25 #include "ui/views/layout/grid_layout.h"
26 #include "ui/views/layout/layout_constants.h"
27 #include "ui/views/widget/widget.h"
29 using views::ColumnSet;
30 using views::GridLayout;
32 namespace {
34 // Minimum width of the the bubble.
35 const int kMinBubbleWidth = 300;
36 // Minimum width of the the textfield.
37 const int kMinTextfieldWidth = 200;
38 // Size of the icon.
39 const int kIconSize = extension_misc::EXTENSION_ICON_MEDIUM;
41 } // namespace
43 BookmarkAppBubbleView* BookmarkAppBubbleView::bookmark_app_bubble_ = NULL;
45 BookmarkAppBubbleView::~BookmarkAppBubbleView() {
48 // static
49 void BookmarkAppBubbleView::ShowBubble(views::View* anchor_view,
50 Profile* profile,
51 const WebApplicationInfo& web_app_info,
52 const std::string& extension_id) {
53 if (bookmark_app_bubble_ != NULL)
54 return;
56 bookmark_app_bubble_ = new BookmarkAppBubbleView(
57 anchor_view, profile, web_app_info, extension_id);
58 views::BubbleDelegateView::CreateBubble(bookmark_app_bubble_)->Show();
59 // Select the entire title textfield contents when the bubble is first shown.
60 bookmark_app_bubble_->title_tf_->SelectAll(true);
61 bookmark_app_bubble_->SetArrowPaintType(views::BubbleBorder::PAINT_NONE);
64 BookmarkAppBubbleView::BookmarkAppBubbleView(
65 views::View* anchor_view,
66 Profile* profile,
67 const WebApplicationInfo& web_app_info,
68 const std::string& extension_id)
69 : BubbleDelegateView(anchor_view, views::BubbleBorder::TOP_RIGHT),
70 profile_(profile),
71 web_app_info_(web_app_info),
72 extension_id_(extension_id),
73 add_button_(NULL),
74 cancel_button_(NULL),
75 open_as_tab_checkbox_(NULL),
76 title_tf_(NULL),
77 remove_app_(true),
78 app_icon_loader_(new extensions::AppIconLoaderImpl(profile,
79 kIconSize,
80 this)) {
81 const SkColor background_color = GetNativeTheme()->GetSystemColor(
82 ui::NativeTheme::kColorId_DialogBackground);
83 set_arrow(views::BubbleBorder::TOP_CENTER);
84 set_color(background_color);
85 set_background(views::Background::CreateSolidBackground(background_color));
86 set_margins(gfx::Insets(views::kPanelVertMargin, 0, 0, 0));
89 void BookmarkAppBubbleView::Init() {
90 views::Label* title_label = new views::Label(
91 l10n_util::GetStringUTF16(IDS_BOOKMARK_APP_BUBBLE_TITLE));
92 ui::ResourceBundle* rb = &ui::ResourceBundle::GetSharedInstance();
93 title_label->SetFontList(rb->GetFontList(ui::ResourceBundle::MediumFont));
94 title_label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
96 add_button_ =
97 new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_ADD));
98 add_button_->SetStyle(views::Button::STYLE_BUTTON);
99 add_button_->SetIsDefault(true);
101 cancel_button_ =
102 new views::LabelButton(this, l10n_util::GetStringUTF16(IDS_CANCEL));
103 cancel_button_->SetStyle(views::Button::STYLE_BUTTON);
105 GridLayout* layout = new GridLayout(this);
106 SetLayoutManager(layout);
108 // Column sets used in the layout of the bubble.
109 enum ColumnSetID {
110 TITLE_COLUMN_SET_ID,
111 TITLE_TEXT_COLUMN_SET_ID,
112 CONTENT_COLUMN_SET_ID
115 // The column layout used for the title and checkbox.
116 ColumnSet* cs = layout->AddColumnSet(TITLE_COLUMN_SET_ID);
117 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
118 cs->AddColumn(
119 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
120 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
122 // The column layout used for the icon and text box.
123 cs = layout->AddColumnSet(TITLE_TEXT_COLUMN_SET_ID);
124 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
125 cs->AddColumn(GridLayout::LEADING,
126 GridLayout::CENTER,
128 GridLayout::USE_PREF,
131 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
132 cs->AddColumn(GridLayout::FILL,
133 GridLayout::CENTER,
135 GridLayout::USE_PREF,
137 kMinTextfieldWidth);
138 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
140 // The column layout used for the row with buttons.
141 cs = layout->AddColumnSet(CONTENT_COLUMN_SET_ID);
142 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
143 cs->AddColumn(
144 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
145 cs->AddPaddingColumn(1, views::kUnrelatedControlHorizontalSpacing);
146 cs->AddColumn(
147 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
148 cs->AddPaddingColumn(0, views::kRelatedButtonHSpacing);
149 cs->AddColumn(
150 GridLayout::LEADING, GridLayout::CENTER, 0, GridLayout::USE_PREF, 0, 0);
151 cs->AddPaddingColumn(0, views::kButtonHEdgeMarginNew);
153 layout->StartRow(0, TITLE_COLUMN_SET_ID);
154 layout->AddView(title_label);
155 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
157 const extensions::Extension* extension =
158 profile_->GetExtensionService()->GetInstalledExtension(extension_id_);
160 layout->StartRow(0, TITLE_TEXT_COLUMN_SET_ID);
161 icon_image_view_ = new views::ImageView();
162 icon_image_view_->SetImageSize(gfx::Size(kIconSize, kIconSize));
163 layout->AddView(icon_image_view_);
164 app_icon_loader_->FetchImage(extension_id_);
166 title_tf_ = new views::Textfield();
167 title_tf_->SetText(extension ? base::UTF8ToUTF16(extension->name())
168 : web_app_info_.title);
169 layout->AddView(title_tf_);
170 layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
172 layout->StartRow(0, CONTENT_COLUMN_SET_ID);
173 open_as_tab_checkbox_ = new views::Checkbox(
174 l10n_util::GetStringUTF16(IDS_BOOKMARK_APP_BUBBLE_OPEN_AS_TAB));
175 open_as_tab_checkbox_->SetChecked(
176 profile_->GetPrefs()->GetInteger(
177 extensions::pref_names::kBookmarkAppCreationLaunchType) ==
178 extensions::LAUNCH_TYPE_REGULAR);
179 layout->AddView(open_as_tab_checkbox_);
180 layout->AddView(add_button_);
181 layout->AddView(cancel_button_);
182 layout->AddPaddingRow(0, views::kUnrelatedControlVerticalSpacing);
184 AddAccelerator(ui::Accelerator(ui::VKEY_RETURN, ui::EF_NONE));
187 views::View* BookmarkAppBubbleView::GetInitiallyFocusedView() {
188 return title_tf_;
191 void BookmarkAppBubbleView::WindowClosing() {
192 // We have to reset |bookmark_app_bubble_| here, not in our destructor,
193 // because we'll be destroyed asynchronously and the shown state will be
194 // checked before then.
195 DCHECK_EQ(bookmark_app_bubble_, this);
196 bookmark_app_bubble_ = NULL;
198 if (remove_app_) {
199 profile_->GetExtensionService()->UninstallExtension(
200 extension_id_, false, NULL);
201 } else {
202 ApplyEdits();
206 bool BookmarkAppBubbleView::AcceleratorPressed(
207 const ui::Accelerator& accelerator) {
208 if (accelerator.key_code() == ui::VKEY_RETURN) {
209 HandleButtonPressed(add_button_);
212 return BubbleDelegateView::AcceleratorPressed(accelerator);
215 gfx::Size BookmarkAppBubbleView::GetMinimumSize() {
216 gfx::Size size(views::BubbleDelegateView::GetPreferredSize());
217 size.SetToMax(gfx::Size(kMinBubbleWidth, 0));
218 return size;
221 void BookmarkAppBubbleView::ButtonPressed(views::Button* sender,
222 const ui::Event& event) {
223 HandleButtonPressed(sender);
226 void BookmarkAppBubbleView::SetAppImage(const std::string& id,
227 const gfx::ImageSkia& image) {
228 DCHECK_EQ(extension_id_, id);
229 icon_image_view_->SetImage(image);
232 void BookmarkAppBubbleView::HandleButtonPressed(views::Button* sender) {
233 // Unset |remove_app_| so we don't delete the bookmark after the window
234 // closes.
235 if (sender == add_button_)
236 remove_app_ = false;
238 GetWidget()->Close();
241 void BookmarkAppBubbleView::ApplyEdits() {
242 // Set the launch type based on the checkbox.
243 extensions::LaunchType launch_type = open_as_tab_checkbox_->checked()
244 ? extensions::LAUNCH_TYPE_REGULAR
245 : extensions::LAUNCH_TYPE_WINDOW;
246 profile_->GetPrefs()->SetInteger(
247 extensions::pref_names::kBookmarkAppCreationLaunchType, launch_type);
248 extensions::SetLaunchType(profile_->GetExtensionService(),
249 extension_id_,
250 launch_type);
252 const extensions::Extension* extension =
253 profile_->GetExtensionService()->GetInstalledExtension(extension_id_);
254 if (extension && base::UTF8ToUTF16(extension->name()) == title_tf_->text())
255 return;
257 // Reinstall the app with an updated name.
258 WebApplicationInfo install_info(web_app_info_);
259 install_info.title = title_tf_->text();
261 extensions::CreateOrUpdateBookmarkApp(profile_->GetExtensionService(),
262 install_info);