1 // Copyright 2017 Dolphin Emulator Project
2 // Licensed under GPLv2+
3 // Refer to the license.txt file included.
4
5 #include "DolphinQt/NetPlay/MD5Dialog.h"
6
7 #include <algorithm>
8 #include <functional>
9
10 #include <QDialogButtonBox>
11 #include <QGroupBox>
12 #include <QLabel>
13 #include <QProgressBar>
14 #include <QPushButton>
15 #include <QVBoxLayout>
16
17 #include "Core/NetPlayClient.h"
18 #include "Core/NetPlayServer.h"
19
20 #include "DolphinQt/Settings.h"
21
GetPlayerNameFromPID(int pid)22 static QString GetPlayerNameFromPID(int pid)
23 {
24 QString player_name = QObject::tr("Invalid Player ID");
25 auto client = Settings::Instance().GetNetPlayClient();
26 if (!client)
27 return player_name;
28
29 for (const auto* player : client->GetPlayers())
30 {
31 if (player->pid == pid)
32 {
33 player_name = QString::fromStdString(player->name);
34 break;
35 }
36 }
37 return player_name;
38 }
39
MD5Dialog(QWidget * parent)40 MD5Dialog::MD5Dialog(QWidget* parent) : QDialog(parent)
41 {
42 CreateWidgets();
43 ConnectWidgets();
44 setWindowTitle(tr("MD5 Checksum"));
45 setWindowFlags(Qt::Sheet | Qt::Dialog);
46 setWindowModality(Qt::WindowModal);
47 }
48
CreateWidgets()49 void MD5Dialog::CreateWidgets()
50 {
51 m_main_layout = new QVBoxLayout;
52 m_progress_box = new QGroupBox;
53 m_progress_layout = new QVBoxLayout;
54 m_button_box = new QDialogButtonBox(QDialogButtonBox::NoButton);
55 m_check_label = new QLabel;
56
57 m_progress_box->setLayout(m_progress_layout);
58
59 m_main_layout->addWidget(m_progress_box);
60 m_main_layout->addWidget(m_check_label);
61 m_main_layout->addWidget(m_button_box);
62 setLayout(m_main_layout);
63 }
64
ConnectWidgets()65 void MD5Dialog::ConnectWidgets()
66 {
67 connect(m_button_box, &QDialogButtonBox::rejected, this, &MD5Dialog::reject);
68 }
69
show(const QString & title)70 void MD5Dialog::show(const QString& title)
71 {
72 m_progress_box->setTitle(title);
73
74 for (auto& pair : m_progress_bars)
75 {
76 m_progress_layout->removeWidget(pair.second);
77 pair.second->deleteLater();
78 }
79
80 for (auto& pair : m_status_labels)
81 {
82 m_progress_layout->removeWidget(pair.second);
83 pair.second->deleteLater();
84 }
85
86 m_progress_bars.clear();
87 m_status_labels.clear();
88 m_results.clear();
89 m_check_label->setText(QString::fromStdString(""));
90
91 auto client = Settings::Instance().GetNetPlayClient();
92 if (!client)
93 return;
94
95 if (Settings::Instance().GetNetPlayServer())
96 {
97 m_button_box->setStandardButtons(QDialogButtonBox::Cancel);
98 QPushButton* cancel_button = m_button_box->button(QDialogButtonBox::Cancel);
99 cancel_button->setAutoDefault(false);
100 cancel_button->setDefault(false);
101 }
102 else
103 {
104 m_button_box->setStandardButtons(QDialogButtonBox::Close);
105 QPushButton* close_button = m_button_box->button(QDialogButtonBox::Close);
106 close_button->setAutoDefault(false);
107 close_button->setDefault(false);
108 }
109
110 for (const auto* player : client->GetPlayers())
111 {
112 m_progress_bars[player->pid] = new QProgressBar;
113 m_status_labels[player->pid] = new QLabel;
114
115 m_progress_layout->addWidget(m_progress_bars[player->pid]);
116 m_progress_layout->addWidget(m_status_labels[player->pid]);
117 }
118
119 QDialog::show();
120 }
121
SetProgress(int pid,int progress)122 void MD5Dialog::SetProgress(int pid, int progress)
123 {
124 QString player_name = GetPlayerNameFromPID(pid);
125
126 if (!m_status_labels.count(pid))
127 return;
128
129 m_status_labels[pid]->setText(
130 tr("%1[%2]: %3 %").arg(player_name, QString::number(pid), QString::number(progress)));
131 m_progress_bars[pid]->setValue(progress);
132 }
133
SetResult(int pid,const std::string & result)134 void MD5Dialog::SetResult(int pid, const std::string& result)
135 {
136 QString player_name = GetPlayerNameFromPID(pid);
137
138 if (!m_status_labels.count(pid))
139 return;
140
141 m_status_labels[pid]->setText(
142 tr("%1[%2]: %3").arg(player_name, QString::number(pid), QString::fromStdString(result)));
143
144 m_results.push_back(result);
145
146 auto client = Settings::Instance().GetNetPlayClient();
147 if (client && m_results.size() >= client->GetPlayers().size())
148 {
149 if (std::adjacent_find(m_results.begin(), m_results.end(), std::not_equal_to<>()) ==
150 m_results.end())
151 {
152 m_check_label->setText(tr("The hashes match!"));
153 }
154 else
155 {
156 m_check_label->setText(tr("The hashes do not match!"));
157 }
158
159 m_button_box->setStandardButtons(QDialogButtonBox::Close);
160 QPushButton* close_button = m_button_box->button(QDialogButtonBox::Close);
161 close_button->setAutoDefault(false);
162 close_button->setDefault(false);
163 }
164 }
165
reject()166 void MD5Dialog::reject()
167 {
168 auto server = Settings::Instance().GetNetPlayServer();
169
170 if (server)
171 server->AbortMD5();
172
173 QDialog::reject();
174 }
175