extension_install_dialog_view.h revision 116680a4aac90f2aa7413d9095a592090648e557
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.
4
5#ifndef CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_
6#define CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_
7
8#include "chrome/browser/extensions/extension_install_prompt.h"
9#include "ui/gfx/animation/animation_delegate.h"
10#include "ui/gfx/animation/slide_animation.h"
11#include "ui/views/controls/button/button.h"
12#include "ui/views/controls/link_listener.h"
13#include "ui/views/view.h"
14#include "ui/views/window/dialog_delegate.h"
15
16typedef std::vector<base::string16> PermissionDetails;
17class ExpandableContainerView;
18
19namespace content {
20class PageNavigator;
21}
22
23namespace views {
24class GridLayout;
25class ImageButton;
26class Label;
27class Link;
28}
29
30// A custom scrollable view implementation for the dialog.
31class CustomScrollableView : public views::View {
32 public:
33  CustomScrollableView();
34  virtual ~CustomScrollableView();
35
36 private:
37  virtual void Layout() OVERRIDE;
38
39  DISALLOW_COPY_AND_ASSIGN(CustomScrollableView);
40};
41
42// Implements the extension installation dialog for TOOLKIT_VIEWS.
43class ExtensionInstallDialogView : public views::DialogDelegateView,
44                                   public views::LinkListener,
45                                   public views::ButtonListener {
46 public:
47  ExtensionInstallDialogView(
48      content::PageNavigator* navigator,
49      ExtensionInstallPrompt::Delegate* delegate,
50      scoped_refptr<ExtensionInstallPrompt::Prompt> prompt);
51  virtual ~ExtensionInstallDialogView();
52
53  // Returns the interior ScrollView of the dialog. This allows us to inspect
54  // the contents of the DialogView.
55  const views::ScrollView* scroll_view() const { return scroll_view_; }
56
57  // Called when one of the child elements has expanded/collapsed.
58  void ContentsChanged();
59
60 private:
61  // views::DialogDelegateView:
62  virtual int GetDialogButtons() const OVERRIDE;
63  virtual base::string16 GetDialogButtonLabel(
64      ui::DialogButton button) const OVERRIDE;
65  virtual int GetDefaultDialogButton() const OVERRIDE;
66  virtual bool Cancel() OVERRIDE;
67  virtual bool Accept() OVERRIDE;
68  virtual ui::ModalType GetModalType() const OVERRIDE;
69  virtual base::string16 GetWindowTitle() const OVERRIDE;
70  virtual void Layout() OVERRIDE;
71  virtual gfx::Size GetPreferredSize() const OVERRIDE;
72  virtual void ViewHierarchyChanged(
73      const ViewHierarchyChangedDetails& details) OVERRIDE;
74
75  // views::LinkListener:
76  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
77
78  // views::ButtonListener:
79  virtual void ButtonPressed(views::Button* sender,
80                             const ui::Event& event) OVERRIDE;
81
82  // Experimental: Toggles inline permission explanations with an animation.
83  void ToggleInlineExplanations();
84
85  // Creates a layout consisting of dialog header, extension name and icon.
86  views::GridLayout* CreateLayout(
87      views::View* parent,
88      int left_column_width,
89      int column_set_id,
90      bool single_detail_row) const;
91
92  bool is_inline_install() const {
93    return prompt_->type() == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT;
94  }
95
96  bool is_bundle_install() const {
97    return prompt_->type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT;
98  }
99
100  bool is_external_install() const {
101    return prompt_->type() == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT;
102  }
103
104  // Updates the histogram that holds installation accepted/aborted data.
105  void UpdateInstallResultHistogram(bool accepted) const;
106
107  // Updates the histogram that holds data about whether "Show details" or
108  // "Show permissions" links were shown and/or clicked.
109  void UpdateLinkActionHistogram(int action_type) const;
110
111  content::PageNavigator* navigator_;
112  ExtensionInstallPrompt::Delegate* delegate_;
113  scoped_refptr<ExtensionInstallPrompt::Prompt> prompt_;
114
115  // The scroll view containing all the details for the dialog (including all
116  // collapsible/expandable sections).
117  views::ScrollView* scroll_view_;
118
119  // The container view for the scroll view.
120  CustomScrollableView* scrollable_;
121
122  // The container for the simpler view with only the dialog header and the
123  // extension icon. Used for the experiment where the permissions are
124  // initially hidden when the dialog shows.
125  CustomScrollableView* scrollable_header_only_;
126
127  // The preferred size of the dialog.
128  gfx::Size dialog_size_;
129
130  // Experimental: "Show details" link to expand inline explanations and reveal
131  // permision dialog.
132  views::Link* show_details_link_;
133
134  // Experimental: Label for showing information about the checkboxes.
135  views::Label* checkbox_info_label_;
136
137  // Experimental: Contains pointers to inline explanation views.
138  typedef std::vector<ExpandableContainerView*> InlineExplanations;
139  InlineExplanations inline_explanations_;
140
141  // Experimental: Number of unchecked checkboxes in the permission list.
142  // If this becomes zero, the accept button is enabled, otherwise disabled.
143  int unchecked_boxes_;
144
145  DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView);
146};
147
148// A simple view that prepends a view with a bullet with the help of a grid
149// layout.
150class BulletedView : public views::View {
151 public:
152  explicit BulletedView(views::View* view);
153 private:
154  DISALLOW_COPY_AND_ASSIGN(BulletedView);
155};
156
157// A simple view that prepends a view with a checkbox with the help of a grid
158// layout. Used for the permission experiment.
159// TODO(meacer): Remove once the experiment is completed.
160class CheckboxedView : public views::View {
161 public:
162  CheckboxedView(views::View* view, views::ButtonListener* listener);
163 private:
164  DISALLOW_COPY_AND_ASSIGN(CheckboxedView);
165};
166
167// A view to display text with an expandable details section.
168class ExpandableContainerView : public views::View,
169                                public views::ButtonListener,
170                                public views::LinkListener,
171                                public gfx::AnimationDelegate {
172 public:
173  ExpandableContainerView(ExtensionInstallDialogView* owner,
174                          const base::string16& description,
175                          const PermissionDetails& details,
176                          int horizontal_space,
177                          bool parent_bulleted,
178                          bool show_expand_link,
179                          bool lighter_color_details);
180  virtual ~ExpandableContainerView();
181
182  // views::View:
183  virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE;
184
185  // views::ButtonListener:
186  virtual void ButtonPressed(views::Button* sender,
187                             const ui::Event& event) OVERRIDE;
188
189  // views::LinkListener:
190  virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE;
191
192  // gfx::AnimationDelegate:
193  virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE;
194  virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE;
195
196  // Expand/Collapse the detail section for this ExpandableContainerView.
197  void ToggleDetailLevel();
198
199  // Expand the detail section without any animation.
200  // TODO(meacer): Remove once the experiment is completed.
201  void ExpandWithoutAnimation();
202
203 private:
204  // A view which displays all the details of an IssueAdviceInfoEntry.
205  class DetailsView : public views::View {
206   public:
207    explicit DetailsView(int horizontal_space, bool parent_bulleted,
208                         bool lighter_color);
209    virtual ~DetailsView() {}
210
211    // views::View:
212    virtual gfx::Size GetPreferredSize() const OVERRIDE;
213
214    void AddDetail(const base::string16& detail);
215
216    // Animates this to be a height proportional to |state|.
217    void AnimateToState(double state);
218
219   private:
220    views::GridLayout* layout_;
221    double state_;
222
223    // Whether the detail text should be shown with a lighter color.
224    bool lighter_color_;
225
226    DISALLOW_COPY_AND_ASSIGN(DetailsView);
227  };
228
229  // The dialog that owns |this|. It's also an ancestor in the View hierarchy.
230  ExtensionInstallDialogView* owner_;
231
232  // A view for showing |issue_advice.details|.
233  DetailsView* details_view_;
234
235  // The 'more details' link shown under the heading (changes to 'hide details'
236  // when the details section is expanded).
237  views::Link* more_details_;
238
239  gfx::SlideAnimation slide_animation_;
240
241  // The up/down arrow next to the 'more detail' link (points up/down depending
242  // on whether the details section is expanded).
243  views::ImageButton* arrow_toggle_;
244
245  // Whether the details section is expanded.
246  bool expanded_;
247
248  DISALLOW_COPY_AND_ASSIGN(ExpandableContainerView);
249};
250
251void ShowExtensionInstallDialogImpl(
252    const ExtensionInstallPrompt::ShowParams& show_params,
253    ExtensionInstallPrompt::Delegate* delegate,
254    scoped_refptr<ExtensionInstallPrompt::Prompt> prompt);
255
256#endif  // CHROME_BROWSER_UI_VIEWS_EXTENSIONS_EXTENSION_INSTALL_DIALOG_VIEW_H_
257