create_application_shortcut_view.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/create_application_shortcut_view.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/utf_string_conversions.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/win/windows_version.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/extensions/tab_helper.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/prefs/pref_service.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/web_applications/web_app_ui.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_constants.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/extensions/extension_resource.h"
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/pref_names.h"
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_delegate.h"
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/generated_resources.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/locale_settings.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "grit/theme_resources.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkBitmap.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkPaint.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkRect.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/l10n/l10n_util.h"
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/canvas.h"
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/codec/png_codec.h"
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/button/checkbox.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/image_view.h"
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/controls/label.h"
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/grid_layout.h"
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/layout/layout_constants.h"
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/window/dialog_client_view.h"
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAppIconSize = 32;
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppInfoView shows the application icon and title.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppInfoView : public views::View {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppInfoView(const string16& title,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const string16& description,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)              const SkBitmap& icon);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates the title/description of the web app.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateText(const string16& title, const string16& description);
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Updates the icon of the web app.
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void UpdateIcon(const gfx::Image& image);
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Overridden from views::View:
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnPaint(gfx::Canvas* canvas);
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Initializes the controls
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Init(const string16& title,
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            const string16& description, const SkBitmap& icon);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates or updates description label.
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void PrepareDescriptionLabel(const string16& description);
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Sets up layout manager.
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetupLayout();
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::ImageView* icon_;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Label* title_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Label* description_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppInfoView::AppInfoView(const string16& title,
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const string16& description,
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         const SkBitmap& icon)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : icon_(NULL),
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      title_(NULL),
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      description_(NULL) {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Init(title, description, icon);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppInfoView::Init(const string16& title_text,
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const string16& description_text,
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                       const SkBitmap& icon) {
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_ = new views::ImageView();
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_->SetImage(gfx::ImageSkia(icon));
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  icon_->SetImageSize(gfx::Size(kAppIconSize, kAppIconSize));
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  title_ = new views::Label(title_text);
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  title_->SetMultiLine(true);
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  title_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  title_->SetFont(ui::ResourceBundle::GetSharedInstance().GetFont(
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ui::ResourceBundle::BaseFont).DeriveFont(0, gfx::Font::BOLD));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!description_text.empty()) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    PrepareDescriptionLabel(description_text);
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupLayout();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppInfoView::PrepareDescriptionLabel(const string16& description) {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!description.empty());
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const size_t kMaxLength = 200;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const string16 kEllipsis(ASCIIToUTF16(" ... "));
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string16 text = description;
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (text.length() > kMaxLength) {
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    text = text.substr(0, kMaxLength);
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    text += kEllipsis;
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (description_) {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    description_->SetText(text);
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    description_ = new views::Label(text);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    description_->SetMultiLine(true);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    description_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppInfoView::SetupLayout() {
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::GridLayout* layout = views::GridLayout::CreatePanel(this);
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLayoutManager(layout);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kColumnSetId = 0;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::ColumnSet* column_set = layout->AddColumnSet(kColumnSetId);
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::LEADING,
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        20.0f, views::GridLayout::FIXED,
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        kAppIconSize, kAppIconSize);
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER,
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        80.0f, views::GridLayout::USE_PREF, 0, 0);
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, kColumnSetId);
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(icon_, 1, description_ ? 2 : 1);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(title_);
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (description_) {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->StartRow(0, kColumnSetId);
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->SkipColumns(1);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddView(description_);
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppInfoView::UpdateText(const string16& title,
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             const string16& description) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  title_->SetText(title);
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PrepareDescriptionLabel(description);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetupLayout();
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppInfoView::UpdateIcon(const gfx::Image& image) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!image.IsEmpty())
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_->SetImage(image.ToImageSkia());
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppInfoView::OnPaint(gfx::Canvas* canvas) {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds = GetLocalBounds();
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect border_rect = {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkIntToScalar(bounds.x()),
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkIntToScalar(bounds.y()),
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkIntToScalar(bounds.right()),
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkIntToScalar(bounds.bottom())
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint border_paint;
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  border_paint.setAntiAlias(true);
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  border_paint.setARGB(0xFF, 0xC8, 0xC8, 0xC8);
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->sk_canvas()->drawRoundRect(border_rect, SkIntToScalar(2),
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SkIntToScalar(2), border_paint);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkRect inner_rect = {
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    border_rect.fLeft + SkDoubleToScalar(0.5),
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    border_rect.fTop + SkDoubleToScalar(0.5),
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    border_rect.fRight - SkDoubleToScalar(0.5),
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    border_rect.fBottom - SkDoubleToScalar(0.5),
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPaint inner_paint;
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_paint.setAntiAlias(true);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  inner_paint.setARGB(0xFF, 0xF8, 0xF8, 0xF8);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  canvas->sk_canvas()->drawRoundRect(inner_rect, SkDoubleToScalar(1.5),
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     SkDoubleToScalar(1.5), inner_paint);
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace chrome {
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowCreateWebAppShortcutsDialog(gfx::NativeWindow parent_window,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     content::WebContents* web_contents) {
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget::CreateWindowWithParent(
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CreateUrlApplicationShortcutView(web_contents),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent_window)->Show();
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void ShowCreateChromeAppShortcutsDialog(gfx::NativeWindow parent_window,
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        Profile* profile,
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                        const extensions::Extension* app) {
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Widget::CreateWindowWithParent(
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      new CreateChromeApplicationShortcutView(profile, app),
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      parent_window)->Show();
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace chrome
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CreateUrlApplicationShortcutView::IconDownloadCallbackFunctor {
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit IconDownloadCallbackFunctor(CreateUrlApplicationShortcutView* owner)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : owner_(owner) {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Run(int download_id, bool errored, const SkBitmap& image) {
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (owner_)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      owner_->OnIconDownloaded(errored, image);
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    delete this;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Cancel() {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    owner_ = NULL;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateUrlApplicationShortcutView* owner_;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateApplicationShortcutView::CreateApplicationShortcutView(Profile* profile)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : profile_(profile),
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      app_info_(NULL),
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      create_shortcuts_label_(NULL),
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      desktop_check_box_(NULL),
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      menu_check_box_(NULL),
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quick_launch_check_box_(NULL) {}
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateApplicationShortcutView::~CreateApplicationShortcutView() {}
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutView::InitControls() {
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create controls
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  app_info_ = new AppInfoView(shortcut_info_.title, shortcut_info_.description,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      shortcut_info_.favicon.IsEmpty() ? SkBitmap() :
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         *shortcut_info_.favicon.ToSkBitmap());
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  create_shortcuts_label_ = new views::Label(
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_CREATE_SHORTCUTS_LABEL));
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  create_shortcuts_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  desktop_check_box_ = AddCheckbox(
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_CREATE_SHORTCUTS_DESKTOP_CHKBOX),
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateOnDesktop));
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_check_box_ = NULL;
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quick_launch_check_box_ = NULL;
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Do not allow creating shortcuts on the Start Screen for Windows 8.
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (base::win::GetVersion() < base::win::VERSION_WIN8) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    menu_check_box_ = AddCheckbox(
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_CREATE_SHORTCUTS_START_MENU_CHKBOX),
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu));
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  quick_launch_check_box_ = AddCheckbox(
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      (base::win::GetVersion() >= base::win::VERSION_WIN7) ?
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(IDS_PIN_TO_TASKBAR_CHKBOX) :
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        l10n_util::GetStringUTF16(
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            IDS_CREATE_SHORTCUTS_QUICK_LAUNCH_BAR_CHKBOX),
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateInQuickLaunchBar));
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  menu_check_box_ = AddCheckbox(
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      l10n_util::GetStringUTF16(IDS_CREATE_SHORTCUTS_MENU_CHKBOX),
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      profile_->GetPrefs()->GetBoolean(prefs::kWebAppCreateInAppsMenu));
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Layout controls
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::GridLayout* layout = views::GridLayout::CreatePanel(this);
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetLayoutManager(layout);
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kHeaderColumnSetId = 0;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::ColumnSet* column_set = layout->AddColumnSet(kHeaderColumnSetId);
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::CENTER,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        100.0f, views::GridLayout::FIXED, 0, 0);
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kTableColumnSetId = 1;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set = layout->AddColumnSet(kTableColumnSetId);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddPaddingColumn(0, views::kPanelHorizIndentation);
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        100.0f, views::GridLayout::USE_PREF, 0, 0);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, kHeaderColumnSetId);
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(app_info_);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddPaddingRow(0, views::kPanelSubVerticalSpacing);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, kHeaderColumnSetId);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(create_shortcuts_label_);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddPaddingRow(0, views::kLabelToControlVerticalSpacing);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->StartRow(0, kTableColumnSetId);
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  layout->AddView(desktop_check_box_);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (menu_check_box_ != NULL) {
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->StartRow(0, kTableColumnSetId);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddView(menu_check_box_);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (quick_launch_check_box_ != NULL) {
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddPaddingRow(0, views::kRelatedControlSmallVerticalSpacing);
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->StartRow(0, kTableColumnSetId);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    layout->AddView(quick_launch_check_box_);
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Size CreateApplicationShortcutView::GetPreferredSize() {
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(evanm): should this use IDS_CREATE_SHORTCUTS_DIALOG_WIDTH_CHARS?
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kDialogWidth = 360;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int height = GetLayoutManager()->GetPreferredHeightForWidth(this,
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kDialogWidth);
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Size(kDialogWidth, height);
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 CreateApplicationShortcutView::GetDialogButtonLabel(
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::DialogButton button) const {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (button == ui::DIALOG_BUTTON_OK)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return l10n_util::GetStringUTF16(IDS_CREATE_SHORTCUTS_COMMIT);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return string16();
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateApplicationShortcutView::IsDialogButtonEnabled(
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ui::DialogButton button) const {
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (button == ui::DIALOG_BUTTON_OK)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return desktop_check_box_->checked() ||
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ((menu_check_box_ != NULL) &&
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            menu_check_box_->checked()) ||
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           ((quick_launch_check_box_ != NULL) &&
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            quick_launch_check_box_->checked());
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateApplicationShortcutView::CanResize() const {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateApplicationShortcutView::CanMaximize() const {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::ModalType CreateApplicationShortcutView::GetModalType() const {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ui::MODAL_TYPE_WINDOW;
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string16 CreateApplicationShortcutView::GetWindowTitle() const {
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return l10n_util::GetStringUTF16(IDS_CREATE_SHORTCUTS_TITLE);
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateApplicationShortcutView::Accept() {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!IsDialogButtonEnabled(ui::DIALOG_BUTTON_OK))
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.create_on_desktop = desktop_check_box_->checked();
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.create_in_applications_menu = menu_check_box_ == NULL ? false :
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      menu_check_box_->checked();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.create_in_quick_launch_bar = quick_launch_check_box_ == NULL ?
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NULL : quick_launch_check_box_->checked();
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Create shortcut in Mac dock or as Linux (gnome/kde) application launcher
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are not implemented yet.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.create_in_quick_launch_bar = false;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_app::CreateShortcuts(shortcut_info_);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::View* CreateApplicationShortcutView::GetContentsView() {
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return this;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)views::Checkbox* CreateApplicationShortcutView::AddCheckbox(
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const string16& text, bool checked) {
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  views::Checkbox* checkbox = new views::Checkbox(text);
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  checkbox->SetChecked(checked);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  checkbox->set_listener(this);
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return checkbox;
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateApplicationShortcutView::ButtonPressed(views::Button* sender,
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                  const ui::Event& event) {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (sender == desktop_check_box_) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateOnDesktop,
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     desktop_check_box_->checked());
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (sender == menu_check_box_) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateInAppsMenu,
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     menu_check_box_->checked());
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else if (sender == quick_launch_check_box_) {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    profile_->GetPrefs()->SetBoolean(prefs::kWebAppCreateInQuickLaunchBar,
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     quick_launch_check_box_->checked());
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // When no checkbox is checked we should not have the action button enabled.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GetDialogClientView()->UpdateDialogButtons();
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateUrlApplicationShortcutView::CreateUrlApplicationShortcutView(
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    content::WebContents* web_contents)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : CreateApplicationShortcutView(
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          Profile::FromBrowserContext(web_contents->GetBrowserContext())),
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      web_contents_(web_contents),
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      pending_download_(NULL)  {
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  web_app::GetShortcutInfoForTab(web_contents_, &shortcut_info_);
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const WebApplicationInfo& app_info =
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      extensions::TabHelper::FromWebContents(web_contents_)->web_app_info();
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!app_info.icons.empty()) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    web_app::GetIconsInfo(app_info, &unprocessed_icons_);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FetchIcon();
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitControls();
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateUrlApplicationShortcutView::~CreateUrlApplicationShortcutView() {
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (pending_download_)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pending_download_->Cancel();
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateUrlApplicationShortcutView::Accept() {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!CreateApplicationShortcutView::Accept())
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  extensions::TabHelper::FromWebContents(web_contents_)->
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SetAppIcon(shortcut_info_.favicon.IsEmpty()
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          ? SkBitmap()
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          : *shortcut_info_.favicon.ToSkBitmap());
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Browser* browser = browser::FindBrowserWithWebContents(web_contents_);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (browser)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    chrome::ConvertTabToAppWindow(browser, web_contents_);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateUrlApplicationShortcutView::FetchIcon() {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // There should only be fetch job at a time.
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_download_ == NULL);
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (unprocessed_icons_.empty())  // No icons to fetch.
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_download_ = new IconDownloadCallbackFunctor(this);
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(pending_download_);
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FaviconTabHelper::FromWebContents(web_contents_)->
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DownloadImage(unprocessed_icons_.back().url,
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    std::max(unprocessed_icons_.back().width,
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             unprocessed_icons_.back().height),
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    history::FAVICON,
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    base::Bind(&IconDownloadCallbackFunctor::Run,
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               base::Unretained(pending_download_)));
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  unprocessed_icons_.pop_back();
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateUrlApplicationShortcutView::OnIconDownloaded(bool errored,
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                        const SkBitmap& image) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pending_download_ = NULL;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!errored && !image.isNull()) {
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shortcut_info_.favicon = gfx::Image(image);
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FetchIcon();
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateChromeApplicationShortcutView::CreateChromeApplicationShortcutView(
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Profile* profile,
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const extensions::Extension* app) :
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      CreateApplicationShortcutView(profile),
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      app_(app),
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ALLOW_THIS_IN_INITIALIZER_LIST(tracker_(this)) {
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.extension_id = app_->id();
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.url = GURL(app_->launch_web_url());
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.title = UTF8ToUTF16(app_->name());
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.description = UTF8ToUTF16(app_->description());
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.extension_path = app_->path();
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  shortcut_info_.profile_path = profile->GetPath();
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The icon will be resized to |max_size|.
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const gfx::Size max_size(kAppIconSize, kAppIconSize);
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Look for an icon.  If there is no icon at the ideal size,
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we will resize whatever we can get.  Making a large icon smaller
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // is prefered to making a small icon larger, so look for a larger
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // icon first:
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ExtensionResource icon_resource = app_->GetIconResource(
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kAppIconSize,
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ExtensionIconSet::MATCH_BIGGER);
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If no icon exists that is the desired size or larger, get the
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // largest icon available:
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (icon_resource.empty()) {
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    icon_resource = app_->GetIconResource(
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kAppIconSize,
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ExtensionIconSet::MATCH_SMALLER);
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  InitControls();
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // tracker_.LoadImage() can call OnImageLoaded() before it returns if the
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // image is cached.  This is very rare.  app_info_ must be initialized
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // when OnImageLoaded() is called, so we check it here.
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(app_info_);
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tracker_.LoadImage(app_,
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     icon_resource,
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     max_size,
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     ImageLoadingTracker::DONT_CACHE);
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CreateChromeApplicationShortcutView::~CreateChromeApplicationShortcutView() {}
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Called by tracker_ when the app's icon is loaded.
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CreateChromeApplicationShortcutView::OnImageLoaded(
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Image& image,
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& extension_id,
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index) {
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (image.IsEmpty()) {
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shortcut_info_.favicon = ui::ResourceBundle::GetSharedInstance().
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        GetImageNamed(IDR_APP_DEFAULT_ICON);
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    shortcut_info_.favicon = image;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CHECK(app_info_);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static_cast<AppInfoView*>(app_info_)->UpdateIcon(shortcut_info_.favicon);
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
552