1// Copyright (c) 2011 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.
4
5#include "base/basictypes.h"
6#include "base/compiler_specific.h"
7#include "base/string_util.h"
8#include "base/utf_string_conversions.h"
9#include "chrome/browser/extensions/extension_uninstall_dialog.h"
10#include "chrome/browser/profiles/profile.h"
11#include "chrome/browser/ui/browser_list.h"
12#include "chrome/browser/ui/browser_window.h"
13#include "chrome/browser/ui/views/window.h"
14#include "chrome/common/extensions/extension.h"
15#include "grit/generated_resources.h"
16#include "ui/base/l10n/l10n_util.h"
17#include "views/controls/button/checkbox.h"
18#include "views/controls/image_view.h"
19#include "views/controls/label.h"
20#include "views/controls/link.h"
21#include "views/layout/layout_constants.h"
22#include "views/view.h"
23#include "views/window/dialog_delegate.h"
24#include "views/window/window.h"
25
26namespace {
27
28const int kRightColumnWidth = 210;
29const int kIconSize = 69;
30
31class ExtensionUninstallDialogView : public views::View,
32                                     public views::DialogDelegate {
33 public:
34  ExtensionUninstallDialogView(ExtensionUninstallDialog::Delegate* delegate,
35                               const Extension* extension,
36                               SkBitmap* icon)
37        : delegate_(delegate),
38          icon_(NULL) {
39    // Scale down to icon size, but allow smaller icons (don't scale up).
40    gfx::Size size(icon->width(), icon->height());
41    if (size.width() > kIconSize || size.height() > kIconSize)
42      size = gfx::Size(kIconSize, kIconSize);
43    icon_ = new views::ImageView();
44    icon_->SetImageSize(size);
45    icon_->SetImage(*icon);
46    AddChildView(icon_);
47
48    heading_ = new views::Label(UTF16ToWide(
49        l10n_util::GetStringFUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_HEADING,
50                                   UTF8ToUTF16(extension->name()))));
51    heading_->SetMultiLine(true);
52    heading_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
53    AddChildView(heading_);
54  }
55
56 private:
57  // views::DialogDelegate:
58  virtual std::wstring GetDialogButtonLabel(
59      MessageBoxFlags::DialogButton button) const OVERRIDE {
60    switch (button) {
61      case MessageBoxFlags::DIALOGBUTTON_OK:
62        return UTF16ToWide(
63            l10n_util::GetStringUTF16(
64                IDS_EXTENSION_PROMPT_UNINSTALL_BUTTON));
65      case MessageBoxFlags::DIALOGBUTTON_CANCEL:
66        return UTF16ToWide(l10n_util::GetStringUTF16(IDS_CANCEL));
67      default:
68        NOTREACHED();
69        return L"";
70    }
71  }
72
73  virtual int GetDefaultDialogButton() const OVERRIDE {
74    return MessageBoxFlags::DIALOGBUTTON_CANCEL;
75  }
76
77  virtual bool Accept() OVERRIDE {
78    delegate_->ExtensionDialogAccepted();
79    return true;
80  }
81
82  virtual bool Cancel() OVERRIDE {
83    delegate_->ExtensionDialogCanceled();
84    return true;
85  }
86
87  // views::WindowDelegate:
88  virtual bool IsModal() const OVERRIDE { return true; }
89  virtual std::wstring GetWindowTitle() const OVERRIDE {
90    return UTF16ToWide(
91        l10n_util::GetStringUTF16(IDS_EXTENSION_UNINSTALL_PROMPT_TITLE));
92  }
93  virtual views::View* GetContentsView() { return this; }
94
95  // views::View:
96  virtual gfx::Size GetPreferredSize() OVERRIDE {
97    int width = kRightColumnWidth;
98    width += kIconSize;
99    width += views::kPanelHorizMargin * 3;
100
101    int height = views::kPanelVertMargin * 2;
102    height += heading_->GetHeightForWidth(kRightColumnWidth);
103
104    return gfx::Size(width,
105                     std::max(height, kIconSize + views::kPanelVertMargin * 2));
106  }
107
108  virtual void Layout() OVERRIDE {
109    int x = views::kPanelHorizMargin;
110    int y = views::kPanelVertMargin;
111
112    heading_->SizeToFit(kRightColumnWidth);
113
114    if (heading_->height() <= kIconSize) {
115      icon_->SetBounds(x, y, kIconSize, kIconSize);
116      x += kIconSize;
117      x += views::kPanelHorizMargin;
118
119      heading_->SetX(x);
120      heading_->SetY(y + (kIconSize - heading_->height()) / 2);
121    } else {
122      icon_->SetBounds(x,
123                       y + (heading_->height() - kIconSize) / 2,
124                       kIconSize,
125                       kIconSize);
126      x += kIconSize;
127      x += views::kPanelHorizMargin;
128
129      heading_->SetX(x);
130      heading_->SetY(y);
131    }
132  }
133
134  ExtensionUninstallDialog::Delegate* delegate_;
135  views::ImageView* icon_;
136  views::Label* heading_;
137
138  DISALLOW_COPY_AND_ASSIGN(ExtensionUninstallDialogView);
139};
140
141}  // namespace
142
143// static
144void ExtensionUninstallDialog::Show(
145    Profile* profile,
146    ExtensionUninstallDialog::Delegate* delegate,
147    const Extension* extension,
148    SkBitmap* icon) {
149  Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
150  if (!browser) {
151    delegate->ExtensionDialogCanceled();
152    return;
153  }
154
155  BrowserWindow* window = browser->window();
156  if (!window) {
157    delegate->ExtensionDialogCanceled();
158    return;
159  }
160
161  browser::CreateViewsWindow(window->GetNativeHandle(), gfx::Rect(),
162      new ExtensionUninstallDialogView(delegate, extension, icon))->Show();
163}
164