Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(980)

Unified Diff: chrome/browser/ui/views/settings_reset_prompt_dialog.cc

Issue 2701313002: Adds a modal dialog implementation of the settings reset prompt. (Closed)
Patch Set: Fix constness in mock test class Created 3 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/views/settings_reset_prompt_dialog.cc
diff --git a/chrome/browser/ui/views/settings_reset_prompt_dialog.cc b/chrome/browser/ui/views/settings_reset_prompt_dialog.cc
new file mode 100644
index 0000000000000000000000000000000000000000..9407cabccf51d4c17d929635df8695e00509d361
--- /dev/null
+++ b/chrome/browser/ui/views/settings_reset_prompt_dialog.cc
@@ -0,0 +1,325 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/ui/views/settings_reset_prompt_dialog.h"
+
+#include <vector>
+
+#include "chrome/browser/safe_browsing/settings_reset_prompt/settings_reset_prompt_controller.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/chrome_web_modal_dialog_manager_delegate.h"
+#include "chrome/browser/ui/views/frame/browser_view.h"
+#include "chrome/browser/ui/views/toolbar/app_menu_button.h"
+#include "chrome/browser/ui/views/toolbar/toolbar_view.h"
+#include "components/constrained_window/constrained_window_views.h"
+#include "components/web_modal/web_contents_modal_dialog_host.h"
+#include "ui/gfx/color_palette.h"
+#include "ui/gfx/image/image.h"
+#include "ui/gfx/paint_vector_icon.h"
+#include "ui/gfx/text_constants.h"
+#include "ui/gfx/vector_icons_public.h"
+#include "ui/views/bubble/bubble_border.h"
+#include "ui/views/controls/label.h"
+#include "ui/views/controls/link.h"
+#include "ui/views/controls/scroll_view.h"
+#include "ui/views/controls/separator.h"
+#include "ui/views/layout/box_layout.h"
+#include "ui/views/layout/grid_layout.h"
+#include "ui/views/layout/layout_constants.h"
+#include "ui/views/view.h"
+#include "ui/views/widget/widget.h"
+
+namespace safe_browsing {
+
+// static
+void SettingsResetPromptController::ShowSettingsResetPrompt(
+ Browser* browser,
+ SettingsResetPromptController* controller) {
+ SettingsResetPromptDialog* dialog = new SettingsResetPromptDialog(controller);
+ // The dialog will delete itself, as implemented in
+ // |DialogDelegateView::DeleteDelegate()|, when its widget is closed.
+ dialog->Show(browser);
+}
+
+} // namespace safe_browsing
+
+namespace {
+
+using LabelInfo = safe_browsing::SettingsResetPromptController::LabelInfo;
+
+constexpr int kDialogWidth = 512;
+constexpr int kDetailsSectionMaxHeight = 150;
+constexpr int kBulletColumnWidth = 5;
+// Constants used for the layout of the label views.
+static constexpr int kMainColumSetId = 0;
+static constexpr int kBulletColumnSetId = 1;
+
+// Helper function used by |CreateLabelView()| below that adds the labels as
+// specified by |labels| to |label_view|.
+void AddLabelsToLabelView(views::View* label_view,
+ views::GridLayout* layout,
+ const std::vector<LabelInfo>& labels) {
+ static const base::char16 kBulletPoint[] = {0x2022, 0};
+
+ bool first_label = true;
+ bool last_label_was_bullet = false;
+ for (const LabelInfo& label_info : labels) {
+ const bool is_bullet = label_info.type == LabelInfo::BULLET_ITEM;
+ views::Label* label = new views::Label(label_info.text);
+ label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
+ if (is_bullet) {
+ label->SetElideBehavior(gfx::ELIDE_TAIL);
+ } else {
+ label->SetMultiLine(true);
+ }
+
+ // Do not add a padding row if
+ // - this is the first label being added, or
+ // - a bullet item is being added and the last label was also a bullet item.
+ if (!(first_label || (is_bullet && last_label_was_bullet)))
+ layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
+
+ layout->StartRow(0, is_bullet ? kBulletColumnSetId : kMainColumSetId);
+ if (is_bullet) {
+ views::Label* bullet = new views::Label(base::string16(kBulletPoint));
+ layout->AddView(bullet);
+ }
+ layout->AddView(label);
+
+ last_label_was_bullet = is_bullet;
+ first_label = false;
+ }
+}
+
+// Creates a view that displays two types of labels: multiline labels or
+// indented single-line labels that are indented and start with a bullet
+// point. The indented text is intended to be used to display setting values
+// (URLs) and is elided if the text is too wide to fit in its entirety.
+views::View* CreateLabelView(int top_vertical_spacing,
+ const std::vector<LabelInfo>& labels) {
+ views::View* label_view = new views::View();
+ views::GridLayout* layout = new views::GridLayout(label_view);
+ label_view->SetLayoutManager(layout);
+
+ views::ColumnSet* main_column_set = layout->AddColumnSet(kMainColumSetId);
+ main_column_set->AddColumn(views::GridLayout::FILL,
+ views::GridLayout::LEADING,
+ /*resize_percent=*/1, views::GridLayout::USE_PREF,
+ /*fixed_width=*/0,
+ /*min_width=*/0);
+
+ views::ColumnSet* bullet_column_set_ =
+ layout->AddColumnSet(kBulletColumnSetId);
+ bullet_column_set_->AddPaddingColumn(
+ /*resize_percent=*/0, views::kUnrelatedControlLargeHorizontalSpacing);
+ bullet_column_set_->AddColumn(
+ views::GridLayout::FILL, views::GridLayout::LEADING,
+ /*resize_percent=*/0, views::GridLayout::USE_PREF,
+ /*fixed_width=*/0,
+ /*min_width=*/0);
+ bullet_column_set_->AddPaddingColumn(/*resize_percent=*/0,
+ kBulletColumnWidth);
+ bullet_column_set_->AddColumn(
+ views::GridLayout::FILL, views::GridLayout::LEADING,
+ /*resize_percent=*/1, views::GridLayout::USE_PREF,
+ /*fixed_width=*/0,
+ /*min_width=*/0);
+
+ if (top_vertical_spacing > 0)
+ layout->AddPaddingRow(/*vertical_resize=*/0, top_vertical_spacing);
+
+ AddLabelsToLabelView(label_view, layout, labels);
+ return label_view;
+}
+
+} // namespace
+
+////////////////////////////////////////////////////////////////////////////////
+// SettingsResetPromptDialog::ExpandableMessageView
+//
+// A view, whose visibilty can be toggled, and will be used for the details
+// section the main dialog.
+class SettingsResetPromptDialog::ExpandableMessageView : public views::View {
+ public:
+ explicit ExpandableMessageView(const std::vector<LabelInfo>& labels);
+ ~ExpandableMessageView() override;
+
+ void ToggleShowView();
+
+ // views::View overrides.
+ gfx::Size GetPreferredSize() const override;
+ int GetHeightForWidth(int width) const override;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ExpandableMessageView);
+};
+
+SettingsResetPromptDialog::ExpandableMessageView::ExpandableMessageView(
+ const std::vector<LabelInfo>& labels) {
+ views::GridLayout* layout = new views::GridLayout(this);
+ SetLayoutManager(layout);
+
+ SetVisible(false);
+
+ constexpr int kColumnId = 0;
+ views::ColumnSet* column_set = layout->AddColumnSet(kColumnId);
+ column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::LEADING,
+ /*resize_percent=*/1, views::GridLayout::USE_PREF,
+ /*fixed_width=*/0,
+ /*min_width=*/0);
+
+ // Add a horizontal line separator.
+ layout->StartRowWithPadding(
+ /*vertical_resize=*/0, kColumnId,
+ /*padding_resize=*/0, views::kUnrelatedControlVerticalSpacing);
+ layout->AddView(new views::Separator());
+
+ // Add the main message view inside a scroll view.
+ views::View* label_view =
+ CreateLabelView(views::kUnrelatedControlVerticalSpacing, labels);
+ views::ScrollView* scroll_view = new views::ScrollView();
+ scroll_view->ClipHeightTo(/*min_height=*/0, kDetailsSectionMaxHeight);
+ scroll_view->SetContents(label_view);
+ layout->StartRow(0, kColumnId);
+ layout->AddView(scroll_view);
+}
+
+SettingsResetPromptDialog::ExpandableMessageView::~ExpandableMessageView() {}
+
+void SettingsResetPromptDialog::ExpandableMessageView::ToggleShowView() {
+ SetVisible(!visible());
+ PreferredSizeChanged();
+}
+
+gfx::Size SettingsResetPromptDialog::ExpandableMessageView::GetPreferredSize()
+ const {
+ gfx::Size size = views::View::GetPreferredSize();
+ return gfx::Size(size.width(), visible() ? size.height() : 0);
+}
+
+int SettingsResetPromptDialog::ExpandableMessageView::GetHeightForWidth(
+ int width) const {
+ return GetPreferredSize().height();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// SettingsResetPromptDialog
+
+SettingsResetPromptDialog::SettingsResetPromptDialog(
+ safe_browsing::SettingsResetPromptController* controller)
+ : browser_(nullptr),
+ controller_(controller),
+ interaction_done_(false),
+ details_link_(nullptr) {
+ DCHECK(controller_);
+
+ SetLayoutManager(new views::BoxLayout(views::BoxLayout::kVertical,
+ views::kButtonHEdgeMarginNew,
+ views::kPanelVertMargin, 0));
+
+ // Add the dialog's main label view.
+ AddChildView(CreateLabelView(0, controller_->GetMainText()));
+
+ // Add the main details view that starts off not being visible.
+ details_view_ = new ExpandableMessageView(controller_->GetDetailsText());
+ AddChildView(details_view_);
+}
+
+SettingsResetPromptDialog::~SettingsResetPromptDialog() {
+ // Make sure the controller is correctly notified in case the dialog widget is
+ // closed by some other means than the dialog buttons.
+ Close();
+}
+
+void SettingsResetPromptDialog::Show(Browser* browser) {
+ DCHECK(browser);
+ browser_ = browser;
+ BrowserView* browser_view = BrowserView::GetBrowserViewForBrowser(browser);
+ constrained_window::CreateBrowserModalDialogViews(
+ this, browser_view->GetNativeWindow())
+ ->Show();
+}
+
+// WidgetDelegate overrides.
+
+ui::ModalType SettingsResetPromptDialog::GetModalType() const {
+ return ui::MODAL_TYPE_WINDOW;
+}
+
+bool SettingsResetPromptDialog::ShouldShowWindowIcon() const {
+ return true;
+}
+
+gfx::ImageSkia SettingsResetPromptDialog::GetWindowIcon() {
+ return gfx::CreateVectorIcon(gfx::VectorIconId::WARNING, 32 /* Icon size. */,
+ gfx::kGoogleRed700);
+}
+
+base::string16 SettingsResetPromptDialog::GetWindowTitle() const {
+ return controller_->GetWindowTitle();
+}
+
+// DialogModel overrides.
+
+bool SettingsResetPromptDialog::ShouldDefaultButtonBeBlue() const {
+ return true;
+}
+
+// DialogDelegate overrides.
+
+base::string16 SettingsResetPromptDialog::GetDialogButtonLabel(
+ ui::DialogButton button) const {
+ DCHECK(button == ui::DIALOG_BUTTON_OK || button == ui::DIALOG_BUTTON_CANCEL);
+
+ if (button == ui::DIALOG_BUTTON_OK)
+ return controller_->GetButtonLabel();
+ return DialogDelegate::GetDialogButtonLabel(button);
+}
+
+views::View* SettingsResetPromptDialog::CreateExtraView() {
+ // Add a "show details" link that toggles visibility of the details view.
+ details_link_ = new views::Link(controller_->GetShowDetailsLabel());
+ details_link_->SetUnderline(false);
+ details_link_->set_listener(this);
+ return details_link_;
+}
+
+bool SettingsResetPromptDialog::Accept() {
+ if (!interaction_done_) {
+ interaction_done_ = true;
+ controller_->Accept();
+ }
+ return true;
+}
+
+bool SettingsResetPromptDialog::Cancel() {
+ if (!interaction_done_) {
+ interaction_done_ = true;
+ controller_->Cancel();
+ }
+ return true;
+}
+
+// View overrides.
+
+gfx::Size SettingsResetPromptDialog::GetPreferredSize() const {
+ return gfx::Size(kDialogWidth, GetHeightForWidth(kDialogWidth));
+}
+
+// LinkListener overrides.
+
+void SettingsResetPromptDialog::LinkClicked(views::Link* source,
+ int event_flags) {
+ DCHECK_EQ(source, details_link_);
+ DCHECK(browser_);
+
+ details_view_->ToggleShowView();
+ details_link_->SetText(details_view_->visible()
+ ? controller_->GetHideDetailsLabel()
+ : controller_->GetShowDetailsLabel());
+
+ ChromeWebModalDialogManagerDelegate* manager = browser_;
+ constrained_window::UpdateWidgetModalDialogPosition(
+ GetWidget(), manager->GetWebContentsModalDialogHost());
+}

Powered by Google App Engine
This is Rietveld 408576698