blob: 1229e8ae3720b2e065d9c9d87caa9aa0ba5a48b4 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// 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/autofill/edit_address_profile_view.h"
#include <memory>
#include <utility>
#include "base/functional/bind.h"
#include "chrome/browser/autofill/personal_data_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/autofill/address_editor_controller.h"
#include "chrome/browser/ui/autofill/autofill_bubble_base.h"
#include "chrome/browser/ui/autofill/edit_address_profile_dialog_controller.h"
#include "chrome/browser/ui/autofill/edit_address_profile_view.h"
#include "chrome/browser/ui/views/autofill/address_editor_view.h"
#include "chrome/browser/ui/views/chrome_layout_provider.h"
#include "components/autofill/core/common/autofill_features.h"
#include "components/constrained_window/constrained_window_views.h"
#include "components/strings/grit/components_strings.h"
#include "content/public/browser/web_contents.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/views/controls/label.h"
#include "ui/views/layout/box_layout.h"
#include "ui/views/layout/fill_layout.h"
#include "ui/views/view_class_properties.h"
namespace autofill {
AutofillBubbleBase* ShowEditAddressProfileDialogView(
content::WebContents* web_contents,
EditAddressProfileDialogController* controller) {
EditAddressProfileView* dialog = new EditAddressProfileView(controller);
dialog->ShowForWebContents(web_contents);
constrained_window::ShowWebModalDialogViews(dialog, web_contents);
dialog->RequestFocus();
return dialog;
}
EditAddressProfileView::EditAddressProfileView(
EditAddressProfileDialogController* controller)
: controller_(controller) {
DCHECK(controller);
SetButtons(ui::DIALOG_BUTTON_OK | ui::DIALOG_BUTTON_CANCEL);
SetModalType(ui::MODAL_TYPE_CHILD);
SetShowCloseButton(false);
set_fixed_width(views::LayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_MODAL_DIALOG_PREFERRED_WIDTH));
SetAcceptCallbackWithClose(base::BindRepeating(
&EditAddressProfileView::OnAcceptButtonClicked, base::Unretained(this)));
SetCancelCallback(base::BindOnce(
&EditAddressProfileView::OnUserDecision, base::Unretained(this),
AutofillClient::AddressPromptUserDecision::kEditDeclined));
SetLayoutManager(std::make_unique<views::BoxLayout>(
views::BoxLayout::Orientation::kVertical, gfx::Insets(),
views::LayoutProvider::Get()->GetDistanceMetric(
views::DISTANCE_RELATED_CONTROL_VERTICAL)));
set_margins(ChromeLayoutProvider::Get()->GetInsetsMetric(
views::InsetsMetric::INSETS_DIALOG));
SetProperty(views::kElementIdentifierKey, kTopViewId);
SetTitle(controller_->GetWindowTitle());
SetButtonLabel(ui::DIALOG_BUTTON_OK, controller_->GetOkButtonLabel());
SetButtonLabel(ui::DIALOG_BUTTON_CANCEL,
l10n_util::GetStringUTF16(
IDS_AUTOFILL_EDIT_ADDRESS_DIALOG_CANCEL_BUTTON_LABEL));
}
EditAddressProfileView::~EditAddressProfileView() = default;
void EditAddressProfileView::ShowForWebContents(
content::WebContents* web_contents) {
DCHECK(web_contents);
Profile* profile =
Profile::FromBrowserContext(web_contents->GetBrowserContext());
auto address_editor_controller = std::make_unique<AddressEditorController>(
controller_->GetProfileToEdit(),
autofill::PersonalDataManagerFactory::GetForProfile(
profile->GetOriginalProfile()),
controller_->GetIsValidatable());
// Storing subscription (which gets canceled in the destructor) in a property
// secures using of Unretained(this).
on_is_valid_change_subscription_ =
address_editor_controller->AddIsValidChangedCallback(
base::BindRepeating(&EditAddressProfileView::UpdateActionButtonState,
base::Unretained(this)));
address_editor_view_ = AddChildView(std::make_unique<AddressEditorView>(
std::move(address_editor_controller)));
const std::u16string& footer_message = controller_->GetFooterMessage();
if (!footer_message.empty()) {
AddChildView(
views::Builder<views::Label>()
.SetText(footer_message)
.SetTextStyle(views::style::STYLE_SECONDARY)
.SetHorizontalAlignment(gfx::HorizontalAlignment::ALIGN_LEFT)
.SetMultiLine(true)
.Build());
}
}
void EditAddressProfileView::Hide() {
controller_ = nullptr;
GetWidget()->Close();
}
views::View* EditAddressProfileView::GetInitiallyFocusedView() {
return address_editor_view_ ? address_editor_view_->initial_focus_view()
: nullptr;
}
void EditAddressProfileView::WindowClosing() {
if (controller_) {
controller_->OnDialogClosed(
decision_,
decision_ == AutofillClient::AddressPromptUserDecision::kEditAccepted
? base::optional_ref(address_editor_view_->GetAddressProfile())
: std::nullopt);
controller_ = nullptr;
}
}
void EditAddressProfileView::ChildPreferredSizeChanged(views::View* child) {
const int width = fixed_width();
GetWidget()->SetSize(gfx::Size(width, GetHeightForWidth(width)));
}
AddressEditorView* EditAddressProfileView::GetAddressEditorViewForTesting() {
return address_editor_view_;
}
void EditAddressProfileView::OnUserDecision(
AutofillClient::AddressPromptUserDecision decision) {
decision_ = decision;
}
void EditAddressProfileView::UpdateActionButtonState(bool is_valid) {
SetButtonEnabled(ui::DIALOG_BUTTON_OK, is_valid);
}
bool EditAddressProfileView::OnAcceptButtonClicked() {
bool is_form_valid = address_editor_view_->ValidateAllFields();
if (is_form_valid) {
OnUserDecision(AutofillClient::AddressPromptUserDecision::kEditAccepted);
}
return is_form_valid;
}
DEFINE_CLASS_ELEMENT_IDENTIFIER_VALUE(EditAddressProfileView, kTopViewId);
} // namespace autofill