From ef5184cf1cddffbd5f10657e3e6bf7c957ddd628 Mon Sep 17 00:00:00 2001
From: lat9nq <22451773+lat9nq@users.noreply.github.com>
Date: Tue, 15 Nov 2022 17:57:01 -0500
Subject: [PATCH] configure_profile_manager: Use a custom dialog for deletion

A hopefully more informative dialog that most importantly notifies the
user that their saves will be deleted with the user profile.

cpm: Only keep track of UI elements that we need

cpm: Remove unused forward declarations

cpm: Add missing include
---
 .../configure_profile_manager.cpp             | 67 ++++++++++++++++---
 .../configuration/configure_profile_manager.h | 25 ++++++-
 2 files changed, 81 insertions(+), 11 deletions(-)

diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 5c0217ba83..9493cb82e5 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -2,6 +2,9 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include <algorithm>
+#include <functional>
+#include <QDialog>
+#include <QDialogButtonBox>
 #include <QFileDialog>
 #include <QGraphicsItem>
 #include <QHeaderView>
@@ -108,9 +111,12 @@ ConfigureProfileManager::ConfigureProfileManager(const Core::System& system_, QW
 
     connect(ui->pm_add, &QPushButton::clicked, this, &ConfigureProfileManager::AddUser);
     connect(ui->pm_rename, &QPushButton::clicked, this, &ConfigureProfileManager::RenameUser);
-    connect(ui->pm_remove, &QPushButton::clicked, this, &ConfigureProfileManager::DeleteUser);
+    connect(ui->pm_remove, &QPushButton::clicked, this,
+            &ConfigureProfileManager::ConfirmDeleteUser);
     connect(ui->pm_set_image, &QPushButton::clicked, this, &ConfigureProfileManager::SetUserImage);
 
+    confirm_dialog = std::make_unique<ConfigureProfileManagerDeleteDialog>(this);
+
     scene = new QGraphicsScene;
     ui->current_user_icon->setScene(scene);
 
@@ -230,26 +236,23 @@ void ConfigureProfileManager::RenameUser() {
     UpdateCurrentUser();
 }
 
-void ConfigureProfileManager::DeleteUser() {
+void ConfigureProfileManager::ConfirmDeleteUser() {
     const auto index = tree_view->currentIndex().row();
     const auto uuid = profile_manager->GetUser(index);
     ASSERT(uuid);
     const auto username = GetAccountUsername(*profile_manager, *uuid);
 
-    const auto confirm = QMessageBox::question(
-        this, tr("Confirm Delete"),
-        tr("You are about to delete user with name \"%1\". Are you sure?").arg(username));
-
-    if (confirm == QMessageBox::No) {
-        return;
-    }
+    confirm_dialog->SetInfo(username, *uuid, [this, uuid]() { DeleteUser(*uuid); });
+    confirm_dialog->show();
+}
 
+void ConfigureProfileManager::DeleteUser(const Common::UUID uuid) {
     if (Settings::values.current_user.GetValue() == tree_view->currentIndex().row()) {
         Settings::values.current_user = 0;
     }
     UpdateCurrentUser();
 
-    if (!profile_manager->RemoveUser(*uuid)) {
+    if (!profile_manager->RemoveUser(uuid)) {
         return;
     }
 
@@ -319,3 +322,47 @@ void ConfigureProfileManager::SetUserImage() {
                         new QStandardItem{GetIcon(*uuid), FormatUserEntryText(username, *uuid)});
     UpdateCurrentUser();
 }
+
+ConfigureProfileManagerDeleteDialog::ConfigureProfileManagerDeleteDialog(QWidget* parent)
+    : QDialog(parent) {
+    auto dialog_vbox_layout = new QVBoxLayout(this);
+    dialog_button_box =
+        new QDialogButtonBox(QDialogButtonBox::Yes | QDialogButtonBox::No, Qt::Horizontal, parent);
+    auto label_message =
+        new QLabel(tr("Delete this user? All of the user's save data will be deleted."), this);
+    label_info = new QLabel(this);
+    auto dialog_hbox_layout_widget = new QWidget(this);
+    auto dialog_hbox_layout = new QHBoxLayout(dialog_hbox_layout_widget);
+    icon_scene = new QGraphicsScene(0, 0, 64, 64, this);
+    auto icon_view = new QGraphicsView(icon_scene, this);
+
+    dialog_hbox_layout_widget->setLayout(dialog_hbox_layout);
+    icon_view->setMaximumSize(64, 64);
+    icon_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    icon_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    this->setLayout(dialog_vbox_layout);
+    this->setWindowTitle(tr("Confirm Delete"));
+    this->setSizeGripEnabled(false);
+    dialog_vbox_layout->addWidget(label_message);
+    dialog_vbox_layout->addWidget(dialog_hbox_layout_widget);
+    dialog_vbox_layout->addWidget(dialog_button_box);
+    dialog_hbox_layout->addWidget(icon_view);
+    dialog_hbox_layout->addWidget(label_info);
+
+    connect(dialog_button_box, &QDialogButtonBox::rejected, this, [this]() { close(); });
+}
+
+ConfigureProfileManagerDeleteDialog::~ConfigureProfileManagerDeleteDialog() = default;
+
+void ConfigureProfileManagerDeleteDialog::SetInfo(const QString username, const Common::UUID uuid,
+                                                  std::function<void()> accept_callback) {
+    label_info->setText(
+        tr("Name: %1\nUUID: %2").arg(username, QString::fromStdString(uuid.FormattedString())));
+    icon_scene->clear();
+    icon_scene->addPixmap(GetIcon(uuid));
+
+    connect(dialog_button_box, &QDialogButtonBox::accepted, this, [this, accept_callback]() {
+        close();
+        accept_callback();
+    });
+}
diff --git a/src/yuzu/configuration/configure_profile_manager.h b/src/yuzu/configuration/configure_profile_manager.h
index fe90337796..6e5cb748d4 100644
--- a/src/yuzu/configuration/configure_profile_manager.h
+++ b/src/yuzu/configuration/configure_profile_manager.h
@@ -3,16 +3,22 @@
 
 #pragma once
 
+#include <functional>
 #include <memory>
 
+#include <QDialog>
 #include <QList>
 #include <QWidget>
 
+#include "common/uuid.h"
+
 namespace Core {
 class System;
 }
 
 class QGraphicsScene;
+class QDialogButtonBox;
+class QLabel;
 class QStandardItem;
 class QStandardItemModel;
 class QTreeView;
@@ -26,6 +32,20 @@ namespace Ui {
 class ConfigureProfileManager;
 }
 
+class ConfigureProfileManagerDeleteDialog : public QDialog {
+public:
+    explicit ConfigureProfileManagerDeleteDialog(QWidget* parent);
+    ~ConfigureProfileManagerDeleteDialog();
+
+    void SetInfo(const QString username, const Common::UUID uuid,
+                 std::function<void()> accept_callback);
+
+private:
+    QDialogButtonBox* dialog_button_box;
+    QGraphicsScene* icon_scene;
+    QLabel* label_info;
+};
+
 class ConfigureProfileManager : public QWidget {
     Q_OBJECT
 
@@ -47,7 +67,8 @@ private:
     void SelectUser(const QModelIndex& index);
     void AddUser();
     void RenameUser();
-    void DeleteUser();
+    void ConfirmDeleteUser();
+    void DeleteUser(const Common::UUID uuid);
     void SetUserImage();
 
     QVBoxLayout* layout;
@@ -55,6 +76,8 @@ private:
     QStandardItemModel* item_model;
     QGraphicsScene* scene;
 
+    std::unique_ptr<ConfigureProfileManagerDeleteDialog> confirm_dialog;
+
     std::vector<QList<QStandardItem*>> list_items;
 
     std::unique_ptr<Ui::ConfigureProfileManager> ui;