| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/ui/views/extensions/extension_install_dialog_view.h" |
| 6 |
| 5 #include <vector> | 7 #include <vector> |
| 6 | 8 |
| 7 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 8 #include "base/command_line.h" | 10 #include "base/command_line.h" |
| 9 #include "base/compiler_specific.h" | 11 #include "base/compiler_specific.h" |
| 10 #include "base/i18n/rtl.h" | 12 #include "base/i18n/rtl.h" |
| 11 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 12 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 13 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 14 #include "chrome/browser/extensions/bundle_installer.h" | 16 #include "chrome/browser/extensions/bundle_installer.h" |
| 15 #include "chrome/browser/extensions/extension_install_prompt.h" | |
| 16 #include "chrome/browser/extensions/extension_install_prompt_experiment.h" | 17 #include "chrome/browser/extensions/extension_install_prompt_experiment.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/ui/views/constrained_window_views.h" | 19 #include "chrome/browser/ui/views/constrained_window_views.h" |
| 19 #include "chrome/common/chrome_switches.h" | 20 #include "chrome/common/chrome_switches.h" |
| 20 #include "chrome/common/extensions/extension_constants.h" | 21 #include "chrome/common/extensions/extension_constants.h" |
| 21 #include "chrome/installer/util/browser_distribution.h" | 22 #include "chrome/installer/util/browser_distribution.h" |
| 22 #include "content/public/browser/page_navigator.h" | 23 #include "content/public/browser/page_navigator.h" |
| 23 #include "content/public/browser/web_contents.h" | 24 #include "content/public/browser/web_contents.h" |
| 24 #include "extensions/common/extension.h" | 25 #include "extensions/common/extension.h" |
| 25 #include "grit/chromium_strings.h" | 26 #include "grit/chromium_strings.h" |
| 26 #include "grit/generated_resources.h" | 27 #include "grit/generated_resources.h" |
| 27 #include "grit/google_chrome_strings.h" | 28 #include "grit/google_chrome_strings.h" |
| 28 #include "grit/theme_resources.h" | 29 #include "grit/theme_resources.h" |
| 29 #include "ui/base/l10n/l10n_util.h" | 30 #include "ui/base/l10n/l10n_util.h" |
| 30 #include "ui/base/resource/resource_bundle.h" | 31 #include "ui/base/resource/resource_bundle.h" |
| 31 #include "ui/gfx/animation/animation_delegate.h" | |
| 32 #include "ui/gfx/animation/slide_animation.h" | |
| 33 #include "ui/gfx/text_utils.h" | 32 #include "ui/gfx/text_utils.h" |
| 34 #include "ui/gfx/transform.h" | |
| 35 #include "ui/views/background.h" | 33 #include "ui/views/background.h" |
| 36 #include "ui/views/border.h" | 34 #include "ui/views/border.h" |
| 37 #include "ui/views/controls/button/checkbox.h" | 35 #include "ui/views/controls/button/checkbox.h" |
| 38 #include "ui/views/controls/button/image_button.h" | 36 #include "ui/views/controls/button/image_button.h" |
| 39 #include "ui/views/controls/button/label_button.h" | 37 #include "ui/views/controls/button/label_button.h" |
| 40 #include "ui/views/controls/image_view.h" | 38 #include "ui/views/controls/image_view.h" |
| 41 #include "ui/views/controls/label.h" | 39 #include "ui/views/controls/label.h" |
| 42 #include "ui/views/controls/link.h" | 40 #include "ui/views/controls/link.h" |
| 43 #include "ui/views/controls/link_listener.h" | |
| 44 #include "ui/views/controls/scroll_view.h" | 41 #include "ui/views/controls/scroll_view.h" |
| 45 #include "ui/views/controls/separator.h" | 42 #include "ui/views/controls/separator.h" |
| 46 #include "ui/views/layout/box_layout.h" | 43 #include "ui/views/layout/box_layout.h" |
| 47 #include "ui/views/layout/grid_layout.h" | 44 #include "ui/views/layout/grid_layout.h" |
| 48 #include "ui/views/layout/layout_constants.h" | 45 #include "ui/views/layout/layout_constants.h" |
| 49 #include "ui/views/view.h" | |
| 50 #include "ui/views/widget/widget.h" | 46 #include "ui/views/widget/widget.h" |
| 51 #include "ui/views/window/dialog_client_view.h" | 47 #include "ui/views/window/dialog_client_view.h" |
| 52 #include "ui/views/window/dialog_delegate.h" | |
| 53 | 48 |
| 54 using content::OpenURLParams; | 49 using content::OpenURLParams; |
| 55 using content::Referrer; | 50 using content::Referrer; |
| 56 using extensions::BundleInstaller; | 51 using extensions::BundleInstaller; |
| 57 | 52 |
| 58 namespace { | 53 namespace { |
| 59 | 54 |
| 55 // Width of the bullet column in BulletedView. |
| 56 const int kBulletWidth = 20; |
| 57 |
| 60 // Size of extension icon in top left of dialog. | 58 // Size of extension icon in top left of dialog. |
| 61 const int kIconSize = 64; | 59 const int kIconSize = 64; |
| 62 | 60 |
| 63 // We offset the icon a little bit from the right edge of the dialog, to make it | 61 // We offset the icon a little bit from the right edge of the dialog, to make it |
| 64 // align with the button below it. | 62 // align with the button below it. |
| 65 const int kIconOffset = 16; | 63 const int kIconOffset = 16; |
| 66 | 64 |
| 67 // The dialog will resize based on its content, but this sets a maximum height | 65 // The dialog will resize based on its content, but this sets a maximum height |
| 68 // before overflowing a scrollbar. | 66 // before overflowing a scrollbar. |
| 69 const int kDialogMaxHeight = 300; | 67 const int kDialogMaxHeight = 300; |
| (...skipping 21 matching lines...) Expand all Loading... |
| 91 // experiment. This is used to group the actions in UMA histograms named | 89 // experiment. This is used to group the actions in UMA histograms named |
| 92 // Extensions.InstallPromptExperiment.ShowDetails and | 90 // Extensions.InstallPromptExperiment.ShowDetails and |
| 93 // Extensions.InstallPromptExperiment.ShowPermissions. | 91 // Extensions.InstallPromptExperiment.ShowPermissions. |
| 94 enum ExperimentLinkAction { | 92 enum ExperimentLinkAction { |
| 95 LINK_SHOWN = 0, | 93 LINK_SHOWN = 0, |
| 96 LINK_NOT_SHOWN, | 94 LINK_NOT_SHOWN, |
| 97 LINK_CLICKED, | 95 LINK_CLICKED, |
| 98 NUM_LINK_ACTIONS | 96 NUM_LINK_ACTIONS |
| 99 }; | 97 }; |
| 100 | 98 |
| 101 typedef std::vector<base::string16> PermissionDetails; | |
| 102 class ExpandableContainerView; | |
| 103 | |
| 104 void AddResourceIcon(const gfx::ImageSkia* skia_image, void* data) { | 99 void AddResourceIcon(const gfx::ImageSkia* skia_image, void* data) { |
| 105 views::View* parent = static_cast<views::View*>(data); | 100 views::View* parent = static_cast<views::View*>(data); |
| 106 views::ImageView* image_view = new views::ImageView(); | 101 views::ImageView* image_view = new views::ImageView(); |
| 107 image_view->SetImage(*skia_image); | 102 image_view->SetImage(*skia_image); |
| 108 parent->AddChildView(image_view); | 103 parent->AddChildView(image_view); |
| 109 } | 104 } |
| 110 | 105 |
| 111 // Creates a string for displaying |message| to the user. If it has to look | 106 // Creates a string for displaying |message| to the user. If it has to look |
| 112 // like a entry in a bullet point list, one is added. | 107 // like a entry in a bullet point list, one is added. |
| 113 base::string16 PrepareForDisplay(const base::string16& message, | 108 base::string16 PrepareForDisplay(const base::string16& message, |
| 114 bool bullet_point) { | 109 bool bullet_point) { |
| 115 return bullet_point ? l10n_util::GetStringFUTF16( | 110 return bullet_point ? l10n_util::GetStringFUTF16( |
| 116 IDS_EXTENSION_PERMISSION_LINE, | 111 IDS_EXTENSION_PERMISSION_LINE, |
| 117 message) : message; | 112 message) : message; |
| 118 } | 113 } |
| 119 | 114 |
| 120 // A custom scrollable view implementation for the dialog. | 115 } // namespace |
| 121 class CustomScrollableView : public views::View { | |
| 122 public: | |
| 123 CustomScrollableView(); | |
| 124 virtual ~CustomScrollableView(); | |
| 125 | |
| 126 private: | |
| 127 virtual void Layout() OVERRIDE; | |
| 128 | |
| 129 DISALLOW_COPY_AND_ASSIGN(CustomScrollableView); | |
| 130 }; | |
| 131 | |
| 132 // Implements the extension installation dialog for TOOLKIT_VIEWS. | |
| 133 class ExtensionInstallDialogView : public views::DialogDelegateView, | |
| 134 public views::LinkListener, | |
| 135 public views::ButtonListener { | |
| 136 public: | |
| 137 ExtensionInstallDialogView( | |
| 138 content::PageNavigator* navigator, | |
| 139 ExtensionInstallPrompt::Delegate* delegate, | |
| 140 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt); | |
| 141 virtual ~ExtensionInstallDialogView(); | |
| 142 | |
| 143 // Called when one of the child elements has expanded/collapsed. | |
| 144 void ContentsChanged(); | |
| 145 | |
| 146 private: | |
| 147 // views::DialogDelegateView: | |
| 148 virtual int GetDialogButtons() const OVERRIDE; | |
| 149 virtual base::string16 GetDialogButtonLabel( | |
| 150 ui::DialogButton button) const OVERRIDE; | |
| 151 virtual int GetDefaultDialogButton() const OVERRIDE; | |
| 152 virtual bool Cancel() OVERRIDE; | |
| 153 virtual bool Accept() OVERRIDE; | |
| 154 virtual ui::ModalType GetModalType() const OVERRIDE; | |
| 155 virtual base::string16 GetWindowTitle() const OVERRIDE; | |
| 156 virtual void Layout() OVERRIDE; | |
| 157 virtual gfx::Size GetPreferredSize() const OVERRIDE; | |
| 158 virtual void ViewHierarchyChanged( | |
| 159 const ViewHierarchyChangedDetails& details) OVERRIDE; | |
| 160 | |
| 161 // views::LinkListener: | |
| 162 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; | |
| 163 | |
| 164 // views::ButtonListener: | |
| 165 virtual void ButtonPressed(views::Button* sender, | |
| 166 const ui::Event& event) OVERRIDE; | |
| 167 | |
| 168 // Experimental: Toggles inline permission explanations with an animation. | |
| 169 void ToggleInlineExplanations(); | |
| 170 | |
| 171 // Creates a layout consisting of dialog header, extension name and icon. | |
| 172 views::GridLayout* CreateLayout( | |
| 173 views::View* parent, | |
| 174 int left_column_width, | |
| 175 int column_set_id, | |
| 176 bool single_detail_row) const; | |
| 177 | |
| 178 bool is_inline_install() const { | |
| 179 return prompt_->type() == ExtensionInstallPrompt::INLINE_INSTALL_PROMPT; | |
| 180 } | |
| 181 | |
| 182 bool is_bundle_install() const { | |
| 183 return prompt_->type() == ExtensionInstallPrompt::BUNDLE_INSTALL_PROMPT; | |
| 184 } | |
| 185 | |
| 186 bool is_external_install() const { | |
| 187 return prompt_->type() == ExtensionInstallPrompt::EXTERNAL_INSTALL_PROMPT; | |
| 188 } | |
| 189 | |
| 190 // Updates the histogram that holds installation accepted/aborted data. | |
| 191 void UpdateInstallResultHistogram(bool accepted) const; | |
| 192 | |
| 193 // Updates the histogram that holds data about whether "Show details" or | |
| 194 // "Show permissions" links were shown and/or clicked. | |
| 195 void UpdateLinkActionHistogram(int action_type) const; | |
| 196 | |
| 197 content::PageNavigator* navigator_; | |
| 198 ExtensionInstallPrompt::Delegate* delegate_; | |
| 199 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt_; | |
| 200 | |
| 201 // The scroll view containing all the details for the dialog (including all | |
| 202 // collapsible/expandable sections). | |
| 203 views::ScrollView* scroll_view_; | |
| 204 | |
| 205 // The container view for the scroll view. | |
| 206 CustomScrollableView* scrollable_; | |
| 207 | |
| 208 // The container for the simpler view with only the dialog header and the | |
| 209 // extension icon. Used for the experiment where the permissions are | |
| 210 // initially hidden when the dialog shows. | |
| 211 CustomScrollableView* scrollable_header_only_; | |
| 212 | |
| 213 // The preferred size of the dialog. | |
| 214 gfx::Size dialog_size_; | |
| 215 | |
| 216 // Experimental: "Show details" link to expand inline explanations and reveal | |
| 217 // permision dialog. | |
| 218 views::Link* show_details_link_; | |
| 219 | |
| 220 // Experimental: Label for showing information about the checkboxes. | |
| 221 views::Label* checkbox_info_label_; | |
| 222 | |
| 223 // Experimental: Contains pointers to inline explanation views. | |
| 224 typedef std::vector<ExpandableContainerView*> InlineExplanations; | |
| 225 InlineExplanations inline_explanations_; | |
| 226 | |
| 227 // Experimental: Number of unchecked checkboxes in the permission list. | |
| 228 // If this becomes zero, the accept button is enabled, otherwise disabled. | |
| 229 int unchecked_boxes_; | |
| 230 | |
| 231 DISALLOW_COPY_AND_ASSIGN(ExtensionInstallDialogView); | |
| 232 }; | |
| 233 | |
| 234 // A simple view that prepends a view with a bullet with the help of a grid | |
| 235 // layout. | |
| 236 class BulletedView : public views::View { | |
| 237 public: | |
| 238 explicit BulletedView(views::View* view); | |
| 239 private: | |
| 240 DISALLOW_COPY_AND_ASSIGN(BulletedView); | |
| 241 }; | |
| 242 | 116 |
| 243 BulletedView::BulletedView(views::View* view) { | 117 BulletedView::BulletedView(views::View* view) { |
| 244 views::GridLayout* layout = new views::GridLayout(this); | 118 views::GridLayout* layout = new views::GridLayout(this); |
| 245 SetLayoutManager(layout); | 119 SetLayoutManager(layout); |
| 246 views::ColumnSet* column_set = layout->AddColumnSet(0); | 120 views::ColumnSet* column_set = layout->AddColumnSet(0); |
| 121 column_set->AddColumn(views::GridLayout::CENTER, |
| 122 views::GridLayout::LEADING, |
| 123 0, |
| 124 views::GridLayout::FIXED, |
| 125 kBulletWidth, |
| 126 0); |
| 247 column_set->AddColumn(views::GridLayout::LEADING, | 127 column_set->AddColumn(views::GridLayout::LEADING, |
| 248 views::GridLayout::LEADING, | 128 views::GridLayout::LEADING, |
| 249 0, | 129 0, |
| 250 views::GridLayout::USE_PREF, | 130 views::GridLayout::USE_PREF, |
| 251 0, // no fixed width | 131 0, // No fixed width. |
| 252 0); | 132 0); |
| 253 column_set->AddColumn(views::GridLayout::LEADING, | |
| 254 views::GridLayout::LEADING, | |
| 255 0, | |
| 256 views::GridLayout::USE_PREF, | |
| 257 0, // no fixed width | |
| 258 0); | |
| 259 layout->StartRow(0, 0); | 133 layout->StartRow(0, 0); |
| 260 layout->AddView(new views::Label(PrepareForDisplay(base::string16(), true))); | 134 layout->AddView(new views::Label(PrepareForDisplay(base::string16(), true))); |
| 261 layout->AddView(view); | 135 layout->AddView(view); |
| 262 } | 136 } |
| 263 | 137 |
| 264 // A simple view that prepends a view with a checkbox with the help of a grid | |
| 265 // layout. Used for the permission experiment. | |
| 266 // TODO(meacer): Remove once the experiment is completed. | |
| 267 class CheckboxedView : public views::View { | |
| 268 public: | |
| 269 CheckboxedView(views::View* view, views::ButtonListener* listener); | |
| 270 private: | |
| 271 DISALLOW_COPY_AND_ASSIGN(CheckboxedView); | |
| 272 }; | |
| 273 | |
| 274 CheckboxedView::CheckboxedView(views::View* view, | 138 CheckboxedView::CheckboxedView(views::View* view, |
| 275 views::ButtonListener* listener) { | 139 views::ButtonListener* listener) { |
| 276 views::GridLayout* layout = new views::GridLayout(this); | 140 views::GridLayout* layout = new views::GridLayout(this); |
| 277 SetLayoutManager(layout); | 141 SetLayoutManager(layout); |
| 278 views::ColumnSet* column_set = layout->AddColumnSet(0); | 142 views::ColumnSet* column_set = layout->AddColumnSet(0); |
| 279 column_set->AddColumn(views::GridLayout::LEADING, | 143 column_set->AddColumn(views::GridLayout::LEADING, |
| 280 views::GridLayout::LEADING, | 144 views::GridLayout::LEADING, |
| 281 0, | 145 0, |
| 282 views::GridLayout::USE_PREF, | 146 views::GridLayout::USE_PREF, |
| 283 0, // no fixed width | 147 0, // No fixed width. |
| 284 0); | 148 0); |
| 285 column_set->AddColumn(views::GridLayout::LEADING, | 149 column_set->AddColumn(views::GridLayout::LEADING, |
| 286 views::GridLayout::LEADING, | 150 views::GridLayout::LEADING, |
| 287 0, | 151 0, |
| 288 views::GridLayout::USE_PREF, | 152 views::GridLayout::USE_PREF, |
| 289 0, // no fixed width | 153 0, // No fixed width. |
| 290 0); | 154 0); |
| 291 layout->StartRow(0, 0); | 155 layout->StartRow(0, 0); |
| 292 views::Checkbox* checkbox = new views::Checkbox(base::string16()); | 156 views::Checkbox* checkbox = new views::Checkbox(base::string16()); |
| 293 checkbox->set_listener(listener); | 157 checkbox->set_listener(listener); |
| 294 // Alignment needs to be explicitly set again here, otherwise the views are | 158 // Alignment needs to be explicitly set again here, otherwise the views are |
| 295 // not vertically centered. | 159 // not vertically centered. |
| 296 layout->AddView(checkbox, 1, 1, | 160 layout->AddView(checkbox, 1, 1, |
| 297 views::GridLayout::LEADING, views::GridLayout::CENTER); | 161 views::GridLayout::LEADING, views::GridLayout::CENTER); |
| 298 layout->AddView(view, 1, 1, | 162 layout->AddView(view, 1, 1, |
| 299 views::GridLayout::LEADING, views::GridLayout::CENTER); | 163 views::GridLayout::LEADING, views::GridLayout::CENTER); |
| 300 } | 164 } |
| 301 | 165 |
| 302 // A view to display text with an expandable details section. | |
| 303 class ExpandableContainerView : public views::View, | |
| 304 public views::ButtonListener, | |
| 305 public views::LinkListener, | |
| 306 public gfx::AnimationDelegate { | |
| 307 public: | |
| 308 ExpandableContainerView(ExtensionInstallDialogView* owner, | |
| 309 const base::string16& description, | |
| 310 const PermissionDetails& details, | |
| 311 int horizontal_space, | |
| 312 bool parent_bulleted, | |
| 313 bool show_expand_link, | |
| 314 bool lighter_color_details); | |
| 315 virtual ~ExpandableContainerView(); | |
| 316 | |
| 317 // views::View: | |
| 318 virtual void ChildPreferredSizeChanged(views::View* child) OVERRIDE; | |
| 319 | |
| 320 // views::ButtonListener: | |
| 321 virtual void ButtonPressed(views::Button* sender, | |
| 322 const ui::Event& event) OVERRIDE; | |
| 323 | |
| 324 // views::LinkListener: | |
| 325 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE; | |
| 326 | |
| 327 // gfx::AnimationDelegate: | |
| 328 virtual void AnimationProgressed(const gfx::Animation* animation) OVERRIDE; | |
| 329 virtual void AnimationEnded(const gfx::Animation* animation) OVERRIDE; | |
| 330 | |
| 331 // Expand/Collapse the detail section for this ExpandableContainerView. | |
| 332 void ToggleDetailLevel(); | |
| 333 | |
| 334 // Expand the detail section without any animation. | |
| 335 // TODO(meacer): Remove once the experiment is completed. | |
| 336 void ExpandWithoutAnimation(); | |
| 337 | |
| 338 private: | |
| 339 // A view which displays all the details of an IssueAdviceInfoEntry. | |
| 340 class DetailsView : public views::View { | |
| 341 public: | |
| 342 explicit DetailsView(int horizontal_space, bool parent_bulleted, | |
| 343 bool lighter_color); | |
| 344 virtual ~DetailsView() {} | |
| 345 | |
| 346 // views::View: | |
| 347 virtual gfx::Size GetPreferredSize() const OVERRIDE; | |
| 348 | |
| 349 void AddDetail(const base::string16& detail); | |
| 350 | |
| 351 // Animates this to be a height proportional to |state|. | |
| 352 void AnimateToState(double state); | |
| 353 | |
| 354 private: | |
| 355 views::GridLayout* layout_; | |
| 356 double state_; | |
| 357 | |
| 358 // Whether the detail text should be shown with a lighter color. | |
| 359 bool lighter_color_; | |
| 360 | |
| 361 DISALLOW_COPY_AND_ASSIGN(DetailsView); | |
| 362 }; | |
| 363 | |
| 364 // The dialog that owns |this|. It's also an ancestor in the View hierarchy. | |
| 365 ExtensionInstallDialogView* owner_; | |
| 366 | |
| 367 // A view for showing |issue_advice.details|. | |
| 368 DetailsView* details_view_; | |
| 369 | |
| 370 // The 'more details' link shown under the heading (changes to 'hide details' | |
| 371 // when the details section is expanded). | |
| 372 views::Link* more_details_; | |
| 373 | |
| 374 gfx::SlideAnimation slide_animation_; | |
| 375 | |
| 376 // The up/down arrow next to the 'more detail' link (points up/down depending | |
| 377 // on whether the details section is expanded). | |
| 378 views::ImageButton* arrow_toggle_; | |
| 379 | |
| 380 // Whether the details section is expanded. | |
| 381 bool expanded_; | |
| 382 | |
| 383 DISALLOW_COPY_AND_ASSIGN(ExpandableContainerView); | |
| 384 }; | |
| 385 | |
| 386 void ShowExtensionInstallDialogImpl( | 166 void ShowExtensionInstallDialogImpl( |
| 387 const ExtensionInstallPrompt::ShowParams& show_params, | 167 const ExtensionInstallPrompt::ShowParams& show_params, |
| 388 ExtensionInstallPrompt::Delegate* delegate, | 168 ExtensionInstallPrompt::Delegate* delegate, |
| 389 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) { | 169 scoped_refptr<ExtensionInstallPrompt::Prompt> prompt) { |
| 390 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 170 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 391 CreateBrowserModalDialogViews( | 171 CreateBrowserModalDialogViews( |
| 392 new ExtensionInstallDialogView(show_params.navigator, delegate, prompt), | 172 new ExtensionInstallDialogView(show_params.navigator, delegate, prompt), |
| 393 show_params.parent_window)->Show(); | 173 show_params.parent_window)->Show(); |
| 394 } | 174 } |
| 395 | 175 |
| 396 } // namespace | |
| 397 | |
| 398 CustomScrollableView::CustomScrollableView() {} | 176 CustomScrollableView::CustomScrollableView() {} |
| 399 CustomScrollableView::~CustomScrollableView() {} | 177 CustomScrollableView::~CustomScrollableView() {} |
| 400 | 178 |
| 401 void CustomScrollableView::Layout() { | 179 void CustomScrollableView::Layout() { |
| 402 SetBounds(x(), y(), width(), GetHeightForWidth(width())); | 180 SetBounds(x(), y(), width(), GetHeightForWidth(width())); |
| 403 views::View::Layout(); | 181 views::View::Layout(); |
| 404 } | 182 } |
| 405 | 183 |
| 406 ExtensionInstallDialogView::ExtensionInstallDialogView( | 184 ExtensionInstallDialogView::ExtensionInstallDialogView( |
| 407 content::PageNavigator* navigator, | 185 content::PageNavigator* navigator, |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 629 permission_label->SetEnabledColor(kTextHighlight); | 407 permission_label->SetEnabledColor(kTextHighlight); |
| 630 } else if (prompt->experiment()->ShouldHighlightBackground( | 408 } else if (prompt->experiment()->ShouldHighlightBackground( |
| 631 prompt->GetPermission(i))) { | 409 prompt->GetPermission(i))) { |
| 632 permission_label->SetLineHeight(18); | 410 permission_label->SetLineHeight(18); |
| 633 permission_label->set_background( | 411 permission_label->set_background( |
| 634 views::Background::CreateSolidBackground(kBackgroundHighlight)); | 412 views::Background::CreateSolidBackground(kBackgroundHighlight)); |
| 635 } | 413 } |
| 636 | 414 |
| 637 permission_label->SetMultiLine(true); | 415 permission_label->SetMultiLine(true); |
| 638 permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); | 416 permission_label->SetHorizontalAlignment(gfx::ALIGN_LEFT); |
| 639 permission_label->SizeToFit(left_column_width); | |
| 640 | 417 |
| 641 if (prompt->experiment()->show_checkboxes()) { | 418 if (prompt->experiment()->show_checkboxes()) { |
| 419 permission_label->SizeToFit(left_column_width); |
| 642 layout->AddView(new CheckboxedView(permission_label, this)); | 420 layout->AddView(new CheckboxedView(permission_label, this)); |
| 643 ++unchecked_boxes_; | 421 ++unchecked_boxes_; |
| 644 } else { | 422 } else { |
| 423 permission_label->SizeToFit(left_column_width - kBulletWidth); |
| 645 layout->AddView(new BulletedView(permission_label)); | 424 layout->AddView(new BulletedView(permission_label)); |
| 646 } | 425 } |
| 426 |
| 647 // If we have more details to provide, show them in collapsed form. | 427 // If we have more details to provide, show them in collapsed form. |
| 648 if (!prompt->GetPermissionsDetails(i).empty()) { | 428 if (!prompt->GetPermissionsDetails(i).empty()) { |
| 649 layout->StartRow(0, column_set_id); | 429 layout->StartRow(0, column_set_id); |
| 650 PermissionDetails details; | 430 PermissionDetails details; |
| 651 details.push_back( | 431 details.push_back( |
| 652 PrepareForDisplay(prompt->GetPermissionsDetails(i), false)); | 432 PrepareForDisplay(prompt->GetPermissionsDetails(i), false)); |
| 653 ExpandableContainerView* details_container = | 433 ExpandableContainerView* details_container = |
| 654 new ExpandableContainerView( | 434 new ExpandableContainerView( |
| 655 this, base::string16(), details, left_column_width, | 435 this, base::string16(), details, left_column_width, |
| 656 true, true, false); | 436 true, true, false); |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1057 NUM_LINK_ACTIONS); | 837 NUM_LINK_ACTIONS); |
| 1058 } else { | 838 } else { |
| 1059 // The clickable link in the UI is "Show Details". | 839 // The clickable link in the UI is "Show Details". |
| 1060 UMA_HISTOGRAM_ENUMERATION( | 840 UMA_HISTOGRAM_ENUMERATION( |
| 1061 "Extensions.InstallPromptExperiment.ShowDetails", | 841 "Extensions.InstallPromptExperiment.ShowDetails", |
| 1062 action_type, | 842 action_type, |
| 1063 NUM_LINK_ACTIONS); | 843 NUM_LINK_ACTIONS); |
| 1064 } | 844 } |
| 1065 } | 845 } |
| 1066 | 846 |
| 1067 // static | |
| 1068 ExtensionInstallPrompt::ShowDialogCallback | |
| 1069 ExtensionInstallPrompt::GetDefaultShowDialogCallback() { | |
| 1070 return base::Bind(&ShowExtensionInstallDialogImpl); | |
| 1071 } | |
| 1072 | |
| 1073 // ExpandableContainerView::DetailsView ---------------------------------------- | 847 // ExpandableContainerView::DetailsView ---------------------------------------- |
| 1074 | 848 |
| 1075 ExpandableContainerView::DetailsView::DetailsView(int horizontal_space, | 849 ExpandableContainerView::DetailsView::DetailsView(int horizontal_space, |
| 1076 bool parent_bulleted, | 850 bool parent_bulleted, |
| 1077 bool lighter_color) | 851 bool lighter_color) |
| 1078 : layout_(new views::GridLayout(this)), | 852 : layout_(new views::GridLayout(this)), |
| 1079 state_(0), | 853 state_(0), |
| 1080 lighter_color_(lighter_color) { | 854 lighter_color_(lighter_color) { |
| 1081 SetLayoutManager(layout_); | 855 SetLayoutManager(layout_); |
| 1082 views::ColumnSet* column_set = layout_->AddColumnSet(0); | 856 views::ColumnSet* column_set = layout_->AddColumnSet(0); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1276 if (slide_animation_.IsShowing()) | 1050 if (slide_animation_.IsShowing()) |
| 1277 slide_animation_.Hide(); | 1051 slide_animation_.Hide(); |
| 1278 else | 1052 else |
| 1279 slide_animation_.Show(); | 1053 slide_animation_.Show(); |
| 1280 } | 1054 } |
| 1281 | 1055 |
| 1282 void ExpandableContainerView::ExpandWithoutAnimation() { | 1056 void ExpandableContainerView::ExpandWithoutAnimation() { |
| 1283 expanded_ = true; | 1057 expanded_ = true; |
| 1284 details_view_->AnimateToState(1.0); | 1058 details_view_->AnimateToState(1.0); |
| 1285 } | 1059 } |
| 1060 |
| 1061 // static |
| 1062 ExtensionInstallPrompt::ShowDialogCallback |
| 1063 ExtensionInstallPrompt::GetDefaultShowDialogCallback() { |
| 1064 return base::Bind(&ShowExtensionInstallDialogImpl); |
| 1065 } |
| OLD | NEW |