mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-06-10 16:24:45 -07:00
[Move refactor] Move dialogs to interface/widgets/ (#6234)
* Move dialogs/ underneath interface/widgets since QDialog inherits from QWidget. --------- Co-authored-by: Lukas Brübach <Bruebach.Lukas@bdosecurity.de>
This commit is contained in:
parent
b8983f27ab
commit
474c1d0d89
66 changed files with 60 additions and 60 deletions
377
cockatrice/src/interface/widgets/dialogs/dlg_connect.cpp
Normal file
377
cockatrice/src/interface/widgets/dialogs/dlg_connect.cpp
Normal file
|
|
@ -0,0 +1,377 @@
|
|||
#include "dlg_connect.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QEvent>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QKeyEvent>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgConnect::DlgConnect(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
previousHostButton = new QRadioButton(tr("Known Hosts"), this);
|
||||
previousHosts = new QComboBox(this);
|
||||
|
||||
btnDeleteServer = new QPushButton(this);
|
||||
btnDeleteServer->setIcon(QPixmap("theme:icons/remove_row"));
|
||||
btnDeleteServer->setToolTip(tr("Delete the currently selected saved server"));
|
||||
btnDeleteServer->setFixedWidth(30);
|
||||
|
||||
connect(btnDeleteServer, &QPushButton::clicked, this, &DlgConnect::actRemoveSavedServer);
|
||||
|
||||
hps = new HandlePublicServers(this);
|
||||
btnRefreshServers = new QPushButton(this);
|
||||
btnRefreshServers->setIcon(QPixmap("theme:icons/sync"));
|
||||
btnRefreshServers->setToolTip(tr("Refresh the server list with known public servers"));
|
||||
btnRefreshServers->setFixedWidth(30);
|
||||
|
||||
connect(hps, &HandlePublicServers::sigPublicServersDownloadedSuccessfully, this, [this] { rebuildComboBoxList(); });
|
||||
connect(hps, &HandlePublicServers::sigPublicServersDownloadedUnsuccessfully, this,
|
||||
&DlgConnect::rebuildComboBoxList);
|
||||
connect(btnRefreshServers, &QPushButton::released, this, &DlgConnect::downloadThePublicServers);
|
||||
|
||||
connect(this, &DlgConnect::sigPublicServersDownloaded, this, [this] { rebuildComboBoxList(); });
|
||||
preRebuildComboBoxList();
|
||||
|
||||
newHostButton = new QRadioButton(tr("New Host"), this);
|
||||
|
||||
saveLabel = new QLabel(tr("Name:"));
|
||||
saveEdit = new QLineEdit;
|
||||
saveEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
saveLabel->setBuddy(saveEdit);
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit;
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit;
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit;
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
passwordLabel = new QLabel(tr("P&assword:"));
|
||||
passwordEdit = new QLineEdit;
|
||||
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
savePasswordCheckBox = new QCheckBox(tr("&Save password"));
|
||||
|
||||
autoConnectCheckBox = new QCheckBox(tr("A&uto connect"));
|
||||
autoConnectCheckBox->setToolTip(tr("Automatically connect to the most recent login when Cockatrice opens"));
|
||||
|
||||
auto &servers = SettingsCache::instance().servers();
|
||||
if (servers.getSavePassword()) {
|
||||
autoConnectCheckBox->setChecked(servers.getAutoConnect() > 0);
|
||||
autoConnectCheckBox->setEnabled(true);
|
||||
} else {
|
||||
servers.setAutoConnect(0);
|
||||
autoConnectCheckBox->setChecked(false);
|
||||
autoConnectCheckBox->setEnabled(false);
|
||||
}
|
||||
|
||||
connect(savePasswordCheckBox, &QCheckBox::QT_STATE_CHANGED, this, &DlgConnect::passwordSaved);
|
||||
connect(autoConnectCheckBox, &QCheckBox::QT_STATE_CHANGED, &servers, &ServersSettings::setAutoConnect);
|
||||
|
||||
serverIssuesLabel =
|
||||
new QLabel(tr("If you have any trouble connecting or registering then contact the server staff for help!"));
|
||||
serverIssuesLabel->setWordWrap(true);
|
||||
serverContactLabel = new QLabel(tr("Webpage") + ":");
|
||||
serverContactLink = new QLabel;
|
||||
serverContactLink->setTextFormat(Qt::RichText);
|
||||
serverContactLink->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
serverContactLink->setOpenExternalLinks(true);
|
||||
|
||||
updateDisplayInfo(previousHosts->currentText());
|
||||
|
||||
btnForgotPassword = new QPushButton(this);
|
||||
btnForgotPassword->setIcon(QPixmap("theme:icons/forgot_password"));
|
||||
btnForgotPassword->setToolTip(tr("Reset Password"));
|
||||
btnForgotPassword->setFixedWidth(30);
|
||||
connect(btnForgotPassword, &QPushButton::released, this, &DlgConnect::actForgotPassword);
|
||||
|
||||
forgotPasswordLabel = new QLabel(tr("Forgot password?"));
|
||||
forgotPasswordLabel->setBuddy(btnForgotPassword);
|
||||
|
||||
btnConnect = new QPushButton(tr("&Connect"));
|
||||
connect(btnConnect, &QPushButton::released, this, &DlgConnect::actOk);
|
||||
|
||||
auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Cancel);
|
||||
buttonBox->addButton(btnConnect, QDialogButtonBox::AcceptRole);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgConnect::reject);
|
||||
|
||||
newHolderLayout = new QHBoxLayout;
|
||||
newHolderLayout->addWidget(previousHosts);
|
||||
newHolderLayout->addWidget(btnDeleteServer);
|
||||
newHolderLayout->addWidget(btnRefreshServers);
|
||||
|
||||
connectionLayout = new QGridLayout;
|
||||
connectionLayout->addWidget(previousHostButton, 0, 1);
|
||||
connectionLayout->addLayout(newHolderLayout, 1, 1, 1, 2);
|
||||
connectionLayout->addWidget(newHostButton, 2, 1);
|
||||
connectionLayout->addWidget(saveLabel, 3, 0);
|
||||
connectionLayout->addWidget(saveEdit, 3, 1);
|
||||
connectionLayout->addWidget(hostLabel, 4, 0);
|
||||
connectionLayout->addWidget(hostEdit, 4, 1);
|
||||
connectionLayout->addWidget(portLabel, 5, 0);
|
||||
connectionLayout->addWidget(portEdit, 5, 1);
|
||||
connectionLayout->addWidget(autoConnectCheckBox, 6, 1);
|
||||
|
||||
restrictionsGroupBox = new QGroupBox(tr("Server"));
|
||||
restrictionsGroupBox->setLayout(connectionLayout);
|
||||
|
||||
serverInfoLayout = new QGridLayout;
|
||||
serverInfoLayout->addWidget(serverIssuesLabel, 0, 0, 1, 4, Qt::AlignTop);
|
||||
serverInfoLayout->addWidget(serverContactLabel, 1, 0);
|
||||
serverInfoLayout->addWidget(serverContactLink, 1, 1, 1, 3);
|
||||
|
||||
forgotPasswordLayout = new QHBoxLayout;
|
||||
forgotPasswordLayout->addWidget(forgotPasswordLabel, 0, Qt::AlignLeft);
|
||||
forgotPasswordLayout->addWidget(btnForgotPassword, 0, Qt::AlignLeft);
|
||||
|
||||
loginLayout = new QGridLayout;
|
||||
loginLayout->addWidget(playernameLabel, 0, 0);
|
||||
loginLayout->addWidget(playernameEdit, 0, 1, 1, 2);
|
||||
loginLayout->addWidget(passwordLabel, 1, 0);
|
||||
loginLayout->addWidget(passwordEdit, 1, 1, 1, 2);
|
||||
loginLayout->addWidget(savePasswordCheckBox, 2, 1);
|
||||
loginLayout->addLayout(forgotPasswordLayout, 3, 1);
|
||||
|
||||
loginGroupBox = new QGroupBox(tr("Login"));
|
||||
loginGroupBox->setLayout(loginLayout);
|
||||
|
||||
serverInfoGroupBox = new QGroupBox(tr("Server Contact"));
|
||||
serverInfoGroupBox->setLayout(serverInfoLayout);
|
||||
|
||||
grid = new QGridLayout;
|
||||
grid->addWidget(restrictionsGroupBox, 0, 0);
|
||||
grid->addWidget(serverInfoGroupBox, 1, 0);
|
||||
grid->addWidget(loginGroupBox, 2, 0);
|
||||
|
||||
mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Connect to Server"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
|
||||
connect(previousHostButton, &QRadioButton::toggled, this, &DlgConnect::previousHostSelected);
|
||||
connect(newHostButton, &QRadioButton::toggled, this, &DlgConnect::newHostSelected);
|
||||
|
||||
previousHostButton->setChecked(true);
|
||||
|
||||
connect(previousHosts, &QComboBox::currentTextChanged, this, &DlgConnect::updateDisplayInfo);
|
||||
|
||||
playernameEdit->setFocus();
|
||||
}
|
||||
|
||||
DlgConnect::~DlgConnect() = default;
|
||||
|
||||
void DlgConnect::downloadThePublicServers()
|
||||
{
|
||||
btnRefreshServers->setDisabled(true);
|
||||
previousHosts->clear();
|
||||
previousHosts->addItem(placeHolderText);
|
||||
hps->downloadPublicServers();
|
||||
}
|
||||
|
||||
void DlgConnect::preRebuildComboBoxList()
|
||||
{
|
||||
UserConnection_Information uci;
|
||||
savedHostList = uci.getServerInfo();
|
||||
|
||||
if (savedHostList.size() == 1) {
|
||||
downloadThePublicServers();
|
||||
} else {
|
||||
rebuildComboBoxList();
|
||||
}
|
||||
}
|
||||
|
||||
void DlgConnect::rebuildComboBoxList(int failure)
|
||||
{
|
||||
Q_UNUSED(failure);
|
||||
|
||||
previousHosts->clear();
|
||||
|
||||
UserConnection_Information uci;
|
||||
savedHostList = uci.getServerInfo();
|
||||
|
||||
auto &servers = SettingsCache::instance().servers();
|
||||
bool autoConnectEnabled = servers.getAutoConnect() > 0;
|
||||
QString previousHostName = servers.getPrevioushostName();
|
||||
QString autoConnectSaveName = servers.getSaveName();
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (const auto &pair : savedHostList) {
|
||||
const auto &tmp = pair.second;
|
||||
QString saveName = tmp.getSaveName();
|
||||
if (saveName.size()) {
|
||||
previousHosts->addItem(saveName);
|
||||
|
||||
if (autoConnectEnabled) {
|
||||
if (saveName.compare(autoConnectSaveName) == 0) {
|
||||
previousHosts->setCurrentIndex(index);
|
||||
}
|
||||
} else if (saveName.compare(previousHostName) == 0) {
|
||||
previousHosts->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
// Re-enable the refresh server button
|
||||
btnRefreshServers->setDisabled(false);
|
||||
}
|
||||
|
||||
void DlgConnect::previousHostSelected(bool state)
|
||||
{
|
||||
if (state) {
|
||||
saveEdit->setDisabled(true);
|
||||
hostEdit->setDisabled(true);
|
||||
portEdit->setDisabled(true);
|
||||
previousHosts->setDisabled(false);
|
||||
btnRefreshServers->setDisabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DlgConnect::updateDisplayInfo(const QString &saveName)
|
||||
{
|
||||
if (saveEdit == nullptr || saveName == placeHolderText) {
|
||||
return;
|
||||
}
|
||||
|
||||
UserConnection_Information uci;
|
||||
QStringList _data = uci.getServerInfo(saveName);
|
||||
|
||||
if (_data.isEmpty()) {
|
||||
_data << ""
|
||||
<< ""
|
||||
<< ""
|
||||
<< ""
|
||||
<< ""
|
||||
<< ""
|
||||
<< "";
|
||||
}
|
||||
|
||||
bool savePasswordStatus = (_data.at(5) == "1");
|
||||
|
||||
saveEdit->setText(_data.at(0));
|
||||
hostEdit->setText(_data.at(1));
|
||||
portEdit->setText(_data.at(2));
|
||||
playernameEdit->setText(_data.at(3));
|
||||
savePasswordCheckBox->setChecked(savePasswordStatus);
|
||||
|
||||
if (savePasswordStatus) {
|
||||
passwordEdit->setText(_data.at(4));
|
||||
}
|
||||
|
||||
if (!_data.at(6).isEmpty()) {
|
||||
QString formattedLink = "<a href=\"" + _data.at(6) + "\">" + _data.at(6) + "</a>";
|
||||
serverContactLabel->setText(tr("Webpage") + ":");
|
||||
serverContactLink->setText(formattedLink);
|
||||
} else {
|
||||
serverContactLabel->setText("");
|
||||
serverContactLink->setText("");
|
||||
}
|
||||
}
|
||||
|
||||
void DlgConnect::newHostSelected(bool state)
|
||||
{
|
||||
if (state) {
|
||||
previousHosts->setDisabled(true);
|
||||
btnRefreshServers->setDisabled(true);
|
||||
hostEdit->clear();
|
||||
hostEdit->setPlaceholderText(tr("Server URL"));
|
||||
hostEdit->setDisabled(false);
|
||||
portEdit->clear();
|
||||
portEdit->setPlaceholderText(tr("Communication Port"));
|
||||
portEdit->setDisabled(false);
|
||||
playernameEdit->clear();
|
||||
passwordEdit->clear();
|
||||
saveEdit->clear();
|
||||
saveEdit->setPlaceholderText(tr("Unique Server Name"));
|
||||
saveEdit->setDisabled(false);
|
||||
serverContactLabel->setText("");
|
||||
serverContactLink->setText("");
|
||||
} else {
|
||||
preRebuildComboBoxList();
|
||||
}
|
||||
}
|
||||
|
||||
void DlgConnect::passwordSaved(QT_STATE_CHANGED_T state)
|
||||
{
|
||||
Q_UNUSED(state);
|
||||
if (savePasswordCheckBox->isChecked()) {
|
||||
autoConnectCheckBox->setEnabled(true);
|
||||
} else {
|
||||
autoConnectCheckBox->setChecked(false);
|
||||
autoConnectCheckBox->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DlgConnect::actOk()
|
||||
{
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
|
||||
if (newHostButton->isChecked()) {
|
||||
if (saveEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Connection Warning"), tr("You need to name your new connection profile."));
|
||||
return;
|
||||
}
|
||||
|
||||
servers.addNewServer(saveEdit->text().trimmed(), hostEdit->text().trimmed(), portEdit->text().trimmed(),
|
||||
playernameEdit->text().trimmed(), passwordEdit->text(), savePasswordCheckBox->isChecked());
|
||||
} else {
|
||||
servers.updateExistingServer(saveEdit->text().trimmed(), hostEdit->text().trimmed(), portEdit->text().trimmed(),
|
||||
playernameEdit->text().trimmed(), passwordEdit->text(),
|
||||
savePasswordCheckBox->isChecked());
|
||||
}
|
||||
|
||||
servers.setPrevioushostName(saveEdit->text());
|
||||
|
||||
if (playernameEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Connect Warning"), tr("The player name can't be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
|
||||
QString DlgConnect::getHost() const
|
||||
{
|
||||
return hostEdit->text().trimmed();
|
||||
}
|
||||
|
||||
void DlgConnect::actForgotPassword()
|
||||
{
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
servers.setFPHostName(hostEdit->text());
|
||||
servers.setFPPort(portEdit->text());
|
||||
servers.setFPPlayerName(playernameEdit->text().trimmed());
|
||||
|
||||
emit sigStartForgotPasswordRequest();
|
||||
}
|
||||
|
||||
void DlgConnect::actRemoveSavedServer()
|
||||
{
|
||||
SettingsCache::instance().servers().removeServer(hostEdit->text());
|
||||
previousHosts->removeItem(previousHosts->currentIndex());
|
||||
}
|
||||
82
cockatrice/src/interface/widgets/dialogs/dlg_connect.h
Normal file
82
cockatrice/src/interface/widgets/dialogs/dlg_connect.h
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
/**
|
||||
* @file dlg_connect.h
|
||||
* @ingroup ConnectionDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_CONNECT_H
|
||||
#define DLG_CONNECT_H
|
||||
|
||||
#include "../interface/widgets/server/handle_public_servers.h"
|
||||
#include "../interface/widgets/server/user/user_info_connection.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <libcockatrice/utility/macros.h>
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QGridLayout;
|
||||
class QGroupBox;
|
||||
class QHBoxLayout;
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QRadioButton;
|
||||
class QVBoxLayout;
|
||||
|
||||
class DlgConnect : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void sigStartForgotPasswordRequest();
|
||||
void sigPublicServersDownloaded();
|
||||
|
||||
public:
|
||||
explicit DlgConnect(QWidget *parent = nullptr);
|
||||
~DlgConnect() override;
|
||||
QString getHost() const;
|
||||
int getPort() const
|
||||
{
|
||||
return portEdit->text().toInt();
|
||||
}
|
||||
QString getPlayerName() const
|
||||
{
|
||||
return playernameEdit->text();
|
||||
}
|
||||
QString getPassword() const
|
||||
{
|
||||
return passwordEdit->text();
|
||||
}
|
||||
|
||||
public slots:
|
||||
void downloadThePublicServers();
|
||||
|
||||
private slots:
|
||||
void actOk();
|
||||
|
||||
void passwordSaved(QT_STATE_CHANGED_T state);
|
||||
void previousHostSelected(bool state);
|
||||
void newHostSelected(bool state);
|
||||
void actForgotPassword();
|
||||
void actRemoveSavedServer();
|
||||
void updateDisplayInfo(const QString &saveName);
|
||||
void preRebuildComboBoxList();
|
||||
void rebuildComboBoxList(int failure = -1);
|
||||
|
||||
private:
|
||||
QGridLayout *connectionLayout, *loginLayout, *serverInfoLayout, *grid;
|
||||
QHBoxLayout *newHolderLayout, *forgotPasswordLayout;
|
||||
QGroupBox *loginGroupBox, *serverInfoGroupBox, *restrictionsGroupBox;
|
||||
QVBoxLayout *mainLayout;
|
||||
QLabel *hostLabel, *portLabel, *playernameLabel, *passwordLabel, *saveLabel, *serverIssuesLabel,
|
||||
*serverContactLabel, *serverContactLink, *forgotPasswordLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit, *passwordEdit, *saveEdit;
|
||||
QCheckBox *savePasswordCheckBox, *autoConnectCheckBox;
|
||||
QComboBox *previousHosts;
|
||||
QRadioButton *newHostButton, *previousHostButton;
|
||||
QPushButton *btnConnect, *btnForgotPassword, *btnRefreshServers, *btnDeleteServer;
|
||||
QMap<QString, std::pair<QString, UserConnection_Information>> savedHostList;
|
||||
HandlePublicServers *hps;
|
||||
const QString placeHolderText = tr("Downloading...");
|
||||
};
|
||||
#endif
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
#include "dlg_convert_deck_to_cod_format.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
DialogConvertDeckToCodFormat::DialogConvertDeckToCodFormat(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
label = new QLabel();
|
||||
layout->addWidget(label);
|
||||
|
||||
dontAskAgainCheckbox = new QCheckBox(this);
|
||||
layout->addWidget(dontAskAgainCheckbox);
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this);
|
||||
layout->addWidget(buttonBox);
|
||||
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, [this]() { accept(); });
|
||||
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, [this]() { reject(); });
|
||||
|
||||
setLayout(layout);
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void DialogConvertDeckToCodFormat::retranslateUi()
|
||||
{
|
||||
setWindowTitle(tr("Deck Format Conversion"));
|
||||
label->setText(
|
||||
tr("You tried to add a tag to a .txt format deck.\n Tags can only be added to .cod format decks.\n Do "
|
||||
"you want to convert the deck to the .cod format?"));
|
||||
dontAskAgainCheckbox->setText(tr("Remember and automatically apply choice in the future"));
|
||||
}
|
||||
|
||||
bool DialogConvertDeckToCodFormat::dontAskAgain() const
|
||||
{
|
||||
return dontAskAgainCheckbox->isChecked();
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/**
|
||||
* @file dlg_convert_deck_to_cod_format.h
|
||||
* @ingroup LocalDeckStorageDialogs
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DIALOG_CONVERT_DECK_TO_COD_FORMAT_H
|
||||
#define DIALOG_CONVERT_DECK_TO_COD_FORMAT_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class DialogConvertDeckToCodFormat : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DialogConvertDeckToCodFormat(QWidget *parent);
|
||||
void retranslateUi();
|
||||
|
||||
bool dontAskAgain() const;
|
||||
|
||||
private:
|
||||
QVBoxLayout *layout;
|
||||
QLabel *label;
|
||||
QCheckBox *dontAskAgainCheckbox;
|
||||
QDialogButtonBox *buttonBox;
|
||||
|
||||
Q_DISABLE_COPY(DialogConvertDeckToCodFormat)
|
||||
};
|
||||
|
||||
#endif // DIALOG_CONVERT_DECK_TO_COD_FORMAT_H
|
||||
327
cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp
Normal file
327
cockatrice/src/interface/widgets/dialogs/dlg_create_game.cpp
Normal file
|
|
@ -0,0 +1,327 @@
|
|||
#include "dlg_create_game.h"
|
||||
|
||||
#include "../interface/widgets/tabs/tab_room.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QRadioButton>
|
||||
#include <QSet>
|
||||
#include <QSpinBox>
|
||||
#include <QWizard>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_game.pb.h>
|
||||
#include <libcockatrice/protocol/pending_command.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
void DlgCreateGame::sharedCtor()
|
||||
{
|
||||
rememberGameSettings = new QCheckBox(tr("Re&member settings"));
|
||||
descriptionLabel = new QLabel(tr("&Description:"));
|
||||
descriptionEdit = new QLineEdit;
|
||||
descriptionEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
descriptionLabel->setBuddy(descriptionEdit);
|
||||
|
||||
maxPlayersLabel = new QLabel(tr("P&layers:"));
|
||||
maxPlayersEdit = new QSpinBox();
|
||||
maxPlayersEdit->setMinimum(1);
|
||||
maxPlayersEdit->setMaximum(100);
|
||||
maxPlayersEdit->setValue(2);
|
||||
maxPlayersLabel->setBuddy(maxPlayersEdit);
|
||||
|
||||
QGridLayout *generalGrid = new QGridLayout;
|
||||
generalGrid->addWidget(descriptionLabel, 0, 0);
|
||||
generalGrid->addWidget(descriptionEdit, 0, 1);
|
||||
generalGrid->addWidget(maxPlayersLabel, 1, 0);
|
||||
generalGrid->addWidget(maxPlayersEdit, 1, 1);
|
||||
generalGroupBox = new QGroupBox(tr("General"));
|
||||
generalGroupBox->setLayout(generalGrid);
|
||||
|
||||
QVBoxLayout *gameTypeLayout = new QVBoxLayout;
|
||||
QMapIterator<int, QString> gameTypeIterator(gameTypes);
|
||||
while (gameTypeIterator.hasNext()) {
|
||||
gameTypeIterator.next();
|
||||
QRadioButton *gameTypeRadioButton = new QRadioButton(gameTypeIterator.value(), this);
|
||||
gameTypeLayout->addWidget(gameTypeRadioButton);
|
||||
gameTypeCheckBoxes.insert(gameTypeIterator.key(), gameTypeRadioButton);
|
||||
bool isChecked = SettingsCache::instance().getGameTypes().contains(gameTypeIterator.value() + ", ");
|
||||
gameTypeCheckBoxes[gameTypeIterator.key()]->setChecked(isChecked);
|
||||
}
|
||||
QGroupBox *gameTypeGroupBox = new QGroupBox(tr("Game type"));
|
||||
gameTypeGroupBox->setLayout(gameTypeLayout);
|
||||
|
||||
passwordLabel = new QLabel(tr("&Password:"));
|
||||
passwordEdit = new QLineEdit;
|
||||
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
|
||||
onlyBuddiesCheckBox = new QCheckBox(tr("Only &buddies can join"));
|
||||
onlyRegisteredCheckBox = new QCheckBox(tr("Only ®istered users can join"));
|
||||
if (room && room->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) {
|
||||
onlyRegisteredCheckBox->setChecked(true);
|
||||
} else {
|
||||
onlyBuddiesCheckBox->setEnabled(false);
|
||||
onlyRegisteredCheckBox->setEnabled(false);
|
||||
}
|
||||
|
||||
QGridLayout *joinRestrictionsLayout = new QGridLayout;
|
||||
joinRestrictionsLayout->addWidget(passwordLabel, 0, 0);
|
||||
joinRestrictionsLayout->addWidget(passwordEdit, 0, 1);
|
||||
joinRestrictionsLayout->addWidget(onlyBuddiesCheckBox, 1, 0, 1, 2);
|
||||
joinRestrictionsLayout->addWidget(onlyRegisteredCheckBox, 2, 0, 1, 2);
|
||||
|
||||
QGroupBox *joinRestrictionsGroupBox = new QGroupBox(tr("Joining restrictions"));
|
||||
joinRestrictionsGroupBox->setLayout(joinRestrictionsLayout);
|
||||
|
||||
spectatorsAllowedCheckBox = new QCheckBox(tr("&Spectators can watch"));
|
||||
spectatorsAllowedCheckBox->setChecked(true);
|
||||
connect(spectatorsAllowedCheckBox, &QCheckBox::QT_STATE_CHANGED, this, &DlgCreateGame::spectatorsAllowedChanged);
|
||||
spectatorsNeedPasswordCheckBox = new QCheckBox(tr("Spectators &need a password to watch"));
|
||||
spectatorsCanTalkCheckBox = new QCheckBox(tr("Spectators can &chat"));
|
||||
spectatorsSeeEverythingCheckBox = new QCheckBox(tr("Spectators can see &hands"));
|
||||
createGameAsSpectatorCheckBox = new QCheckBox(tr("Create game as spectator"));
|
||||
QVBoxLayout *spectatorsLayout = new QVBoxLayout;
|
||||
spectatorsLayout->addWidget(spectatorsAllowedCheckBox);
|
||||
spectatorsLayout->addWidget(spectatorsNeedPasswordCheckBox);
|
||||
spectatorsLayout->addWidget(spectatorsCanTalkCheckBox);
|
||||
spectatorsLayout->addWidget(spectatorsSeeEverythingCheckBox);
|
||||
spectatorsLayout->addWidget(createGameAsSpectatorCheckBox);
|
||||
spectatorsGroupBox = new QGroupBox(tr("Spectators"));
|
||||
spectatorsGroupBox->setLayout(spectatorsLayout);
|
||||
|
||||
startingLifeTotalLabel = new QLabel(tr("Starting life total:"));
|
||||
startingLifeTotalEdit = new QSpinBox();
|
||||
startingLifeTotalEdit->setMinimum(1);
|
||||
startingLifeTotalEdit->setMaximum(99999); ///< Arbitrary but we can raise this when people start complaining.
|
||||
startingLifeTotalEdit->setValue(20);
|
||||
startingLifeTotalLabel->setBuddy(startingLifeTotalEdit);
|
||||
|
||||
shareDecklistsOnLoadLabel = new QLabel(tr("Open decklists in lobby"));
|
||||
shareDecklistsOnLoadCheckBox = new QCheckBox();
|
||||
shareDecklistsOnLoadLabel->setBuddy(shareDecklistsOnLoadCheckBox);
|
||||
|
||||
QGridLayout *gameSetupOptionsLayout = new QGridLayout;
|
||||
gameSetupOptionsLayout->addWidget(startingLifeTotalLabel, 0, 0);
|
||||
gameSetupOptionsLayout->addWidget(startingLifeTotalEdit, 0, 1);
|
||||
gameSetupOptionsLayout->addWidget(shareDecklistsOnLoadLabel, 1, 0);
|
||||
gameSetupOptionsLayout->addWidget(shareDecklistsOnLoadCheckBox, 1, 1);
|
||||
gameSetupOptionsGroupBox = new QGroupBox(tr("Game setup options"));
|
||||
gameSetupOptionsGroupBox->setLayout(gameSetupOptionsLayout);
|
||||
|
||||
auto *grid = new QGridLayout;
|
||||
|
||||
// Top row
|
||||
grid->addWidget(generalGroupBox, 0, 0);
|
||||
grid->addWidget(joinRestrictionsGroupBox, 0, 1);
|
||||
|
||||
// Middle row: left column
|
||||
grid->addWidget(gameTypeGroupBox, 1, 0);
|
||||
|
||||
// Middle row: right column (game setup + spectators)
|
||||
auto *rightLayout = new QVBoxLayout;
|
||||
rightLayout->addWidget(spectatorsGroupBox, Qt::AlignTop); // top
|
||||
rightLayout->addWidget(gameSetupOptionsGroupBox); // bottom
|
||||
|
||||
grid->addLayout(rightLayout, 1, 1);
|
||||
|
||||
// Bottom row
|
||||
grid->addWidget(rememberGameSettings, 3, 0, 1, 2); // span both columns if needed
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgCreateGame::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setFixedHeight(sizeHint().height());
|
||||
}
|
||||
|
||||
DlgCreateGame::DlgCreateGame(TabRoom *_room, const QMap<int, QString> &_gameTypes, QWidget *parent)
|
||||
: QDialog(parent), room(_room), gameTypes(_gameTypes)
|
||||
{
|
||||
sharedCtor();
|
||||
|
||||
rememberGameSettings->setChecked(SettingsCache::instance().getRememberGameSettings());
|
||||
descriptionEdit->setText(SettingsCache::instance().getGameDescription());
|
||||
maxPlayersEdit->setValue(SettingsCache::instance().getMaxPlayers());
|
||||
if (room && room->getUserInfo()->user_level() & ServerInfo_User::IsRegistered) {
|
||||
onlyBuddiesCheckBox->setChecked(SettingsCache::instance().getOnlyBuddies());
|
||||
onlyRegisteredCheckBox->setChecked(SettingsCache::instance().getOnlyRegistered());
|
||||
} else {
|
||||
onlyBuddiesCheckBox->setEnabled(false);
|
||||
onlyRegisteredCheckBox->setEnabled(false);
|
||||
}
|
||||
spectatorsAllowedCheckBox->setChecked(SettingsCache::instance().getSpectatorsAllowed());
|
||||
spectatorsNeedPasswordCheckBox->setChecked(SettingsCache::instance().getSpectatorsNeedPassword());
|
||||
spectatorsCanTalkCheckBox->setChecked(SettingsCache::instance().getSpectatorsCanTalk());
|
||||
spectatorsSeeEverythingCheckBox->setChecked(SettingsCache::instance().getSpectatorsCanSeeEverything());
|
||||
createGameAsSpectatorCheckBox->setChecked(SettingsCache::instance().getCreateGameAsSpectator());
|
||||
startingLifeTotalEdit->setValue(SettingsCache::instance().getDefaultStartingLifeTotal());
|
||||
shareDecklistsOnLoadCheckBox->setChecked(SettingsCache::instance().getShareDecklistsOnLoad());
|
||||
|
||||
if (!rememberGameSettings->isChecked()) {
|
||||
actReset();
|
||||
}
|
||||
|
||||
descriptionEdit->setFocus();
|
||||
clearButton = new QPushButton(tr("&Clear"));
|
||||
buttonBox->addButton(QDialogButtonBox::Cancel);
|
||||
buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgCreateGame::actOK);
|
||||
connect(clearButton, &QPushButton::clicked, this, &DlgCreateGame::actReset);
|
||||
|
||||
setWindowTitle(tr("Create game"));
|
||||
}
|
||||
|
||||
DlgCreateGame::DlgCreateGame(const ServerInfo_Game &gameInfo, const QMap<int, QString> &_gameTypes, QWidget *parent)
|
||||
: QDialog(parent), room(0), gameTypes(_gameTypes)
|
||||
{
|
||||
sharedCtor();
|
||||
|
||||
rememberGameSettings->setEnabled(false);
|
||||
descriptionEdit->setEnabled(false);
|
||||
maxPlayersEdit->setEnabled(false);
|
||||
passwordEdit->setEnabled(false);
|
||||
onlyBuddiesCheckBox->setEnabled(false);
|
||||
onlyRegisteredCheckBox->setEnabled(false);
|
||||
spectatorsAllowedCheckBox->setEnabled(false);
|
||||
spectatorsNeedPasswordCheckBox->setEnabled(false);
|
||||
spectatorsCanTalkCheckBox->setEnabled(false);
|
||||
spectatorsSeeEverythingCheckBox->setEnabled(false);
|
||||
createGameAsSpectatorCheckBox->setEnabled(false);
|
||||
startingLifeTotalEdit->setEnabled(false);
|
||||
shareDecklistsOnLoadCheckBox->setEnabled(false);
|
||||
|
||||
descriptionEdit->setText(QString::fromStdString(gameInfo.description()));
|
||||
maxPlayersEdit->setValue(gameInfo.max_players());
|
||||
onlyBuddiesCheckBox->setChecked(gameInfo.only_buddies());
|
||||
onlyRegisteredCheckBox->setChecked(gameInfo.only_registered());
|
||||
spectatorsAllowedCheckBox->setChecked(gameInfo.spectators_allowed());
|
||||
spectatorsNeedPasswordCheckBox->setChecked(gameInfo.spectators_need_password());
|
||||
spectatorsCanTalkCheckBox->setChecked(gameInfo.spectators_can_chat());
|
||||
spectatorsSeeEverythingCheckBox->setChecked(gameInfo.spectators_omniscient());
|
||||
|
||||
QSet<int> types;
|
||||
for (int i = 0; i < gameInfo.game_types_size(); ++i)
|
||||
types.insert(gameInfo.game_types(i));
|
||||
|
||||
QMapIterator<int, QString> gameTypeIterator(gameTypes);
|
||||
while (gameTypeIterator.hasNext()) {
|
||||
gameTypeIterator.next();
|
||||
|
||||
QRadioButton *gameTypeCheckBox = gameTypeCheckBoxes.value(gameTypeIterator.key());
|
||||
gameTypeCheckBox->setEnabled(false);
|
||||
gameTypeCheckBox->setChecked(types.contains(gameTypeIterator.key()));
|
||||
}
|
||||
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgCreateGame::accept);
|
||||
|
||||
setWindowTitle(tr("Game information"));
|
||||
}
|
||||
|
||||
void DlgCreateGame::actReset()
|
||||
{
|
||||
descriptionEdit->setText("");
|
||||
maxPlayersEdit->setValue(2);
|
||||
|
||||
passwordEdit->setText("");
|
||||
onlyBuddiesCheckBox->setChecked(false);
|
||||
onlyRegisteredCheckBox->setChecked(room && room->getUserInfo()->user_level() & ServerInfo_User::IsRegistered);
|
||||
|
||||
spectatorsAllowedCheckBox->setChecked(true);
|
||||
spectatorsNeedPasswordCheckBox->setChecked(false);
|
||||
spectatorsCanTalkCheckBox->setChecked(false);
|
||||
spectatorsSeeEverythingCheckBox->setChecked(false);
|
||||
createGameAsSpectatorCheckBox->setChecked(false);
|
||||
|
||||
startingLifeTotalEdit->setValue(20);
|
||||
shareDecklistsOnLoadCheckBox->setChecked(false);
|
||||
|
||||
QMapIterator<int, QRadioButton *> gameTypeCheckBoxIterator(gameTypeCheckBoxes);
|
||||
while (gameTypeCheckBoxIterator.hasNext()) {
|
||||
gameTypeCheckBoxIterator.next();
|
||||
// must set auto enclusive to false to be able to set the check to false
|
||||
gameTypeCheckBoxIterator.value()->setAutoExclusive(false);
|
||||
gameTypeCheckBoxIterator.value()->setChecked(false);
|
||||
gameTypeCheckBoxIterator.value()->setAutoExclusive(true);
|
||||
}
|
||||
|
||||
descriptionEdit->setFocus();
|
||||
}
|
||||
|
||||
void DlgCreateGame::actOK()
|
||||
{
|
||||
Command_CreateGame cmd;
|
||||
cmd.set_description(descriptionEdit->text().simplified().toStdString());
|
||||
cmd.set_password(passwordEdit->text().toStdString());
|
||||
cmd.set_max_players(maxPlayersEdit->value());
|
||||
cmd.set_only_buddies(onlyBuddiesCheckBox->isChecked());
|
||||
cmd.set_only_registered(onlyRegisteredCheckBox->isChecked());
|
||||
cmd.set_spectators_allowed(spectatorsAllowedCheckBox->isChecked());
|
||||
cmd.set_spectators_need_password(spectatorsNeedPasswordCheckBox->isChecked());
|
||||
cmd.set_spectators_can_talk(spectatorsCanTalkCheckBox->isChecked());
|
||||
cmd.set_spectators_see_everything(spectatorsSeeEverythingCheckBox->isChecked());
|
||||
cmd.set_join_as_judge(QApplication::keyboardModifiers() & Qt::ShiftModifier);
|
||||
cmd.set_join_as_spectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
cmd.set_starting_life_total(startingLifeTotalEdit->value());
|
||||
cmd.set_share_decklists_on_load(shareDecklistsOnLoadCheckBox->isChecked());
|
||||
|
||||
QString _gameTypes = QString();
|
||||
QMapIterator<int, QRadioButton *> gameTypeCheckBoxIterator(gameTypeCheckBoxes);
|
||||
while (gameTypeCheckBoxIterator.hasNext()) {
|
||||
gameTypeCheckBoxIterator.next();
|
||||
if (gameTypeCheckBoxIterator.value()->isChecked()) {
|
||||
cmd.add_game_type_ids(gameTypeCheckBoxIterator.key());
|
||||
_gameTypes += gameTypeCheckBoxIterator.value()->text() + ", ";
|
||||
}
|
||||
}
|
||||
|
||||
SettingsCache::instance().setRememberGameSettings(rememberGameSettings->isChecked());
|
||||
if (rememberGameSettings->isChecked()) {
|
||||
SettingsCache::instance().setGameDescription(descriptionEdit->text());
|
||||
SettingsCache::instance().setMaxPlayers(maxPlayersEdit->value());
|
||||
SettingsCache::instance().setOnlyBuddies(onlyBuddiesCheckBox->isChecked());
|
||||
SettingsCache::instance().setOnlyRegistered(onlyRegisteredCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsAllowed(spectatorsAllowedCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsNeedPassword(spectatorsNeedPasswordCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsCanTalk(spectatorsCanTalkCheckBox->isChecked());
|
||||
SettingsCache::instance().setSpectatorsCanSeeEverything(spectatorsSeeEverythingCheckBox->isChecked());
|
||||
SettingsCache::instance().setCreateGameAsSpectator(createGameAsSpectatorCheckBox->isChecked());
|
||||
SettingsCache::instance().setDefaultStartingLifeTotal(startingLifeTotalEdit->value());
|
||||
SettingsCache::instance().setShareDecklistsOnLoad(shareDecklistsOnLoadCheckBox->isChecked());
|
||||
SettingsCache::instance().setGameTypes(_gameTypes);
|
||||
}
|
||||
PendingCommand *pend = room->prepareRoomCommand(cmd);
|
||||
connect(pend, &PendingCommand::finished, this, &DlgCreateGame::checkResponse);
|
||||
room->sendRoomCommand(pend);
|
||||
|
||||
buttonBox->setEnabled(false);
|
||||
}
|
||||
|
||||
void DlgCreateGame::checkResponse(const Response &response)
|
||||
{
|
||||
buttonBox->setEnabled(true);
|
||||
|
||||
if (response.response_code() == Response::RespOk)
|
||||
accept();
|
||||
else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Server error."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void DlgCreateGame::spectatorsAllowedChanged(QT_STATE_CHANGED_T state)
|
||||
{
|
||||
spectatorsNeedPasswordCheckBox->setEnabled(state);
|
||||
spectatorsCanTalkCheckBox->setEnabled(state);
|
||||
spectatorsSeeEverythingCheckBox->setEnabled(state);
|
||||
}
|
||||
58
cockatrice/src/interface/widgets/dialogs/dlg_create_game.h
Normal file
58
cockatrice/src/interface/widgets/dialogs/dlg_create_game.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @file dlg_create_game.h
|
||||
* @ingroup RoomDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_CREATEGAME_H
|
||||
#define DLG_CREATEGAME_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
#include <libcockatrice/utility/macros.h>
|
||||
|
||||
class QCheckBox;
|
||||
class QDialogButtonBox;
|
||||
class QGroupBox;
|
||||
class QLabel;
|
||||
class QLineEdit;
|
||||
class QPushButton;
|
||||
class QRadioButton;
|
||||
class QSpinBox;
|
||||
class Response;
|
||||
class ServerInfo_Game;
|
||||
class TabRoom;
|
||||
|
||||
class DlgCreateGame : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DlgCreateGame(TabRoom *_room, const QMap<int, QString> &_gameTypes, QWidget *parent = nullptr);
|
||||
DlgCreateGame(const ServerInfo_Game &game, const QMap<int, QString> &_gameTypes, QWidget *parent = nullptr);
|
||||
private slots:
|
||||
void actOK();
|
||||
void actReset();
|
||||
void checkResponse(const Response &response);
|
||||
void spectatorsAllowedChanged(QT_STATE_CHANGED_T state);
|
||||
|
||||
private:
|
||||
TabRoom *room;
|
||||
QMap<int, QString> gameTypes;
|
||||
QMap<int, QRadioButton *> gameTypeCheckBoxes;
|
||||
|
||||
QGroupBox *generalGroupBox, *spectatorsGroupBox, *gameSetupOptionsGroupBox;
|
||||
QLabel *descriptionLabel, *passwordLabel, *maxPlayersLabel, *startingLifeTotalLabel, *shareDecklistsOnLoadLabel;
|
||||
QLineEdit *descriptionEdit, *passwordEdit;
|
||||
QSpinBox *maxPlayersEdit, *startingLifeTotalEdit;
|
||||
QCheckBox *onlyBuddiesCheckBox, *onlyRegisteredCheckBox;
|
||||
QCheckBox *spectatorsAllowedCheckBox, *spectatorsNeedPasswordCheckBox, *spectatorsCanTalkCheckBox,
|
||||
*spectatorsSeeEverythingCheckBox, *createGameAsSpectatorCheckBox;
|
||||
QCheckBox *shareDecklistsOnLoadCheckBox;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QPushButton *clearButton;
|
||||
QCheckBox *rememberGameSettings;
|
||||
|
||||
void sharedCtor();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
#include "dlg_default_tags_editor.h"
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
DlgDefaultTagsEditor::DlgDefaultTagsEditor(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
mainLayout = new QVBoxLayout(this);
|
||||
|
||||
// Input field + Add button (horizontal layout)
|
||||
inputLayout = new QHBoxLayout();
|
||||
inputField = new QLineEdit(this);
|
||||
addButton = new QPushButton(this);
|
||||
inputLayout->addWidget(inputField);
|
||||
inputLayout->addWidget(addButton);
|
||||
mainLayout->addLayout(inputLayout);
|
||||
|
||||
// List widget for tags
|
||||
listWidget = new QListWidget(this);
|
||||
listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
|
||||
listWidget->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::EditKeyPressed);
|
||||
mainLayout->addWidget(listWidget);
|
||||
|
||||
// Button layout (Confirm and Cancel)
|
||||
buttonLayout = new QHBoxLayout();
|
||||
confirmButton = new QPushButton(this);
|
||||
cancelButton = new QPushButton(this);
|
||||
buttonLayout->addWidget(confirmButton);
|
||||
buttonLayout->addWidget(cancelButton);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
loadStringList();
|
||||
retranslateUi();
|
||||
|
||||
// Connect signals
|
||||
connect(addButton, &QPushButton::clicked, this, &DlgDefaultTagsEditor::addItem);
|
||||
connect(cancelButton, &QPushButton::clicked, this, &DlgDefaultTagsEditor::reject); // Cancel closes dialog
|
||||
connect(confirmButton, &QPushButton::clicked, this, &DlgDefaultTagsEditor::confirmChanges);
|
||||
connect(inputField, &QLineEdit::returnPressed, this, &DlgDefaultTagsEditor::addItem);
|
||||
}
|
||||
|
||||
void DlgDefaultTagsEditor::retranslateUi()
|
||||
{
|
||||
setWindowTitle(tr("Edit Tags"));
|
||||
addButton->setText(tr("Add"));
|
||||
confirmButton->setText(tr("Confirm"));
|
||||
cancelButton->setText(tr("Cancel"));
|
||||
inputField->setPlaceholderText(tr("Enter a tag and press Enter"));
|
||||
}
|
||||
|
||||
void DlgDefaultTagsEditor::loadStringList()
|
||||
{
|
||||
listWidget->clear();
|
||||
QStringList tags = SettingsCache::instance().getVisualDeckStorageDefaultTagsList();
|
||||
for (const QString &tag : tags) {
|
||||
auto *item = new QListWidgetItem(); // Create item but don't insert yet
|
||||
|
||||
QWidget *widget = new QWidget(this);
|
||||
QHBoxLayout *layout = new QHBoxLayout(widget);
|
||||
layout->setContentsMargins(2, 2, 2, 2);
|
||||
layout->setSpacing(5);
|
||||
|
||||
QLineEdit *lineEdit = new QLineEdit(tag, this);
|
||||
lineEdit->setFrame(false);
|
||||
lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
|
||||
layout->addWidget(lineEdit);
|
||||
|
||||
QPushButton *deleteButton = new QPushButton(tr("✖"), this);
|
||||
deleteButton->setFixedSize(25, 25);
|
||||
layout->addWidget(deleteButton);
|
||||
|
||||
widget->setLayout(layout);
|
||||
|
||||
// Set item height explicitly to match the widget (widgets get squished without it)
|
||||
item->setSizeHint(widget->sizeHint());
|
||||
|
||||
listWidget->addItem(item);
|
||||
listWidget->setItemWidget(item, widget);
|
||||
|
||||
connect(deleteButton, &QPushButton::clicked, this, [this, item]() { deleteItem(item); });
|
||||
}
|
||||
}
|
||||
|
||||
void DlgDefaultTagsEditor::addItem()
|
||||
{
|
||||
QString newTag = inputField->text().trimmed();
|
||||
if (newTag.isEmpty()) {
|
||||
QMessageBox::warning(this, tr("Invalid Input"), tr("Tag name cannot be empty!"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent duplicate tags
|
||||
for (int i = 0; i < listWidget->count(); ++i) {
|
||||
QWidget *widget = listWidget->itemWidget(listWidget->item(i));
|
||||
if (!widget)
|
||||
continue;
|
||||
QLineEdit *lineEdit = widget->findChild<QLineEdit *>();
|
||||
if (lineEdit && lineEdit->text() == newTag) {
|
||||
QMessageBox::warning(this, tr("Duplicate Tag"), tr("This tag already exists."));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Add new tag
|
||||
auto *item = new QListWidgetItem(listWidget);
|
||||
QWidget *widget = new QWidget(this);
|
||||
QHBoxLayout *layout = new QHBoxLayout(widget);
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
// Editable tag label
|
||||
QLineEdit *lineEdit = new QLineEdit(newTag, this);
|
||||
lineEdit->setFrame(false);
|
||||
layout->addWidget(lineEdit);
|
||||
|
||||
// Delete button
|
||||
QPushButton *deleteButton = new QPushButton(tr("✖"), this);
|
||||
deleteButton->setFixedSize(24, 24);
|
||||
layout->addWidget(deleteButton);
|
||||
|
||||
widget->setLayout(layout);
|
||||
listWidget->setItemWidget(item, widget);
|
||||
|
||||
connect(deleteButton, &QPushButton::clicked, this, [this, item]() { deleteItem(item); });
|
||||
|
||||
inputField->clear();
|
||||
}
|
||||
|
||||
void DlgDefaultTagsEditor::deleteItem(QListWidgetItem *item)
|
||||
{
|
||||
delete listWidget->takeItem(listWidget->row(item));
|
||||
}
|
||||
|
||||
void DlgDefaultTagsEditor::confirmChanges()
|
||||
{
|
||||
QStringList updatedList;
|
||||
for (int i = 0; i < listWidget->count(); ++i) {
|
||||
QWidget *widget = listWidget->itemWidget(listWidget->item(i));
|
||||
if (!widget)
|
||||
continue;
|
||||
QLineEdit *lineEdit = widget->findChild<QLineEdit *>();
|
||||
if (lineEdit) {
|
||||
updatedList.append(lineEdit->text());
|
||||
}
|
||||
}
|
||||
SettingsCache::instance().setVisualDeckStorageDefaultTagsList(updatedList);
|
||||
accept(); // Close dialog and confirm changes
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* @file dlg_default_tags_editor.h
|
||||
* @ingroup Dialogs
|
||||
* @ingroup DeckStorageWidgets
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_DEFAULT_TAGS_EDITOR_H
|
||||
#define DLG_DEFAULT_TAGS_EDITOR_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QListWidget>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class DlgDefaultTagsEditor : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DlgDefaultTagsEditor(QWidget *parent = nullptr);
|
||||
|
||||
private slots:
|
||||
void addItem();
|
||||
void deleteItem(QListWidgetItem *item);
|
||||
void confirmChanges();
|
||||
|
||||
private:
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *inputLayout;
|
||||
QListWidget *listWidget;
|
||||
QHBoxLayout *buttonLayout;
|
||||
QLineEdit *inputField;
|
||||
QPushButton *addButton;
|
||||
QPushButton *confirmButton;
|
||||
QPushButton *cancelButton;
|
||||
|
||||
void loadStringList();
|
||||
void retranslateUi();
|
||||
};
|
||||
|
||||
#endif // DLG_DEFAULT_TAGS_EDITOR_H
|
||||
87
cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp
Normal file
87
cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.cpp
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
#include "dlg_edit_avatar.h"
|
||||
|
||||
#include <QBuffer>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QFileDialog>
|
||||
#include <QImageReader>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgEditAvatar::DlgEditAvatar(QWidget *parent) : QDialog(parent), image()
|
||||
{
|
||||
imageLabel = new QLabel(tr("No image chosen."));
|
||||
imageLabel->setFixedSize(400, 200);
|
||||
imageLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
|
||||
imageLabel->setStyleSheet("border: 1px solid #000");
|
||||
|
||||
textLabel = new QLabel(tr("To change your avatar, choose a new image.\nTo remove your current avatar, confirm "
|
||||
"without choosing a new image."));
|
||||
browseButton = new QPushButton(tr("Browse..."));
|
||||
connect(browseButton, &QPushButton::clicked, this, &DlgEditAvatar::actBrowse);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(imageLabel, 0, 0, 1, 2);
|
||||
grid->addWidget(textLabel, 1, 0);
|
||||
grid->addWidget(browseButton, 1, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgEditAvatar::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgEditAvatar::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Change avatar"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
}
|
||||
|
||||
void DlgEditAvatar::actOk()
|
||||
{
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgEditAvatar::actBrowse()
|
||||
{
|
||||
QString fileName =
|
||||
QFileDialog::getOpenFileName(this, tr("Open Image"), QDir::homePath(), tr("Image Files (*.png *.jpg *.bmp)"));
|
||||
if (fileName.isEmpty()) {
|
||||
imageLabel->setText(tr("No image chosen."));
|
||||
return;
|
||||
}
|
||||
|
||||
QImageReader imgReader;
|
||||
imgReader.setDecideFormatFromContent(true);
|
||||
imgReader.setFileName(fileName);
|
||||
if (!imgReader.read(&image)) {
|
||||
qCWarning(DlgEditAvatarLog) << "Avatar image loading failed for file:" << fileName;
|
||||
imageLabel->setText(tr("Invalid image chosen."));
|
||||
return;
|
||||
}
|
||||
imageLabel->setPixmap(QPixmap::fromImage(image).scaled(400, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
}
|
||||
|
||||
QByteArray DlgEditAvatar::getImage()
|
||||
{
|
||||
if (image.isNull()) {
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
QByteArray ba;
|
||||
QBuffer buffer(&ba);
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
image.save(&buffer, "JPG");
|
||||
if (ba.length() > MAX_FILE_LENGTH) {
|
||||
image = image.scaledToWidth(image.width() / 2); // divide the amount of pixels in four to get the size down
|
||||
} else {
|
||||
return ba;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.h
Normal file
37
cockatrice/src/interface/widgets/dialogs/dlg_edit_avatar.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @file dlg_edit_avatar.h
|
||||
* @ingroup AccountDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_EDITAVATAR_H
|
||||
#define DLG_EDITAVATAR_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DlgEditAvatarLog, "dlg_edit_avatar");
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgEditAvatar : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgEditAvatar(QWidget *parent = nullptr);
|
||||
QByteArray getImage();
|
||||
private slots:
|
||||
void actOk();
|
||||
void actBrowse();
|
||||
|
||||
private:
|
||||
QImage image;
|
||||
QLabel *textLabel, *imageLabel;
|
||||
QPushButton *browseButton;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
#include "dlg_edit_password.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgEditPassword::DlgEditPassword(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
oldPasswordLabel = new QLabel(tr("Old password:"));
|
||||
oldPasswordEdit = new QLineEdit();
|
||||
oldPasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
|
||||
auto &servers = SettingsCache::instance().servers();
|
||||
if (servers.getSavePassword()) {
|
||||
oldPasswordEdit->setText(servers.getPassword());
|
||||
}
|
||||
|
||||
oldPasswordLabel->setBuddy(oldPasswordEdit);
|
||||
oldPasswordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
newPasswordLabel = new QLabel(tr("New password:"));
|
||||
newPasswordEdit = new QLineEdit();
|
||||
newPasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
newPasswordLabel->setBuddy(newPasswordLabel);
|
||||
newPasswordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
newPasswordLabel2 = new QLabel(tr("Confirm new password:"));
|
||||
newPasswordEdit2 = new QLineEdit();
|
||||
newPasswordEdit2->setMaxLength(MAX_NAME_LENGTH);
|
||||
newPasswordLabel2->setBuddy(newPasswordLabel2);
|
||||
newPasswordEdit2->setEchoMode(QLineEdit::Password);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(oldPasswordLabel, 0, 0);
|
||||
grid->addWidget(oldPasswordEdit, 0, 1);
|
||||
grid->addWidget(newPasswordLabel, 1, 0);
|
||||
grid->addWidget(newPasswordEdit, 1, 1);
|
||||
grid->addWidget(newPasswordLabel2, 2, 0);
|
||||
grid->addWidget(newPasswordEdit2, 2, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgEditPassword::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgEditPassword::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Change password"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
}
|
||||
|
||||
void DlgEditPassword::actOk()
|
||||
{
|
||||
// TODO this stuff should be using qvalidators
|
||||
if (newPasswordEdit->text().length() < 8) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Your password is too short."));
|
||||
return;
|
||||
} else if (newPasswordEdit->text() != newPasswordEdit2->text()) {
|
||||
QMessageBox::warning(this, tr("Error"), tr("The new passwords don't match."));
|
||||
return;
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
39
cockatrice/src/interface/widgets/dialogs/dlg_edit_password.h
Normal file
39
cockatrice/src/interface/widgets/dialogs/dlg_edit_password.h
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
/**
|
||||
* @file dlg_edit_password.h
|
||||
* @ingroup AccountDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_EDITPASSWORD_H
|
||||
#define DLG_EDITPASSWORD_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgEditPassword : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgEditPassword(QWidget *parent = nullptr);
|
||||
QString getOldPassword() const
|
||||
{
|
||||
return oldPasswordEdit->text();
|
||||
}
|
||||
QString getNewPassword() const
|
||||
{
|
||||
return newPasswordEdit->text();
|
||||
}
|
||||
private slots:
|
||||
void actOk();
|
||||
|
||||
private:
|
||||
QLabel *oldPasswordLabel, *newPasswordLabel, *newPasswordLabel2;
|
||||
QLineEdit *oldPasswordEdit, *newPasswordEdit, *newPasswordEdit2;
|
||||
};
|
||||
|
||||
#endif
|
||||
200
cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.cpp
Normal file
200
cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.cpp
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
#include "dlg_edit_tokens.h"
|
||||
|
||||
#include "../interface/widgets/utility/get_text_with_max.h"
|
||||
#include "../main.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QComboBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QInputDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QMessageBox>
|
||||
#include <QToolBar>
|
||||
#include <QTreeView>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/card/card_database/card_database.h>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/card/card_database/model/card_database_model.h>
|
||||
#include <libcockatrice/card/card_database/model/token/token_edit_model.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgEditTokens::DlgEditTokens(QWidget *parent) : QDialog(parent), currentCard(nullptr)
|
||||
{
|
||||
nameLabel = new QLabel(tr("&Name:"));
|
||||
nameEdit = new QLineEdit;
|
||||
nameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
nameEdit->setEnabled(false);
|
||||
nameLabel->setBuddy(nameEdit);
|
||||
|
||||
colorLabel = new QLabel(tr("C&olor:"));
|
||||
colorEdit = new QComboBox;
|
||||
colorEdit->addItem(tr("white"), QChar('w'));
|
||||
colorEdit->addItem(tr("blue"), QChar('u'));
|
||||
colorEdit->addItem(tr("black"), QChar('b'));
|
||||
colorEdit->addItem(tr("red"), QChar('r'));
|
||||
colorEdit->addItem(tr("green"), QChar('g'));
|
||||
colorEdit->addItem(tr("multicolor"), QChar('m'));
|
||||
colorEdit->addItem(tr("colorless"), QChar());
|
||||
colorLabel->setBuddy(colorEdit);
|
||||
connect(colorEdit, qOverload<int>(&QComboBox::currentIndexChanged), this, &DlgEditTokens::colorChanged);
|
||||
|
||||
ptLabel = new QLabel(tr("&P/T:"));
|
||||
ptEdit = new QLineEdit;
|
||||
ptEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
ptLabel->setBuddy(ptEdit);
|
||||
connect(ptEdit, &QLineEdit::textChanged, this, &DlgEditTokens::ptChanged);
|
||||
|
||||
annotationLabel = new QLabel(tr("&Annotation:"));
|
||||
annotationEdit = new QLineEdit;
|
||||
annotationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
annotationLabel->setBuddy(annotationEdit);
|
||||
connect(annotationEdit, &QLineEdit::textChanged, this, &DlgEditTokens::annotationChanged);
|
||||
|
||||
auto *grid = new QGridLayout;
|
||||
grid->addWidget(nameLabel, 0, 0);
|
||||
grid->addWidget(nameEdit, 0, 1);
|
||||
grid->addWidget(colorLabel, 1, 0);
|
||||
grid->addWidget(colorEdit, 1, 1);
|
||||
grid->addWidget(ptLabel, 2, 0);
|
||||
grid->addWidget(ptEdit, 2, 1);
|
||||
grid->addWidget(annotationLabel, 3, 0);
|
||||
grid->addWidget(annotationEdit, 3, 1);
|
||||
|
||||
QGroupBox *tokenDataGroupBox = new QGroupBox(tr("Token data"));
|
||||
tokenDataGroupBox->setLayout(grid);
|
||||
|
||||
databaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), false, this);
|
||||
databaseModel->setObjectName("databaseModel");
|
||||
cardDatabaseDisplayModel = new TokenEditModel(this);
|
||||
cardDatabaseDisplayModel->setSourceModel(databaseModel);
|
||||
cardDatabaseDisplayModel->setIsToken(CardDatabaseDisplayModel::ShowTrue);
|
||||
|
||||
chooseTokenView = new QTreeView;
|
||||
chooseTokenView->setModel(cardDatabaseDisplayModel);
|
||||
chooseTokenView->setUniformRowHeights(true);
|
||||
chooseTokenView->setRootIsDecorated(false);
|
||||
chooseTokenView->setAlternatingRowColors(true);
|
||||
chooseTokenView->setSortingEnabled(true);
|
||||
chooseTokenView->sortByColumn(0, Qt::AscendingOrder);
|
||||
chooseTokenView->resizeColumnToContents(0);
|
||||
chooseTokenView->header()->setStretchLastSection(false);
|
||||
chooseTokenView->header()->hideSection(1);
|
||||
chooseTokenView->header()->hideSection(2);
|
||||
chooseTokenView->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
chooseTokenView->header()->setSectionResizeMode(4, QHeaderView::ResizeToContents);
|
||||
|
||||
connect(chooseTokenView->selectionModel(), &QItemSelectionModel::currentRowChanged, this,
|
||||
&DlgEditTokens::tokenSelectionChanged);
|
||||
|
||||
QAction *aAddToken = new QAction(tr("Add token"), this);
|
||||
aAddToken->setIcon(QPixmap("theme:icons/increment"));
|
||||
connect(aAddToken, &QAction::triggered, this, &DlgEditTokens::actAddToken);
|
||||
QAction *aRemoveToken = new QAction(tr("Remove token"), this);
|
||||
aRemoveToken->setIcon(QPixmap("theme:icons/decrement"));
|
||||
connect(aRemoveToken, &QAction::triggered, this, &DlgEditTokens::actRemoveToken);
|
||||
|
||||
auto *databaseToolBar = new QToolBar;
|
||||
databaseToolBar->addAction(aAddToken);
|
||||
databaseToolBar->addAction(aRemoveToken);
|
||||
|
||||
auto *leftVBox = new QVBoxLayout;
|
||||
leftVBox->addWidget(chooseTokenView);
|
||||
leftVBox->addWidget(databaseToolBar);
|
||||
|
||||
auto *hbox = new QHBoxLayout;
|
||||
hbox->addLayout(leftVBox);
|
||||
hbox->addWidget(tokenDataGroupBox);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Close);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgEditTokens::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgEditTokens::reject);
|
||||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(hbox);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
setWindowTitle(tr("Edit custom tokens"));
|
||||
}
|
||||
|
||||
void DlgEditTokens::tokenSelectionChanged(const QModelIndex ¤t, const QModelIndex & /* previous */)
|
||||
{
|
||||
const QModelIndex realIndex = cardDatabaseDisplayModel->mapToSource(current);
|
||||
|
||||
if (current.row() >= 0) {
|
||||
currentCard = databaseModel->getCard(realIndex.row());
|
||||
} else {
|
||||
currentCard.clear();
|
||||
}
|
||||
|
||||
if (currentCard) {
|
||||
nameEdit->setText(currentCard->getName());
|
||||
const QChar cardColor = currentCard->getColorChar();
|
||||
colorEdit->setCurrentIndex(colorEdit->findData(cardColor, Qt::UserRole, Qt::MatchFixedString));
|
||||
ptEdit->setText(currentCard->getPowTough());
|
||||
annotationEdit->setText(currentCard->getText());
|
||||
} else {
|
||||
nameEdit->setText("");
|
||||
colorEdit->setCurrentIndex(colorEdit->findData(QChar(), Qt::UserRole, Qt::MatchFixedString));
|
||||
ptEdit->setText("");
|
||||
annotationEdit->setText("");
|
||||
}
|
||||
}
|
||||
|
||||
void DlgEditTokens::actAddToken()
|
||||
{
|
||||
QString name;
|
||||
for (;;) {
|
||||
name = getTextWithMax(this, tr("Add token"), tr("Please enter the name of the token:"));
|
||||
if (name.isEmpty())
|
||||
return;
|
||||
if (databaseModel->getDatabase()->query()->getCardInfo(name)) {
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("The chosen name conflicts with an existing card or token.\nMake sure to enable "
|
||||
"the 'Token' set in the \"Manage sets\" dialog to display them correctly."));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QString setName = CardSet::TOKENS_SETNAME;
|
||||
SetToPrintingsMap sets;
|
||||
sets[setName].append(PrintingInfo(databaseModel->getDatabase()->getSet(setName)));
|
||||
CardInfoPtr card = CardInfo::newInstance(name, "", true, QVariantHash(), QList<CardRelation *>(),
|
||||
QList<CardRelation *>(), sets, false, false, -1, false);
|
||||
card->setCardType("Token");
|
||||
|
||||
databaseModel->getDatabase()->addCard(card);
|
||||
}
|
||||
|
||||
void DlgEditTokens::actRemoveToken()
|
||||
{
|
||||
if (currentCard) {
|
||||
CardInfoPtr cardToRemove = currentCard; // the currentCard property gets modified during db->removeCard()
|
||||
currentCard.clear();
|
||||
databaseModel->getDatabase()->removeCard(cardToRemove);
|
||||
}
|
||||
}
|
||||
|
||||
void DlgEditTokens::colorChanged(int colorIndex)
|
||||
{
|
||||
if (currentCard)
|
||||
currentCard->setColors(QString(colorEdit->itemData(colorIndex).toChar()));
|
||||
}
|
||||
|
||||
void DlgEditTokens::ptChanged(const QString &_pt)
|
||||
{
|
||||
if (currentCard)
|
||||
currentCard->setPowTough(_pt);
|
||||
}
|
||||
|
||||
void DlgEditTokens::annotationChanged(const QString &_annotation)
|
||||
{
|
||||
if (currentCard)
|
||||
currentCard->setText(_annotation);
|
||||
}
|
||||
47
cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.h
Normal file
47
cockatrice/src/interface/widgets/dialogs/dlg_edit_tokens.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file dlg_edit_tokens.h
|
||||
* @ingroup GameDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_EDIT_TOKENS_H
|
||||
#define DLG_EDIT_TOKENS_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <libcockatrice/card/card_info.h>
|
||||
|
||||
class QModelIndex;
|
||||
class CardDatabaseModel;
|
||||
class TokenEditModel;
|
||||
class QLabel;
|
||||
class QComboBox;
|
||||
class QLineEdit;
|
||||
class QTreeView;
|
||||
|
||||
class DlgEditTokens : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void tokenSelectionChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
void colorChanged(int _colorIndex);
|
||||
void ptChanged(const QString &_pt);
|
||||
void annotationChanged(const QString &_annotation);
|
||||
|
||||
void actAddToken();
|
||||
void actRemoveToken();
|
||||
|
||||
private:
|
||||
CardInfoPtr currentCard;
|
||||
CardDatabaseModel *databaseModel;
|
||||
TokenEditModel *cardDatabaseDisplayModel;
|
||||
QStringList predefinedTokens;
|
||||
QLabel *nameLabel, *colorLabel, *ptLabel, *annotationLabel;
|
||||
QComboBox *colorEdit;
|
||||
QLineEdit *nameEdit, *ptEdit, *annotationEdit;
|
||||
QTreeView *chooseTokenView;
|
||||
|
||||
public:
|
||||
explicit DlgEditTokens(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif
|
||||
66
cockatrice/src/interface/widgets/dialogs/dlg_edit_user.cpp
Normal file
66
cockatrice/src/interface/widgets/dialogs/dlg_edit_user.cpp
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include "dlg_edit_user.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgEditUser::DlgEditUser(QWidget *parent, QString email, QString country, QString realName) : QDialog(parent)
|
||||
{
|
||||
emailLabel = new QLabel(tr("Email:"));
|
||||
emailEdit = new QLineEdit();
|
||||
emailEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailLabel->setBuddy(emailEdit);
|
||||
emailEdit->setText(email);
|
||||
|
||||
countryLabel = new QLabel(tr("Country:"));
|
||||
countryEdit = new QComboBox();
|
||||
countryLabel->setBuddy(countryEdit);
|
||||
countryEdit->insertItem(0, tr("Undefined"));
|
||||
countryEdit->setCurrentIndex(0);
|
||||
|
||||
QStringList countries = SettingsCache::instance().getCountries();
|
||||
int i = 1;
|
||||
for (const QString &c : countries) {
|
||||
countryEdit->addItem(QPixmap("theme:countries/" + c.toLower()), c);
|
||||
if (c == country)
|
||||
countryEdit->setCurrentIndex(i);
|
||||
|
||||
++i;
|
||||
}
|
||||
|
||||
realnameLabel = new QLabel(tr("Real name:"));
|
||||
realnameEdit = new QLineEdit();
|
||||
realnameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
realnameLabel->setBuddy(realnameEdit);
|
||||
realnameEdit->setText(realName);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(emailLabel, 0, 0);
|
||||
grid->addWidget(emailEdit, 0, 1);
|
||||
grid->addWidget(countryLabel, 2, 0);
|
||||
grid->addWidget(countryEdit, 2, 1);
|
||||
grid->addWidget(realnameLabel, 3, 0);
|
||||
grid->addWidget(realnameEdit, 3, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgEditUser::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgEditUser::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Edit user profile"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
}
|
||||
|
||||
void DlgEditUser::actOk()
|
||||
{
|
||||
accept();
|
||||
}
|
||||
47
cockatrice/src/interface/widgets/dialogs/dlg_edit_user.h
Normal file
47
cockatrice/src/interface/widgets/dialogs/dlg_edit_user.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file dlg_edit user.h
|
||||
* @ingroup NetworkDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_EDITUSER_H
|
||||
#define DLG_EDITUSER_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgEditUser : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgEditUser(QWidget *parent = nullptr,
|
||||
QString email = QString(),
|
||||
QString country = QString(),
|
||||
QString realName = QString());
|
||||
QString getEmail() const
|
||||
{
|
||||
return emailEdit->text();
|
||||
}
|
||||
QString getCountry() const
|
||||
{
|
||||
return countryEdit->currentIndex() == 0 ? "" : countryEdit->currentText();
|
||||
}
|
||||
QString getRealName() const
|
||||
{
|
||||
return realnameEdit->text();
|
||||
}
|
||||
private slots:
|
||||
void actOk();
|
||||
|
||||
private:
|
||||
QLabel *emailLabel, *countryLabel, *realnameLabel;
|
||||
QLineEdit *emailEdit, *realnameEdit;
|
||||
QComboBox *countryEdit;
|
||||
};
|
||||
|
||||
#endif
|
||||
289
cockatrice/src/interface/widgets/dialogs/dlg_filter_games.cpp
Normal file
289
cockatrice/src/interface/widgets/dialogs/dlg_filter_games.cpp
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
#include "dlg_filter_games.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QCryptographicHash>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
|
||||
DlgFilterGames::DlgFilterGames(const QMap<int, QString> &_allGameTypes,
|
||||
const GamesProxyModel *_gamesProxyModel,
|
||||
QWidget *parent)
|
||||
: QDialog(parent), allGameTypes(_allGameTypes), gamesProxyModel(_gamesProxyModel),
|
||||
gameAgeMap({{QTime(), tr("no limit")},
|
||||
{QTime(0, 5), tr("5 minutes")},
|
||||
{QTime(0, 10), tr("10 minutes")},
|
||||
{QTime(0, 30), tr("30 minutes")},
|
||||
{QTime(1, 0), tr("1 hour")},
|
||||
{QTime(2, 0), tr("2 hours")}})
|
||||
{
|
||||
hideBuddiesOnlyGames = new QCheckBox(tr("Hide 'buddies only' games"));
|
||||
hideBuddiesOnlyGames->setChecked(gamesProxyModel->getHideBuddiesOnlyGames());
|
||||
|
||||
hideFullGames = new QCheckBox(tr("Hide full games"));
|
||||
hideFullGames->setChecked(gamesProxyModel->getHideFullGames());
|
||||
|
||||
hideGamesThatStarted = new QCheckBox(tr("Hide games that have started"));
|
||||
hideGamesThatStarted->setChecked(gamesProxyModel->getHideGamesThatStarted());
|
||||
|
||||
hidePasswordProtectedGames = new QCheckBox(tr("Hide password protected games"));
|
||||
hidePasswordProtectedGames->setChecked(gamesProxyModel->getHidePasswordProtectedGames());
|
||||
|
||||
hideIgnoredUserGames = new QCheckBox(tr("Hide 'ignored user' games"));
|
||||
hideIgnoredUserGames->setChecked(gamesProxyModel->getHideIgnoredUserGames());
|
||||
|
||||
hideNotBuddyCreatedGames = new QCheckBox(tr("Hide games not created by buddy"));
|
||||
hideNotBuddyCreatedGames->setChecked(gamesProxyModel->getHideNotBuddyCreatedGames());
|
||||
|
||||
hideOpenDecklistGames = new QCheckBox(tr("Hide games with forced open decklists"));
|
||||
hideOpenDecklistGames->setChecked(gamesProxyModel->getHideOpenDecklistGames());
|
||||
|
||||
maxGameAgeComboBox = new QComboBox();
|
||||
maxGameAgeComboBox->setEditable(false);
|
||||
maxGameAgeComboBox->addItems(gameAgeMap.values());
|
||||
QTime gameAge = gamesProxyModel->getMaxGameAge();
|
||||
maxGameAgeComboBox->setCurrentIndex(gameAgeMap.keys().indexOf(gameAge)); // index is -1 if unknown
|
||||
auto *maxGameAgeLabel = new QLabel(tr("&Newer than:"));
|
||||
maxGameAgeLabel->setBuddy(maxGameAgeComboBox);
|
||||
|
||||
gameNameFilterEdit = new QLineEdit;
|
||||
gameNameFilterEdit->setText(gamesProxyModel->getGameNameFilter());
|
||||
auto *gameNameFilterLabel = new QLabel(tr("Game &description:"));
|
||||
gameNameFilterLabel->setBuddy(gameNameFilterEdit);
|
||||
creatorNameFilterEdit = new QLineEdit;
|
||||
creatorNameFilterEdit->setText(gamesProxyModel->getCreatorNameFilter());
|
||||
auto *creatorNameFilterLabel = new QLabel(tr("&Creator name:"));
|
||||
creatorNameFilterLabel->setBuddy(creatorNameFilterEdit);
|
||||
|
||||
auto *generalGrid = new QGridLayout;
|
||||
generalGrid->addWidget(gameNameFilterLabel, 0, 0);
|
||||
generalGrid->addWidget(gameNameFilterEdit, 0, 1);
|
||||
generalGrid->addWidget(creatorNameFilterLabel, 1, 0);
|
||||
generalGrid->addWidget(creatorNameFilterEdit, 1, 1);
|
||||
generalGrid->addWidget(maxGameAgeLabel, 2, 0);
|
||||
generalGrid->addWidget(maxGameAgeComboBox, 2, 1);
|
||||
generalGroupBox = new QGroupBox(tr("General"));
|
||||
generalGroupBox->setLayout(generalGrid);
|
||||
|
||||
auto *gameTypeFilterLayout = new QVBoxLayout;
|
||||
QMapIterator<int, QString> gameTypesIterator(allGameTypes);
|
||||
while (gameTypesIterator.hasNext()) {
|
||||
gameTypesIterator.next();
|
||||
|
||||
auto *temp = new QCheckBox(gameTypesIterator.value());
|
||||
temp->setChecked(gamesProxyModel->getGameTypeFilter().contains(gameTypesIterator.key()));
|
||||
|
||||
gameTypeFilterCheckBoxes.insert(gameTypesIterator.key(), temp);
|
||||
gameTypeFilterLayout->addWidget(temp);
|
||||
}
|
||||
QGroupBox *gameTypeFilterGroupBox;
|
||||
if (!allGameTypes.isEmpty()) {
|
||||
gameTypeFilterGroupBox = new QGroupBox(tr("&Game types"));
|
||||
gameTypeFilterGroupBox->setLayout(gameTypeFilterLayout);
|
||||
} else
|
||||
gameTypeFilterGroupBox = nullptr;
|
||||
|
||||
auto *maxPlayersFilterMinLabel = new QLabel(tr("at &least:"));
|
||||
maxPlayersFilterMinSpinBox = new QSpinBox;
|
||||
maxPlayersFilterMinSpinBox->setMinimum(0);
|
||||
maxPlayersFilterMinSpinBox->setMaximum(99);
|
||||
maxPlayersFilterMinSpinBox->setValue(gamesProxyModel->getMaxPlayersFilterMin());
|
||||
maxPlayersFilterMinLabel->setBuddy(maxPlayersFilterMinSpinBox);
|
||||
|
||||
auto *maxPlayersFilterMaxLabel = new QLabel(tr("at &most:"));
|
||||
maxPlayersFilterMaxSpinBox = new QSpinBox;
|
||||
maxPlayersFilterMaxSpinBox->setMinimum(0);
|
||||
maxPlayersFilterMaxSpinBox->setMaximum(99);
|
||||
maxPlayersFilterMaxSpinBox->setValue(gamesProxyModel->getMaxPlayersFilterMax());
|
||||
maxPlayersFilterMaxLabel->setBuddy(maxPlayersFilterMaxSpinBox);
|
||||
|
||||
auto *maxPlayersFilterLayout = new QGridLayout;
|
||||
maxPlayersFilterLayout->addWidget(maxPlayersFilterMinLabel, 0, 0);
|
||||
maxPlayersFilterLayout->addWidget(maxPlayersFilterMinSpinBox, 0, 1);
|
||||
maxPlayersFilterLayout->addWidget(maxPlayersFilterMaxLabel, 1, 0);
|
||||
maxPlayersFilterLayout->addWidget(maxPlayersFilterMaxSpinBox, 1, 1);
|
||||
|
||||
auto *maxPlayersGroupBox = new QGroupBox(tr("Maximum player count"));
|
||||
maxPlayersGroupBox->setLayout(maxPlayersFilterLayout);
|
||||
|
||||
auto *restrictionsLayout = new QGridLayout;
|
||||
restrictionsLayout->addWidget(hideFullGames, 0, 0);
|
||||
restrictionsLayout->addWidget(hideGamesThatStarted, 1, 0);
|
||||
restrictionsLayout->addWidget(hidePasswordProtectedGames, 2, 0);
|
||||
restrictionsLayout->addWidget(hideBuddiesOnlyGames, 3, 0);
|
||||
restrictionsLayout->addWidget(hideIgnoredUserGames, 4, 0);
|
||||
restrictionsLayout->addWidget(hideNotBuddyCreatedGames, 5, 0);
|
||||
restrictionsLayout->addWidget(hideOpenDecklistGames, 6, 0);
|
||||
|
||||
auto *restrictionsGroupBox = new QGroupBox(tr("Restrictions"));
|
||||
restrictionsGroupBox->setLayout(restrictionsLayout);
|
||||
|
||||
showOnlyIfSpectatorsCanWatch = new QCheckBox(tr("Show games only if &spectators can watch"));
|
||||
showOnlyIfSpectatorsCanWatch->setChecked(gamesProxyModel->getShowOnlyIfSpectatorsCanWatch());
|
||||
connect(showOnlyIfSpectatorsCanWatch, &QCheckBox::toggled, this,
|
||||
&DlgFilterGames::toggleSpectatorCheckboxEnabledness);
|
||||
|
||||
showSpectatorPasswordProtected = new QCheckBox(tr("Show spectator password p&rotected games"));
|
||||
showSpectatorPasswordProtected->setChecked(gamesProxyModel->getShowSpectatorPasswordProtected());
|
||||
showOnlyIfSpectatorsCanChat = new QCheckBox(tr("Show only if spectators can ch&at"));
|
||||
showOnlyIfSpectatorsCanChat->setChecked(gamesProxyModel->getShowOnlyIfSpectatorsCanChat());
|
||||
showOnlyIfSpectatorsCanSeeHands = new QCheckBox(tr("Show only if spectators can see &hands"));
|
||||
showOnlyIfSpectatorsCanSeeHands->setChecked(gamesProxyModel->getShowOnlyIfSpectatorsCanSeeHands());
|
||||
toggleSpectatorCheckboxEnabledness(getShowOnlyIfSpectatorsCanWatch());
|
||||
|
||||
auto *spectatorsLayout = new QGridLayout;
|
||||
spectatorsLayout->addWidget(showOnlyIfSpectatorsCanWatch, 0, 0);
|
||||
spectatorsLayout->addWidget(showSpectatorPasswordProtected, 1, 0);
|
||||
spectatorsLayout->addWidget(showOnlyIfSpectatorsCanChat, 2, 0);
|
||||
spectatorsLayout->addWidget(showOnlyIfSpectatorsCanSeeHands, 3, 0);
|
||||
|
||||
auto *spectatorsGroupBox = new QGroupBox(tr("Spectators"));
|
||||
spectatorsGroupBox->setLayout(spectatorsLayout);
|
||||
|
||||
auto *leftGrid = new QGridLayout;
|
||||
leftGrid->addWidget(generalGroupBox, 0, 0, 1, 2);
|
||||
leftGrid->addWidget(maxPlayersGroupBox, 2, 0, 1, 2);
|
||||
leftGrid->addWidget(restrictionsGroupBox, 3, 0, 1, 2);
|
||||
|
||||
auto *leftColumn = new QVBoxLayout;
|
||||
leftColumn->addLayout(leftGrid);
|
||||
leftColumn->addStretch();
|
||||
|
||||
auto *rightGrid = new QGridLayout;
|
||||
rightGrid->addWidget(gameTypeFilterGroupBox, 0, 0, 1, 1);
|
||||
rightGrid->addWidget(spectatorsGroupBox, 1, 0, 1, 1);
|
||||
|
||||
auto *rightColumn = new QVBoxLayout;
|
||||
rightColumn->addLayout(rightGrid);
|
||||
rightColumn->addStretch();
|
||||
|
||||
auto *hbox = new QHBoxLayout;
|
||||
hbox->addLayout(leftColumn);
|
||||
hbox->addLayout(rightColumn);
|
||||
|
||||
auto *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgFilterGames::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgFilterGames::reject);
|
||||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(hbox);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
setWindowTitle(tr("Filter games"));
|
||||
|
||||
setFixedHeight(sizeHint().height());
|
||||
}
|
||||
|
||||
void DlgFilterGames::actOk()
|
||||
{
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgFilterGames::toggleSpectatorCheckboxEnabledness(bool spectatorsEnabled)
|
||||
{
|
||||
showSpectatorPasswordProtected->setDisabled(!spectatorsEnabled);
|
||||
showOnlyIfSpectatorsCanChat->setDisabled(!spectatorsEnabled);
|
||||
showOnlyIfSpectatorsCanSeeHands->setDisabled(!spectatorsEnabled);
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getHideFullGames() const
|
||||
{
|
||||
return hideFullGames->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getHideGamesThatStarted() const
|
||||
{
|
||||
return hideGamesThatStarted->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getHideBuddiesOnlyGames() const
|
||||
{
|
||||
return hideBuddiesOnlyGames->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getHidePasswordProtectedGames() const
|
||||
{
|
||||
return hidePasswordProtectedGames->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getHideIgnoredUserGames() const
|
||||
{
|
||||
return hideIgnoredUserGames->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getHideNotBuddyCreatedGames() const
|
||||
{
|
||||
return hideNotBuddyCreatedGames->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getHideOpenDecklistGames() const
|
||||
{
|
||||
return hideOpenDecklistGames->isChecked();
|
||||
}
|
||||
|
||||
QString DlgFilterGames::getGameNameFilter() const
|
||||
{
|
||||
return gameNameFilterEdit->text();
|
||||
}
|
||||
|
||||
QString DlgFilterGames::getCreatorNameFilter() const
|
||||
{
|
||||
return creatorNameFilterEdit->text();
|
||||
}
|
||||
|
||||
QSet<int> DlgFilterGames::getGameTypeFilter() const
|
||||
{
|
||||
QSet<int> result;
|
||||
QMapIterator<int, QCheckBox *> i(gameTypeFilterCheckBoxes);
|
||||
while (i.hasNext()) {
|
||||
i.next();
|
||||
if (i.value()->isChecked())
|
||||
result.insert(i.key());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int DlgFilterGames::getMaxPlayersFilterMin() const
|
||||
{
|
||||
return maxPlayersFilterMinSpinBox->value();
|
||||
}
|
||||
|
||||
int DlgFilterGames::getMaxPlayersFilterMax() const
|
||||
{
|
||||
return maxPlayersFilterMaxSpinBox->value();
|
||||
}
|
||||
|
||||
QTime DlgFilterGames::getMaxGameAge() const
|
||||
{
|
||||
int index = maxGameAgeComboBox->currentIndex();
|
||||
if (index < 0 || index >= gameAgeMap.size()) { // index is out of bounds
|
||||
return gamesProxyModel->getMaxGameAge(); // leave the setting unchanged
|
||||
}
|
||||
return gameAgeMap.keys().at(index);
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getShowOnlyIfSpectatorsCanWatch() const
|
||||
{
|
||||
return showOnlyIfSpectatorsCanWatch->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getShowSpectatorPasswordProtected() const
|
||||
{
|
||||
return showSpectatorPasswordProtected->isEnabled() && showSpectatorPasswordProtected->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getShowOnlyIfSpectatorsCanChat() const
|
||||
{
|
||||
return showOnlyIfSpectatorsCanChat->isEnabled() && showOnlyIfSpectatorsCanChat->isChecked();
|
||||
}
|
||||
|
||||
bool DlgFilterGames::getShowOnlyIfSpectatorsCanSeeHands() const
|
||||
{
|
||||
return showOnlyIfSpectatorsCanSeeHands->isEnabled() && showOnlyIfSpectatorsCanSeeHands->isChecked();
|
||||
}
|
||||
89
cockatrice/src/interface/widgets/dialogs/dlg_filter_games.h
Normal file
89
cockatrice/src/interface/widgets/dialogs/dlg_filter_games.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* @file dlg_filter_games.h
|
||||
* @ingroup RoomDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_FILTER_GAMES_H
|
||||
#define DLG_FILTER_GAMES_H
|
||||
|
||||
#include "../interface/widgets/server/games_model.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QMap>
|
||||
#include <QSet>
|
||||
#include <QTime>
|
||||
|
||||
class QCheckBox;
|
||||
class QComboBox;
|
||||
class QGroupBox;
|
||||
class QLineEdit;
|
||||
class QSpinBox;
|
||||
|
||||
class DlgFilterGames : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QGroupBox *generalGroupBox;
|
||||
QCheckBox *hideBuddiesOnlyGames;
|
||||
QCheckBox *hideFullGames;
|
||||
QCheckBox *hideGamesThatStarted;
|
||||
QCheckBox *hidePasswordProtectedGames;
|
||||
QCheckBox *hideIgnoredUserGames;
|
||||
QCheckBox *hideNotBuddyCreatedGames;
|
||||
QCheckBox *hideOpenDecklistGames;
|
||||
QLineEdit *gameNameFilterEdit;
|
||||
QLineEdit *creatorNameFilterEdit;
|
||||
QMap<int, QCheckBox *> gameTypeFilterCheckBoxes;
|
||||
QSpinBox *maxPlayersFilterMinSpinBox;
|
||||
QSpinBox *maxPlayersFilterMaxSpinBox;
|
||||
QComboBox *maxGameAgeComboBox;
|
||||
|
||||
QCheckBox *showOnlyIfSpectatorsCanWatch;
|
||||
QCheckBox *showSpectatorPasswordProtected;
|
||||
QCheckBox *showOnlyIfSpectatorsCanChat;
|
||||
QCheckBox *showOnlyIfSpectatorsCanSeeHands;
|
||||
|
||||
const QMap<int, QString> &allGameTypes;
|
||||
const GamesProxyModel *gamesProxyModel;
|
||||
|
||||
private slots:
|
||||
void actOk();
|
||||
void toggleSpectatorCheckboxEnabledness(bool spectatorsEnabled);
|
||||
|
||||
public:
|
||||
DlgFilterGames(const QMap<int, QString> &_allGameTypes,
|
||||
const GamesProxyModel *_gamesProxyModel,
|
||||
QWidget *parent = nullptr);
|
||||
|
||||
bool getHideFullGames() const;
|
||||
bool getHideGamesThatStarted() const;
|
||||
bool getHidePasswordProtectedGames() const;
|
||||
void setShowPasswordProtectedGames(bool _passwordProtectedGamesHidden);
|
||||
bool getHideBuddiesOnlyGames() const;
|
||||
void setHideBuddiesOnlyGames(bool _hideBuddiesOnlyGames);
|
||||
bool getHideOpenDecklistGames() const;
|
||||
void setHideOpenDecklistGames(bool _hideOpenDecklistGames);
|
||||
bool getHideIgnoredUserGames() const;
|
||||
void setHideIgnoredUserGames(bool _hideIgnoredUserGames);
|
||||
bool getHideNotBuddyCreatedGames() const;
|
||||
QString getGameNameFilter() const;
|
||||
void setGameNameFilter(const QString &_gameNameFilter);
|
||||
QString getCreatorNameFilter() const;
|
||||
void setCreatorNameFilter(const QString &_creatorNameFilter);
|
||||
QSet<int> getGameTypeFilter() const;
|
||||
void setGameTypeFilter(const QSet<int> &_gameTypeFilter);
|
||||
int getMaxPlayersFilterMin() const;
|
||||
int getMaxPlayersFilterMax() const;
|
||||
void setMaxPlayersFilter(int _maxPlayersFilterMin, int _maxPlayersFilterMax);
|
||||
QTime getMaxGameAge() const;
|
||||
const QMap<QTime, QString> gameAgeMap;
|
||||
bool getShowOnlyIfSpectatorsCanWatch() const;
|
||||
bool getShowSpectatorPasswordProtected() const;
|
||||
bool getShowOnlyIfSpectatorsCanChat() const;
|
||||
bool getShowOnlyIfSpectatorsCanSeeHands() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
#include "dlg_forgot_password_challenge.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgForgotPasswordChallenge::DlgForgotPasswordChallenge(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QString lastfphost;
|
||||
QString lastfpport;
|
||||
QString lastfpplayername;
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
lastfphost = servers.getHostname();
|
||||
lastfpport = servers.getPort();
|
||||
lastfpplayername = servers.getPlayerName();
|
||||
|
||||
if (!servers.getFPHostname().isEmpty() && !servers.getFPPort().isEmpty() && !servers.getFPPlayerName().isEmpty()) {
|
||||
lastfphost = servers.getFPHostname();
|
||||
lastfpport = servers.getFPPort();
|
||||
lastfpplayername = servers.getFPPlayerName();
|
||||
}
|
||||
|
||||
if (servers.getFPHostname().isEmpty() && servers.getFPPort().isEmpty() && servers.getFPPlayerName().isEmpty()) {
|
||||
QMessageBox::warning(this, tr("Reset Password Challenge Warning"),
|
||||
tr("A problem has occurred. Please try to request a new password again."));
|
||||
reject();
|
||||
}
|
||||
|
||||
infoLabel =
|
||||
new QLabel(tr("Enter the information of the server and the account you'd like to request a new password for."));
|
||||
infoLabel->setWordWrap(true);
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(lastfphost);
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(lastfpport);
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(lastfpplayername);
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
emailLabel = new QLabel(tr("Email:"));
|
||||
emailEdit = new QLineEdit();
|
||||
emailEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailLabel->setBuddy(emailLabel);
|
||||
|
||||
if (!servers.getFPHostname().isEmpty() && !servers.getFPPort().isEmpty() && !servers.getFPPlayerName().isEmpty()) {
|
||||
hostLabel->hide();
|
||||
hostEdit->hide();
|
||||
portLabel->hide();
|
||||
portEdit->hide();
|
||||
playernameLabel->hide();
|
||||
playernameEdit->hide();
|
||||
}
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(infoLabel, 0, 0, 1, 2);
|
||||
grid->addWidget(hostLabel, 1, 0);
|
||||
grid->addWidget(hostEdit, 1, 1);
|
||||
grid->addWidget(portLabel, 2, 0);
|
||||
grid->addWidget(portEdit, 2, 1);
|
||||
grid->addWidget(playernameLabel, 3, 0);
|
||||
grid->addWidget(playernameEdit, 3, 1);
|
||||
grid->addWidget(emailLabel, 4, 0);
|
||||
grid->addWidget(emailEdit, 4, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgForgotPasswordChallenge::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgForgotPasswordChallenge::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Reset Password Challenge"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
}
|
||||
|
||||
void DlgForgotPasswordChallenge::actOk()
|
||||
{
|
||||
if (emailEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Reset Password Challenge Error"), tr("The email address can't be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
servers.setFPHostName(hostEdit->text());
|
||||
servers.setFPPort(portEdit->text());
|
||||
servers.setFPPlayerName(playernameEdit->text());
|
||||
|
||||
accept();
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file dlg_forgot_password_challenge.h
|
||||
* @ingroup AccountDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_FORGOTPASSWORDCHALLENGE_H
|
||||
#define DLG_FORGOTPASSWORDCHALLENGE_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgForgotPasswordChallenge : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgForgotPasswordChallenge(QWidget *parent = nullptr);
|
||||
QString getHost() const
|
||||
{
|
||||
return hostEdit->text();
|
||||
}
|
||||
int getPort() const
|
||||
{
|
||||
return portEdit->text().toInt();
|
||||
}
|
||||
QString getPlayerName() const
|
||||
{
|
||||
return playernameEdit->text();
|
||||
}
|
||||
QString getEmail() const
|
||||
{
|
||||
return emailEdit->text();
|
||||
}
|
||||
private slots:
|
||||
void actOk();
|
||||
|
||||
private:
|
||||
QLabel *infoLabel, *hostLabel, *portLabel, *playernameLabel, *emailLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit, *emailEdit;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
#include "dlg_forgot_password_request.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgForgotPasswordRequest::DlgForgotPasswordRequest(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QString lastfphost;
|
||||
QString lastfpport;
|
||||
QString lastfpplayername;
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
lastfphost = servers.getHostname();
|
||||
lastfpport = servers.getPort();
|
||||
lastfpplayername = servers.getPlayerName();
|
||||
|
||||
if (!servers.getFPHostname().isEmpty() && !servers.getFPPort().isEmpty() && !servers.getFPPlayerName().isEmpty()) {
|
||||
lastfphost = servers.getFPHostname();
|
||||
lastfpport = servers.getFPPort();
|
||||
lastfpplayername = servers.getFPPlayerName();
|
||||
}
|
||||
|
||||
infoLabel = new QLabel(tr("Enter the information of the server you'd like to request a new password for."));
|
||||
infoLabel->setWordWrap(true);
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(lastfphost);
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(lastfpport);
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(lastfpplayername);
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(infoLabel, 0, 0, 1, 2);
|
||||
grid->addWidget(hostLabel, 1, 0);
|
||||
grid->addWidget(hostEdit, 1, 1);
|
||||
grid->addWidget(portLabel, 2, 0);
|
||||
grid->addWidget(portEdit, 2, 1);
|
||||
grid->addWidget(playernameLabel, 3, 0);
|
||||
grid->addWidget(playernameEdit, 3, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgForgotPasswordRequest::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgForgotPasswordRequest::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Reset Password Request"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
}
|
||||
|
||||
void DlgForgotPasswordRequest::actOk()
|
||||
{
|
||||
if (playernameEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Reset Password Error"), tr("The player name can't be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
servers.setFPHostName(hostEdit->text());
|
||||
servers.setFPPort(portEdit->text());
|
||||
servers.setFPPlayerName(playernameEdit->text());
|
||||
|
||||
accept();
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* @file dlg_forgot_password_request.h
|
||||
* @ingroup AccountDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_FORGOTPASSWORDREQUEST_H
|
||||
#define DLG_FORGOTPASSWORDREQUEST_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgForgotPasswordRequest : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgForgotPasswordRequest(QWidget *parent = nullptr);
|
||||
QString getHost() const
|
||||
{
|
||||
return hostEdit->text();
|
||||
}
|
||||
int getPort() const
|
||||
{
|
||||
return portEdit->text().toInt();
|
||||
}
|
||||
QString getPlayerName() const
|
||||
{
|
||||
return playernameEdit->text();
|
||||
}
|
||||
private slots:
|
||||
void actOk();
|
||||
|
||||
private:
|
||||
QLabel *infoLabel, *hostLabel, *portLabel, *playernameLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
#include "dlg_forgot_password_reset.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgForgotPasswordReset::DlgForgotPasswordReset(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
QString lastfphost;
|
||||
QString lastfpport;
|
||||
QString lastfpplayername;
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
lastfphost = servers.getHostname();
|
||||
lastfpport = servers.getPort();
|
||||
lastfpplayername = servers.getPlayerName();
|
||||
|
||||
if (!servers.getFPHostname().isEmpty() && !servers.getFPPort().isEmpty() && !servers.getFPPlayerName().isEmpty()) {
|
||||
lastfphost = servers.getFPHostname();
|
||||
lastfpport = servers.getFPPort();
|
||||
lastfpplayername = servers.getFPPlayerName();
|
||||
}
|
||||
|
||||
if (servers.getFPHostname().isEmpty() && servers.getFPPort().isEmpty() && servers.getFPPlayerName().isEmpty()) {
|
||||
QMessageBox::warning(this, tr("Reset Password Warning"),
|
||||
tr("A problem has occurred. Please try to request a new password again."));
|
||||
reject();
|
||||
}
|
||||
|
||||
infoLabel = new QLabel(tr("Enter the received token and the new password in order to set your new password."));
|
||||
infoLabel->setWordWrap(true);
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(lastfphost);
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(lastfpport);
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(lastfpplayername);
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
tokenLabel = new QLabel(tr("Token:"));
|
||||
tokenEdit = new QLineEdit();
|
||||
tokenEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
tokenLabel->setBuddy(tokenLabel);
|
||||
|
||||
newpasswordLabel = new QLabel(tr("New Password:"));
|
||||
newpasswordEdit = new QLineEdit();
|
||||
newpasswordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
newpasswordLabel->setBuddy(newpasswordEdit);
|
||||
newpasswordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
newpasswordverifyLabel = new QLabel(tr("New Password:"));
|
||||
newpasswordverifyEdit = new QLineEdit();
|
||||
newpasswordverifyEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
newpasswordverifyLabel->setBuddy(newpasswordEdit);
|
||||
newpasswordverifyEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
if (!servers.getFPHostname().isEmpty() && !servers.getFPPort().isEmpty() && !servers.getFPPlayerName().isEmpty()) {
|
||||
hostLabel->hide();
|
||||
hostEdit->hide();
|
||||
portLabel->hide();
|
||||
portEdit->hide();
|
||||
playernameLabel->hide();
|
||||
playernameEdit->hide();
|
||||
}
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(infoLabel, 0, 0, 1, 2);
|
||||
grid->addWidget(hostLabel, 1, 0);
|
||||
grid->addWidget(hostEdit, 1, 1);
|
||||
grid->addWidget(portLabel, 2, 0);
|
||||
grid->addWidget(portEdit, 2, 1);
|
||||
grid->addWidget(playernameLabel, 3, 0);
|
||||
grid->addWidget(playernameEdit, 3, 1);
|
||||
grid->addWidget(tokenLabel, 4, 0);
|
||||
grid->addWidget(tokenEdit, 4, 1);
|
||||
grid->addWidget(newpasswordLabel, 5, 0);
|
||||
grid->addWidget(newpasswordEdit, 5, 1);
|
||||
grid->addWidget(newpasswordverifyLabel, 6, 0);
|
||||
grid->addWidget(newpasswordverifyEdit, 6, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgForgotPasswordReset::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgForgotPasswordReset::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Reset Password"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
}
|
||||
|
||||
void DlgForgotPasswordReset::actOk()
|
||||
{
|
||||
if (playernameEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Reset Password Error"), tr("The player name can't be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (tokenEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Reset Password Error"), tr("The token can't be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (newpasswordEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Reset Password Error"), tr("The new password can't be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO this stuff should be using qvalidators
|
||||
if (newpasswordEdit->text().length() < 8) {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Your password is too short."));
|
||||
return;
|
||||
} else if (newpasswordEdit->text() != newpasswordverifyEdit->text()) {
|
||||
QMessageBox::critical(this, tr("Reset Password Error"), tr("The passwords do not match."));
|
||||
return;
|
||||
}
|
||||
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
servers.setFPHostName(hostEdit->text());
|
||||
servers.setFPPort(portEdit->text());
|
||||
servers.setFPPlayerName(playernameEdit->text());
|
||||
|
||||
accept();
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* @file dlg_forgot_password_reset.h
|
||||
* @ingroup AccountDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_FORGOTPASSWORDRESET_H
|
||||
#define DLG_FORGOTPASSWORDRESET_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgForgotPasswordReset : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgForgotPasswordReset(QWidget *parent = nullptr);
|
||||
QString getHost() const
|
||||
{
|
||||
return hostEdit->text();
|
||||
}
|
||||
int getPort() const
|
||||
{
|
||||
return portEdit->text().toInt();
|
||||
}
|
||||
QString getPlayerName() const
|
||||
{
|
||||
return playernameEdit->text();
|
||||
}
|
||||
QString getToken() const
|
||||
{
|
||||
return tokenEdit->text();
|
||||
}
|
||||
QString getPassword() const
|
||||
{
|
||||
return newpasswordEdit->text();
|
||||
}
|
||||
private slots:
|
||||
void actOk();
|
||||
|
||||
private:
|
||||
QLabel *infoLabel, *hostLabel, *portLabel, *playernameLabel, *tokenLabel, *newpasswordLabel,
|
||||
*newpasswordverifyLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit, *tokenEdit, *newpasswordEdit, *newpasswordverifyEdit;
|
||||
};
|
||||
|
||||
#endif
|
||||
22
cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp
Normal file
22
cockatrice/src/interface/widgets/dialogs/dlg_load_deck.cpp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
#include "dlg_load_deck.h"
|
||||
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck"))
|
||||
{
|
||||
QString startingDir = SettingsCache::instance().recents().getLatestDeckDirPath();
|
||||
if (startingDir.isEmpty()) {
|
||||
startingDir = SettingsCache::instance().getDeckPath();
|
||||
}
|
||||
|
||||
setDirectory(startingDir);
|
||||
setNameFilters(DeckLoader::FILE_NAME_FILTERS);
|
||||
|
||||
connect(this, &DlgLoadDeck::accepted, this, &DlgLoadDeck::actAccepted);
|
||||
}
|
||||
|
||||
void DlgLoadDeck::actAccepted()
|
||||
{
|
||||
SettingsCache::instance().recents().setLatestDeckDirPath(directory().absolutePath());
|
||||
}
|
||||
27
cockatrice/src/interface/widgets/dialogs/dlg_load_deck.h
Normal file
27
cockatrice/src/interface/widgets/dialogs/dlg_load_deck.h
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
/**
|
||||
* @file dlg_load_deck.h
|
||||
* @ingroup LocalDeckStorageDialogs
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_LOAD_DECK_H
|
||||
#define DLG_LOAD_DECK_H
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
/**
|
||||
* The file dialog for "Load Deck" operations.
|
||||
* Handles remembering the most recently used deck loading directory.
|
||||
*/
|
||||
class DlgLoadDeck : public QFileDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
void actAccepted();
|
||||
|
||||
public:
|
||||
explicit DlgLoadDeck(QWidget *parent = nullptr);
|
||||
};
|
||||
|
||||
#endif // DLG_LOAD_DECK_H
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
#include "dlg_load_deck_from_clipboard.h"
|
||||
|
||||
#include "dlg_settings.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QCheckBox>
|
||||
#include <QClipboard>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QMessageBox>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QTextStream>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
/**
|
||||
* Creates the main layout and connects the signals that are common to all versions of this window
|
||||
*/
|
||||
AbstractDlgDeckTextEdit::AbstractDlgDeckTextEdit(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
contentsEdit = new QPlainTextEdit;
|
||||
|
||||
refreshButton = new QPushButton(tr("&Refresh"));
|
||||
connect(refreshButton, &QPushButton::clicked, this, &AbstractDlgDeckTextEdit::actRefresh);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttonBox->addButton(refreshButton, QDialogButtonBox::ActionRole);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &AbstractDlgDeckTextEdit::actOK);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &AbstractDlgDeckTextEdit::reject);
|
||||
|
||||
loadSetNameAndNumberCheckBox = new QCheckBox(tr("Parse Set Name and Number (if available)"));
|
||||
loadSetNameAndNumberCheckBox->setChecked(true);
|
||||
|
||||
auto *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addWidget(loadSetNameAndNumberCheckBox);
|
||||
buttonLayout->addWidget(buttonBox);
|
||||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(contentsEdit);
|
||||
mainLayout->addLayout(buttonLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
resize(500, 500);
|
||||
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&AbstractDlgDeckTextEdit::refreshShortcuts);
|
||||
refreshShortcuts();
|
||||
}
|
||||
|
||||
void AbstractDlgDeckTextEdit::refreshShortcuts()
|
||||
{
|
||||
refreshButton->setShortcut(
|
||||
SettingsCache::instance().shortcuts().getSingleShortcut("DlgLoadDeckFromClipboard/refreshButton"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Replaces the contents of the contentsEdit with the given text.
|
||||
* @param text The text
|
||||
*/
|
||||
void AbstractDlgDeckTextEdit::setText(const QString &text)
|
||||
{
|
||||
contentsEdit->setPlainText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to load the current contents of the contentsEdit into the DeckLoader
|
||||
*
|
||||
* @param deckLoader The DeckLoader to load the deck into
|
||||
* @return Whether the loading was successful
|
||||
*/
|
||||
bool AbstractDlgDeckTextEdit::loadIntoDeck(DeckLoader *deckLoader) const
|
||||
{
|
||||
QString buffer = contentsEdit->toPlainText();
|
||||
|
||||
if (buffer.contains("<cockatrice_deck version=\"1\">")) {
|
||||
return deckLoader->loadFromString_Native(buffer);
|
||||
}
|
||||
|
||||
QTextStream stream(&buffer);
|
||||
|
||||
if (deckLoader->loadFromStream_Plain(stream, true)) {
|
||||
if (loadSetNameAndNumberCheckBox->isChecked()) {
|
||||
deckLoader->resolveSetNameAndNumberToProviderID();
|
||||
} else {
|
||||
deckLoader->clearSetNamesAndNumbers();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AbstractDlgDeckTextEdit::keyPressEvent(QKeyEvent *event)
|
||||
{
|
||||
if (event->key() == Qt::Key_Return && event->modifiers() & Qt::ControlModifier) {
|
||||
event->accept();
|
||||
actOK();
|
||||
return;
|
||||
}
|
||||
QDialog::keyPressEvent(event);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dialog window for the "Load deck from clipboard" action
|
||||
*
|
||||
* @param parent The parent widget
|
||||
*/
|
||||
DlgLoadDeckFromClipboard::DlgLoadDeckFromClipboard(QWidget *parent) : AbstractDlgDeckTextEdit(parent), deckList(nullptr)
|
||||
{
|
||||
setWindowTitle(tr("Load deck from clipboard"));
|
||||
|
||||
DlgLoadDeckFromClipboard::actRefresh();
|
||||
}
|
||||
|
||||
void DlgLoadDeckFromClipboard::actRefresh()
|
||||
{
|
||||
setText(QApplication::clipboard()->text());
|
||||
}
|
||||
|
||||
void DlgLoadDeckFromClipboard::actOK()
|
||||
{
|
||||
deckList = new DeckLoader;
|
||||
deckList->setParent(this);
|
||||
|
||||
if (loadIntoDeck(deckList)) {
|
||||
accept();
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid deck list."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the dialog window for the "Edit deck in clipboard" action
|
||||
*
|
||||
* @param deckList The existing deck in the deck editor. Copies the instance
|
||||
* @param _annotated Whether to add annotations to the text that is loaded from the deck
|
||||
* @param parent The parent widget
|
||||
*/
|
||||
DlgEditDeckInClipboard::DlgEditDeckInClipboard(const DeckLoader &deckList, bool _annotated, QWidget *parent)
|
||||
: AbstractDlgDeckTextEdit(parent), annotated(_annotated)
|
||||
{
|
||||
setWindowTitle(tr("Edit deck in clipboard"));
|
||||
|
||||
deckLoader = new DeckLoader(deckList);
|
||||
deckLoader->setParent(this);
|
||||
|
||||
DlgEditDeckInClipboard::actRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the contents of the DeckList into a String. Always loads it with addSetNameAndNumber=true
|
||||
* @param deckList The deck to load
|
||||
* @param addComments Whether to add annotations
|
||||
* @return A QString
|
||||
*/
|
||||
static QString deckListToString(const DeckLoader *deckList, bool addComments)
|
||||
{
|
||||
QString buffer;
|
||||
QTextStream stream(&buffer);
|
||||
deckList->saveToStream_Plain(stream, addComments);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
void DlgEditDeckInClipboard::actRefresh()
|
||||
{
|
||||
setText(deckListToString(deckLoader, annotated));
|
||||
}
|
||||
|
||||
void DlgEditDeckInClipboard::actOK()
|
||||
{
|
||||
if (loadIntoDeck(deckLoader)) {
|
||||
accept();
|
||||
} else {
|
||||
QMessageBox::critical(this, tr("Error"), tr("Invalid deck list."));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/**
|
||||
* @file dlg_load_deck_from_clipboard.h
|
||||
* @ingroup LocalDeckStorageDialogs
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_LOAD_DECK_FROM_CLIPBOARD_H
|
||||
#define DLG_LOAD_DECK_FROM_CLIPBOARD_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
|
||||
class DeckLoader;
|
||||
class QPlainTextEdit;
|
||||
class QPushButton;
|
||||
|
||||
/**
|
||||
* Base class for dialog windows for actions that involve loading decks from text input.
|
||||
*/
|
||||
class AbstractDlgDeckTextEdit : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
QPlainTextEdit *contentsEdit;
|
||||
QPushButton *refreshButton;
|
||||
QCheckBox *loadSetNameAndNumberCheckBox;
|
||||
|
||||
private slots:
|
||||
void refreshShortcuts();
|
||||
|
||||
public:
|
||||
explicit AbstractDlgDeckTextEdit(QWidget *parent = nullptr);
|
||||
|
||||
/**
|
||||
* Gets the loaded deck. Only call this method after this dialog window has been successfully exec'd.
|
||||
*
|
||||
* The returned DeckLoader is parented to this object; make sure to take ownership of the DeckLoader if you intend
|
||||
* to use it, since otherwise it will get destroyed once this dlg is destroyed
|
||||
* @return The DeckLoader
|
||||
*/
|
||||
virtual DeckLoader *getDeckList() const = 0;
|
||||
|
||||
protected:
|
||||
void setText(const QString &text);
|
||||
bool loadIntoDeck(DeckLoader *deckLoader) const;
|
||||
void keyPressEvent(QKeyEvent *event) override;
|
||||
|
||||
protected slots:
|
||||
virtual void actOK() = 0;
|
||||
virtual void actRefresh() = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Dialog window for the "Load deck from clipboard" action
|
||||
*/
|
||||
class DlgLoadDeckFromClipboard : public AbstractDlgDeckTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
protected slots:
|
||||
void actOK() override;
|
||||
void actRefresh() override;
|
||||
|
||||
private:
|
||||
DeckLoader *deckList;
|
||||
|
||||
public:
|
||||
explicit DlgLoadDeckFromClipboard(QWidget *parent = nullptr);
|
||||
|
||||
DeckLoader *getDeckList() const override
|
||||
{
|
||||
return deckList;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Dialog window for the "Edit deck in clipboard" action
|
||||
*/
|
||||
class DlgEditDeckInClipboard : public AbstractDlgDeckTextEdit
|
||||
{
|
||||
Q_OBJECT
|
||||
protected slots:
|
||||
void actOK() override;
|
||||
void actRefresh() override;
|
||||
|
||||
private:
|
||||
DeckLoader *deckLoader;
|
||||
bool annotated;
|
||||
|
||||
public:
|
||||
explicit DlgEditDeckInClipboard(const DeckLoader &deckList, bool _annotated, QWidget *parent = nullptr);
|
||||
|
||||
DeckLoader *getDeckList() const override
|
||||
{
|
||||
return deckLoader;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,145 @@
|
|||
#include "dlg_load_deck_from_website.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QClipboard>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QEventLoop>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMessageBox>
|
||||
#include <QNetworkReply>
|
||||
|
||||
DlgLoadDeckFromWebsite::DlgLoadDeckFromWebsite(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
nam = new QNetworkAccessManager(this);
|
||||
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
instructionLabel = new QLabel(this);
|
||||
layout->addWidget(instructionLabel);
|
||||
|
||||
urlEdit = new QLineEdit(this);
|
||||
urlEdit->setText(QApplication::clipboard()->text());
|
||||
|
||||
layout->addWidget(urlEdit);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
|
||||
layout->addWidget(buttonBox);
|
||||
|
||||
if (testValidUrl()) {
|
||||
QMetaObject::invokeMethod(this, "accept", Qt::QueuedConnection);
|
||||
hide();
|
||||
}
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void DlgLoadDeckFromWebsite::retranslateUi()
|
||||
{
|
||||
instructionLabel->setText(tr("Paste a link to a decklist site here to import it.\n(Archidekt, Deckstats, Moxfield, "
|
||||
"and TappedOut are supported.)"));
|
||||
}
|
||||
|
||||
bool DlgLoadDeckFromWebsite::testValidUrl()
|
||||
{
|
||||
ParsedDeckInfo info;
|
||||
return DeckLinkToApiTransformer::parseDeckUrl(urlEdit->text(), info);
|
||||
}
|
||||
|
||||
void DlgLoadDeckFromWebsite::accept()
|
||||
{
|
||||
ParsedDeckInfo info;
|
||||
if (DeckLinkToApiTransformer::parseDeckUrl(urlEdit->text(), info)) {
|
||||
qCInfo(DlgLoadDeckFromWebsiteLog) << info.baseUrl << info.deckID << info.fullUrl;
|
||||
|
||||
auto jsonParser = createParserForProvider(info.provider);
|
||||
if (!jsonParser && info.provider != DeckProvider::Deckstats && info.provider != DeckProvider::TappedOut) {
|
||||
qCWarning(DlgLoadDeckFromWebsiteLog) << "No parser found for provider";
|
||||
QMessageBox::warning(this, tr("Load Deck from Website"),
|
||||
tr("No parser available for this deck provider.\n (Archidekt, Deckstats, Moxfield, "
|
||||
"and TappedOut are supported.)"));
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkRequest request(QUrl(info.fullUrl));
|
||||
QNetworkReply *reply = nam->get(request);
|
||||
|
||||
QEventLoop loop;
|
||||
connect(reply, &QNetworkReply::finished, &loop, &QEventLoop::quit);
|
||||
loop.exec();
|
||||
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qCWarning(DlgLoadDeckFromWebsiteLog) << "Network error:" << reply->errorString();
|
||||
QMessageBox::warning(this, tr("Load Deck from Website"), tr("Network error: %1").arg(reply->errorString()));
|
||||
reply->deleteLater();
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray responseData = reply->readAll();
|
||||
reply->deleteLater();
|
||||
|
||||
// Special handling for Deckstats and TappedOut .txt
|
||||
if (info.provider == DeckProvider::Deckstats || info.provider == DeckProvider::TappedOut) {
|
||||
QString deckText = QString::fromUtf8(responseData);
|
||||
if (deckText.isEmpty()) {
|
||||
qCWarning(DlgLoadDeckFromWebsiteLog) << "Response is empty";
|
||||
QMessageBox::warning(this, tr("Load Deck from Website"), tr("Received empty deck data."));
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
// Parse the plain text deck here
|
||||
DeckLoader *loader = new DeckLoader();
|
||||
QTextStream stream(&deckText);
|
||||
loader->loadFromStream_Plain(stream, false);
|
||||
loader->resolveSetNameAndNumberToProviderID();
|
||||
deck = loader;
|
||||
|
||||
QDialog::accept();
|
||||
return;
|
||||
}
|
||||
|
||||
// Normal JSON parsing for other providers
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument doc = QJsonDocument::fromJson(responseData, &parseError);
|
||||
if (parseError.error != QJsonParseError::NoError) {
|
||||
qCWarning(DlgLoadDeckFromWebsiteLog) << "JSON parse error:" << parseError.errorString();
|
||||
QMessageBox::warning(this, tr("Load Deck from Website"),
|
||||
tr("Failed to parse deck data: %1").arg(parseError.errorString()));
|
||||
QDialog::reject();
|
||||
return;
|
||||
}
|
||||
|
||||
deck = jsonParser->parse(doc.object());
|
||||
QDialog::accept();
|
||||
|
||||
} else {
|
||||
qCInfo(DlgLoadDeckFromWebsiteLog) << "URL not recognized";
|
||||
QMessageBox::warning(this, tr("Load Deck from Website"),
|
||||
tr("The provided URL is not recognized as a valid deck URL.\n"
|
||||
"Valid deck URLs look like this:\n\n"
|
||||
"https://archidekt.com/decks/9999999\n"
|
||||
"https://deckstats.net/decks/99999/9999999-your-deck-name/en\n"
|
||||
"https://moxfield.com/decks/XYZxx-XYZ99Yyy-xyzXzzz\n"
|
||||
"https://tappedout.net/mtg-decks/your-deck-name/"));
|
||||
QDialog::reject();
|
||||
}
|
||||
}
|
||||
|
||||
QSharedPointer<IJsonDeckParser> DlgLoadDeckFromWebsite::createParserForProvider(DeckProvider provider)
|
||||
{
|
||||
switch (provider) {
|
||||
case DeckProvider::Archidekt:
|
||||
return QSharedPointer<IJsonDeckParser>(new ArchidektJsonParser());
|
||||
case DeckProvider::Moxfield:
|
||||
return QSharedPointer<IJsonDeckParser>(new MoxfieldJsonParser());
|
||||
default:
|
||||
return QSharedPointer<IJsonDeckParser>(nullptr);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/**
|
||||
* @file dlg_load_deck_from_website.h
|
||||
* @ingroup RemoteDeckStorageDialogs
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_LOAD_DECK_FROM_WEBSITE_H
|
||||
#define DLG_LOAD_DECK_FROM_WEBSITE_H
|
||||
|
||||
#include "../client/network/parsers/deck_link_to_api_transformer.h"
|
||||
#include "../client/network/parsers/interface_json_deck_parser.h"
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DlgLoadDeckFromWebsiteLog, "dlg_load_deck_from_website");
|
||||
|
||||
class DlgLoadDeckFromWebsite : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgLoadDeckFromWebsite(QWidget *parent);
|
||||
void retranslateUi();
|
||||
bool testValidUrl();
|
||||
DeckLoader *deck;
|
||||
|
||||
DeckLoader *getDeck()
|
||||
{
|
||||
return deck;
|
||||
}
|
||||
|
||||
private:
|
||||
QNetworkAccessManager *nam;
|
||||
QVBoxLayout *layout;
|
||||
QLabel *instructionLabel;
|
||||
QLineEdit *urlEdit;
|
||||
|
||||
public slots:
|
||||
void accept() override;
|
||||
QSharedPointer<IJsonDeckParser> createParserForProvider(DeckProvider provider);
|
||||
};
|
||||
|
||||
#endif // DLG_LOAD_DECK_FROM_WEBSITE_H
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#include "dlg_load_remote_deck.h"
|
||||
|
||||
#include "../interface/widgets/server/remote/remote_decklist_tree_widget.h"
|
||||
#include "../main.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
DlgLoadRemoteDeck::DlgLoadRemoteDeck(AbstractClient *_client, QWidget *parent) : QDialog(parent), client(_client)
|
||||
{
|
||||
dirView = new RemoteDeckList_TreeWidget(client);
|
||||
dirView->refreshTree();
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgLoadRemoteDeck::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgLoadRemoteDeck::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addWidget(dirView);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Load deck"));
|
||||
setMinimumWidth(sizeHint().width());
|
||||
resize(400, 600);
|
||||
|
||||
connect(dirView->selectionModel(), &QItemSelectionModel::currentChanged, this,
|
||||
&DlgLoadRemoteDeck::currentItemChanged);
|
||||
}
|
||||
|
||||
void DlgLoadRemoteDeck::currentItemChanged(const QModelIndex ¤t, const QModelIndex & /*previous*/)
|
||||
{
|
||||
buttonBox->button(QDialogButtonBox::Ok)
|
||||
->setEnabled(dynamic_cast<RemoteDeckList_TreeModel::FileNode *>(dirView->getNode(current)));
|
||||
}
|
||||
|
||||
int DlgLoadRemoteDeck::getDeckId() const
|
||||
{
|
||||
return dynamic_cast<RemoteDeckList_TreeModel::FileNode *>(
|
||||
dirView->getNode(dirView->selectionModel()->currentIndex()))
|
||||
->getId();
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/**
|
||||
* @file dlg_load_remote_deck.h
|
||||
* @ingroup RemoteDeckStorageDialogs
|
||||
* @ingroup Lobby
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_STARTGAME_H
|
||||
#define DLG_STARTGAME_H
|
||||
|
||||
#include <QDialog>
|
||||
|
||||
class RemoteDeckList_TreeWidget;
|
||||
class QModelIndex;
|
||||
class AbstractClient;
|
||||
class QPushButton;
|
||||
class QDialogButtonBox;
|
||||
|
||||
class DlgLoadRemoteDeck : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
AbstractClient *client;
|
||||
RemoteDeckList_TreeWidget *dirView;
|
||||
QDialogButtonBox *buttonBox;
|
||||
private slots:
|
||||
void currentItemChanged(const QModelIndex ¤t, const QModelIndex &previous);
|
||||
|
||||
public:
|
||||
explicit DlgLoadRemoteDeck(AbstractClient *_client, QWidget *parent = nullptr);
|
||||
int getDeckId() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
470
cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.cpp
Normal file
470
cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.cpp
Normal file
|
|
@ -0,0 +1,470 @@
|
|||
#include "dlg_manage_sets.h"
|
||||
|
||||
#include "../interface/card_picture_loader/card_picture_loader.h"
|
||||
#include "../interface/widgets/utility/custom_line_edit.h"
|
||||
#include "../main.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QGroupBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QItemSelection>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QPushButton>
|
||||
#include <QToolBar>
|
||||
#include <QTreeView>
|
||||
#include <algorithm>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/card/card_database/model/card_set/card_sets_model.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
#define SORT_RESET -1
|
||||
|
||||
WndSets::WndSets(QWidget *parent) : QMainWindow(parent)
|
||||
{
|
||||
setOrderIsSorted = false;
|
||||
|
||||
// left toolbar
|
||||
setsEditToolBar = new QToolBar;
|
||||
setsEditToolBar->setOrientation(Qt::Vertical);
|
||||
setsEditToolBar->setIconSize(QSize(24, 24));
|
||||
setsEditToolBar->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
|
||||
aTop = new QAction(QString(), this);
|
||||
aTop->setIcon(QPixmap("theme:icons/arrow_top_green"));
|
||||
aTop->setToolTip(tr("Move selected set to the top"));
|
||||
aTop->setEnabled(false);
|
||||
connect(aTop, &QAction::triggered, this, &WndSets::actTop);
|
||||
setsEditToolBar->addAction(aTop);
|
||||
|
||||
aUp = new QAction(QString(), this);
|
||||
aUp->setIcon(QPixmap("theme:icons/arrow_up_green"));
|
||||
aUp->setToolTip(tr("Move selected set up"));
|
||||
aUp->setEnabled(false);
|
||||
connect(aUp, &QAction::triggered, this, &WndSets::actUp);
|
||||
setsEditToolBar->addAction(aUp);
|
||||
|
||||
aDown = new QAction(QString(), this);
|
||||
aDown->setIcon(QPixmap("theme:icons/arrow_down_green"));
|
||||
aDown->setToolTip(tr("Move selected set down"));
|
||||
aDown->setEnabled(false);
|
||||
connect(aDown, &QAction::triggered, this, &WndSets::actDown);
|
||||
setsEditToolBar->addAction(aDown);
|
||||
|
||||
aBottom = new QAction(QString(), this);
|
||||
aBottom->setIcon(QPixmap("theme:icons/arrow_bottom_green"));
|
||||
aBottom->setToolTip(tr("Move selected set to the bottom"));
|
||||
aBottom->setEnabled(false);
|
||||
connect(aBottom, &QAction::triggered, this, &WndSets::actBottom);
|
||||
setsEditToolBar->addAction(aBottom);
|
||||
|
||||
// search field
|
||||
searchField = new LineEditUnfocusable;
|
||||
searchField->setObjectName("searchEdit");
|
||||
searchField->setPlaceholderText(tr("Search by set name, code, or type"));
|
||||
searchField->addAction(QPixmap("theme:icons/search"), LineEditUnfocusable::LeadingPosition);
|
||||
searchField->setClearButtonEnabled(true);
|
||||
setFocusProxy(searchField);
|
||||
|
||||
defaultSortButton = new QPushButton(tr("Default order"));
|
||||
defaultSortButton->setToolTip(tr("Restore original art priority order"));
|
||||
|
||||
connect(defaultSortButton, &QPushButton::clicked, this, &WndSets::actRestoreOriginalOrder);
|
||||
|
||||
filterBox = new QHBoxLayout;
|
||||
filterBox->addWidget(searchField);
|
||||
filterBox->addWidget(defaultSortButton);
|
||||
|
||||
// view
|
||||
model = new SetsModel(CardDatabaseManager::getInstance(), this);
|
||||
displayModel = new SetsDisplayModel(this);
|
||||
displayModel->setSourceModel(model);
|
||||
displayModel->setDynamicSortFilter(false);
|
||||
view = new QTreeView;
|
||||
view->setModel(displayModel);
|
||||
|
||||
view->setAlternatingRowColors(true);
|
||||
view->setUniformRowHeights(true);
|
||||
view->setAllColumnsShowFocus(true);
|
||||
view->setSortingEnabled(true);
|
||||
view->setSelectionBehavior(QAbstractItemView::SelectRows);
|
||||
view->setSelectionMode(QAbstractItemView::ExtendedSelection);
|
||||
|
||||
view->setDragEnabled(true);
|
||||
view->setAcceptDrops(true);
|
||||
view->setDropIndicatorShown(true);
|
||||
view->setDragDropMode(QAbstractItemView::InternalMove);
|
||||
|
||||
view->sortByColumn(SetsModel::SortKeyCol, Qt::AscendingOrder);
|
||||
view->setColumnHidden(SetsModel::SortKeyCol, true);
|
||||
view->setColumnHidden(SetsModel::IsKnownCol, true);
|
||||
view->setColumnHidden(SetsModel::PriorityCol, true);
|
||||
view->setRootIsDecorated(false);
|
||||
|
||||
connect(view->header(), &QHeaderView::sectionClicked, this, &WndSets::actSort);
|
||||
|
||||
// bottom buttons
|
||||
enableAllButton = new QPushButton(tr("Enable all sets"));
|
||||
disableAllButton = new QPushButton(tr("Disable all sets"));
|
||||
enableSomeButton = new QPushButton(tr("Enable selected set(s)"));
|
||||
disableSomeButton = new QPushButton(tr("Disable selected set(s)"));
|
||||
|
||||
connect(enableAllButton, &QPushButton::clicked, this, &WndSets::actEnableAll);
|
||||
connect(disableAllButton, &QPushButton::clicked, this, &WndSets::actDisableAll);
|
||||
connect(enableSomeButton, &QPushButton::clicked, this, &WndSets::actEnableSome);
|
||||
connect(disableSomeButton, &QPushButton::clicked, this, &WndSets::actDisableSome);
|
||||
connect(view->selectionModel(), &QItemSelectionModel::selectionChanged, this, &WndSets::actToggleButtons);
|
||||
connect(searchField, &LineEditUnfocusable::textChanged, displayModel,
|
||||
qOverload<const QString &>(&SetsDisplayModel::setFilterRegularExpression));
|
||||
connect(view->header(), &QHeaderView::sortIndicatorChanged, this, &WndSets::actDisableSortButtons);
|
||||
connect(searchField, &LineEditUnfocusable::textChanged, this, &WndSets::actDisableResetButton);
|
||||
|
||||
labNotes = new QLabel;
|
||||
labNotes->setWordWrap(true);
|
||||
labNotes->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
labNotes->setOpenExternalLinks(true);
|
||||
labNotes->setText(tr("Use CTRL+A to select all sets in the view.") + "<br><b>" + tr("Deck Editor") + ":</b> " +
|
||||
tr("Only cards in enabled sets will appear in the card list of the deck editor.") + "<br><b>" +
|
||||
tr("Card Art") + ":</b> " + tr("Image priority is decided in the following order:") + "<br>" +
|
||||
tr("first the CUSTOM Folder (%1), then the Enabled Sets in this dialog (Top to Bottom)",
|
||||
"%1 is a link to the wiki")
|
||||
.arg("<a href='https://github.com/Cockatrice/Cockatrice/wiki/Custom-Cards-%26-Sets"
|
||||
"#to-add-custom-art-for-cards-the-easiest-way-is-to-use-the-custom-folder'>" +
|
||||
tr("How to use custom card art") + "</a>"));
|
||||
|
||||
QGridLayout *hintsGrid = new QGridLayout;
|
||||
hintsGrid->addWidget(labNotes, 0, 0);
|
||||
hintsGroupBox = new QGroupBox(tr("Hints"));
|
||||
hintsGroupBox->setLayout(hintsGrid);
|
||||
|
||||
sortWarning = new QGroupBox(tr("Note"));
|
||||
QGridLayout *sortWarningLayout = new QGridLayout;
|
||||
sortWarningText = new QLabel;
|
||||
sortWarningText->setWordWrap(true);
|
||||
sortWarningText->setText(tr("Sorting by column allows you to find a set while not changing set priority.") + " " +
|
||||
tr("To enable ordering again, click the column header until this message disappears."));
|
||||
sortWarningLayout->addWidget(sortWarningText, 0, 0, 1, 2);
|
||||
sortWarningButton = new QPushButton;
|
||||
sortWarningButton->setText(tr("Use the current sorting as the set priority instead"));
|
||||
sortWarningButton->setToolTip(tr("Sorts the set priority using the same column"));
|
||||
sortWarningButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
connect(sortWarningButton, &QPushButton::released, this, &WndSets::actIgnoreWarning);
|
||||
sortWarningLayout->addWidget(sortWarningButton, 1, 0);
|
||||
sortWarning->setLayout(sortWarningLayout);
|
||||
sortWarning->setVisible(false);
|
||||
|
||||
includeRebalancedCards = SettingsCache::instance().getIncludeRebalancedCards();
|
||||
QCheckBox *includeRebalancedCardsCheckBox =
|
||||
new QCheckBox(tr("Include cards rebalanced for Alchemy [requires restart]"));
|
||||
includeRebalancedCardsCheckBox->setChecked(includeRebalancedCards);
|
||||
connect(includeRebalancedCardsCheckBox, &QAbstractButton::toggled, this, &WndSets::includeRebalancedCardsChanged);
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &WndSets::actSave);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &WndSets::actRestore);
|
||||
|
||||
mainLayout = new QGridLayout;
|
||||
mainLayout->addLayout(filterBox, 0, 1, 1, 2);
|
||||
mainLayout->addWidget(setsEditToolBar, 1, 0, 4, 1);
|
||||
mainLayout->addWidget(view, 1, 1, 1, 2);
|
||||
mainLayout->addWidget(enableAllButton, 2, 1);
|
||||
mainLayout->addWidget(disableAllButton, 2, 2);
|
||||
mainLayout->addWidget(enableSomeButton, 2, 1);
|
||||
mainLayout->addWidget(disableSomeButton, 2, 2);
|
||||
mainLayout->addWidget(sortWarning, 3, 1, 1, 2);
|
||||
mainLayout->addWidget(includeRebalancedCardsCheckBox, 4, 1, 1, 2);
|
||||
mainLayout->addWidget(hintsGroupBox, 5, 1, 1, 2);
|
||||
mainLayout->addWidget(buttonBox, 6, 1, 1, 2);
|
||||
mainLayout->setColumnStretch(1, 1);
|
||||
mainLayout->setColumnStretch(2, 1);
|
||||
|
||||
enableSomeButton->hide();
|
||||
disableSomeButton->hide();
|
||||
|
||||
QWidget *centralWidget = new QWidget;
|
||||
centralWidget->setLayout(mainLayout);
|
||||
setCentralWidget(centralWidget);
|
||||
|
||||
setWindowTitle(tr("Manage sets"));
|
||||
setMinimumSize(800, 500);
|
||||
auto &geometry = SettingsCache::instance().getSetsDialogGeometry();
|
||||
if (!geometry.isEmpty()) {
|
||||
restoreGeometry(geometry);
|
||||
}
|
||||
auto &headerState = SettingsCache::instance().layouts().getSetsDialogHeaderState();
|
||||
if (!headerState.isEmpty()) {
|
||||
view->header()->restoreState(headerState);
|
||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
||||
} else {
|
||||
view->header()->resizeSections(QHeaderView::ResizeToContents);
|
||||
}
|
||||
connect(view->header(), &QHeaderView::geometriesChanged, this, &WndSets::saveHeaderState);
|
||||
}
|
||||
|
||||
WndSets::~WndSets()
|
||||
{
|
||||
}
|
||||
|
||||
void WndSets::closeEvent(QCloseEvent * /*ev*/)
|
||||
{
|
||||
SettingsCache::instance().setSetsDialogGeometry(saveGeometry());
|
||||
}
|
||||
|
||||
void WndSets::saveHeaderState()
|
||||
{
|
||||
SettingsCache::instance().layouts().setSetsDialogHeaderState(view->header()->saveState());
|
||||
}
|
||||
|
||||
void WndSets::rebuildMainLayout(int actionToTake)
|
||||
{
|
||||
if (mainLayout == nullptr)
|
||||
return;
|
||||
|
||||
switch (actionToTake) {
|
||||
case NO_SETS_SELECTED:
|
||||
enableAllButton->show();
|
||||
disableAllButton->show();
|
||||
enableSomeButton->hide();
|
||||
disableSomeButton->hide();
|
||||
break;
|
||||
|
||||
case SOME_SETS_SELECTED:
|
||||
enableAllButton->hide();
|
||||
disableAllButton->hide();
|
||||
enableSomeButton->show();
|
||||
disableSomeButton->show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void WndSets::includeRebalancedCardsChanged(bool _includeRebalancedCards)
|
||||
{
|
||||
includeRebalancedCards = _includeRebalancedCards;
|
||||
}
|
||||
|
||||
void WndSets::actSave()
|
||||
{
|
||||
model->save(CardDatabaseManager::getInstance());
|
||||
SettingsCache::instance().setIncludeRebalancedCards(includeRebalancedCards);
|
||||
CardPictureLoader::clearPixmapCache();
|
||||
close();
|
||||
}
|
||||
|
||||
void WndSets::actRestore()
|
||||
{
|
||||
model->restore(CardDatabaseManager::getInstance());
|
||||
close();
|
||||
}
|
||||
|
||||
void WndSets::actRestoreOriginalOrder()
|
||||
{
|
||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
||||
model->restoreOriginalOrder();
|
||||
sortWarning->setVisible(false);
|
||||
}
|
||||
|
||||
void WndSets::actDisableResetButton(const QString &filterString)
|
||||
{
|
||||
if (filterString.isEmpty()) {
|
||||
defaultSortButton->setEnabled(true);
|
||||
} else {
|
||||
defaultSortButton->setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
void WndSets::actSort(int index)
|
||||
{
|
||||
if (sortIndex != index) {
|
||||
view->sortByColumn(index, Qt::AscendingOrder);
|
||||
sortOrder = Qt::AscendingOrder;
|
||||
sortIndex = index;
|
||||
sortWarning->setVisible(true);
|
||||
} else {
|
||||
if (sortOrder == Qt::AscendingOrder) {
|
||||
view->sortByColumn(index, Qt::DescendingOrder);
|
||||
sortOrder = Qt::DescendingOrder;
|
||||
sortIndex = index;
|
||||
sortWarning->setVisible(true);
|
||||
} else {
|
||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
||||
sortIndex = -1;
|
||||
sortWarning->setVisible(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WndSets::actIgnoreWarning()
|
||||
{
|
||||
if (sortIndex < 0) {
|
||||
return;
|
||||
}
|
||||
model->sort(sortIndex, sortOrder);
|
||||
view->header()->setSortIndicator(SORT_RESET, Qt::DescendingOrder);
|
||||
sortIndex = -1;
|
||||
sortWarning->setVisible(false);
|
||||
}
|
||||
|
||||
void WndSets::actDisableSortButtons(int index)
|
||||
{
|
||||
if (index != SORT_RESET) {
|
||||
view->setDragEnabled(false);
|
||||
setOrderIsSorted = true;
|
||||
} else {
|
||||
setOrderIsSorted = false;
|
||||
view->setDragEnabled(true);
|
||||
}
|
||||
if (!view->selectionModel()->selection().empty()) {
|
||||
view->scrollTo(view->selectionModel()->selectedRows().first());
|
||||
}
|
||||
actToggleButtons(view->selectionModel()->selection(), QItemSelection());
|
||||
}
|
||||
|
||||
void WndSets::actToggleButtons(const QItemSelection &selected, const QItemSelection &)
|
||||
{
|
||||
bool emptySelection = selected.empty();
|
||||
aTop->setDisabled(emptySelection || setOrderIsSorted);
|
||||
aUp->setDisabled(emptySelection || setOrderIsSorted);
|
||||
aDown->setDisabled(emptySelection || setOrderIsSorted);
|
||||
aBottom->setDisabled(emptySelection || setOrderIsSorted);
|
||||
|
||||
int rows = view->selectionModel()->selectedRows().size();
|
||||
rebuildMainLayout((rows > 1) ? SOME_SETS_SELECTED : NO_SETS_SELECTED);
|
||||
}
|
||||
|
||||
void WndSets::selectRows(QSet<int> rows)
|
||||
{
|
||||
for (auto i : rows) {
|
||||
QModelIndex idx = model->index(i, 0);
|
||||
view->selectionModel()->select(idx, QItemSelectionModel::Select | QItemSelectionModel::Rows);
|
||||
view->scrollTo(idx, QAbstractItemView::EnsureVisible);
|
||||
}
|
||||
}
|
||||
|
||||
void WndSets::actEnableAll()
|
||||
{
|
||||
model->toggleAll(true);
|
||||
}
|
||||
|
||||
void WndSets::actDisableAll()
|
||||
{
|
||||
model->toggleAll(false);
|
||||
}
|
||||
|
||||
void WndSets::actEnableSome()
|
||||
{
|
||||
QModelIndexList rows = view->selectionModel()->selectedRows();
|
||||
|
||||
for (auto i : rows) {
|
||||
model->toggleRow(displayModel->mapToSource(i).row(), true);
|
||||
}
|
||||
}
|
||||
|
||||
void WndSets::actDisableSome()
|
||||
{
|
||||
QModelIndexList rows = view->selectionModel()->selectedRows();
|
||||
|
||||
for (auto i : rows) {
|
||||
model->toggleRow(displayModel->mapToSource(i).row(), false);
|
||||
}
|
||||
}
|
||||
|
||||
void WndSets::actUp()
|
||||
{
|
||||
QModelIndexList rows = view->selectionModel()->selectedRows();
|
||||
std::sort(rows.begin(), rows.end(), std::less<QModelIndex>());
|
||||
QSet<int> newRows;
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
for (auto i : rows) {
|
||||
if (i.row() <= 0)
|
||||
continue;
|
||||
int oldRow = displayModel->mapToSource(i).row();
|
||||
int newRow = i.row() - 1;
|
||||
|
||||
model->swapRows(oldRow, displayModel->mapToSource(displayModel->index(newRow, 0)).row());
|
||||
newRows.insert(newRow);
|
||||
}
|
||||
|
||||
selectRows(newRows);
|
||||
}
|
||||
|
||||
void WndSets::actDown()
|
||||
{
|
||||
QModelIndexList rows = view->selectionModel()->selectedRows();
|
||||
// QModelIndex only implements operator<, so we can't use std::greater
|
||||
std::sort(rows.begin(), rows.end(), [](const QModelIndex &a, const QModelIndex &b) { return b < a; });
|
||||
QSet<int> newRows;
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
for (auto i : rows) {
|
||||
if (i.row() >= displayModel->rowCount() - 1)
|
||||
continue;
|
||||
int oldRow = displayModel->mapToSource(i).row();
|
||||
int newRow = i.row() + 1;
|
||||
|
||||
model->swapRows(oldRow, displayModel->mapToSource(displayModel->index(newRow, 0)).row());
|
||||
newRows.insert(newRow);
|
||||
}
|
||||
|
||||
selectRows(newRows);
|
||||
}
|
||||
|
||||
void WndSets::actTop()
|
||||
{
|
||||
QModelIndexList rows = view->selectionModel()->selectedRows();
|
||||
std::sort(rows.begin(), rows.end(), std::less<QModelIndex>());
|
||||
QSet<int> newRows;
|
||||
int newRow = 0;
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < rows.length(); i++) {
|
||||
int oldRow = displayModel->mapToSource(rows.at(i)).row();
|
||||
|
||||
if (oldRow <= 0) {
|
||||
newRow++;
|
||||
continue;
|
||||
}
|
||||
|
||||
newRows.insert(newRow);
|
||||
model->swapRows(oldRow, newRow++);
|
||||
}
|
||||
|
||||
selectRows(newRows);
|
||||
}
|
||||
|
||||
void WndSets::actBottom()
|
||||
{
|
||||
QModelIndexList rows = view->selectionModel()->selectedRows();
|
||||
// QModelIndex only implements operator<, so we can't use std::greater
|
||||
std::sort(rows.begin(), rows.end(), [](const QModelIndex &a, const QModelIndex &b) { return b < a; });
|
||||
QSet<int> newRows;
|
||||
int newRow = model->rowCount() - 1;
|
||||
|
||||
if (rows.empty())
|
||||
return;
|
||||
|
||||
for (int i = 0; i < rows.length(); i++) {
|
||||
int oldRow = displayModel->mapToSource(rows.at(i)).row();
|
||||
|
||||
if (oldRow >= newRow) {
|
||||
newRow--;
|
||||
continue;
|
||||
}
|
||||
|
||||
newRows.insert(newRow);
|
||||
model->swapRows(oldRow, newRow--);
|
||||
}
|
||||
|
||||
selectRows(newRows);
|
||||
}
|
||||
86
cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.h
Normal file
86
cockatrice/src/interface/widgets/dialogs/dlg_manage_sets.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/**
|
||||
* @file dlg_manage_sets.h
|
||||
* @ingroup Dialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_MANAGE_SETS_H
|
||||
#define DLG_MANAGE_SETS_H
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QMainWindow>
|
||||
#include <QSet>
|
||||
|
||||
class CardDatabase;
|
||||
class LineEditUnfocusable;
|
||||
class QGroupBox;
|
||||
class QItemSelection;
|
||||
class QPushButton;
|
||||
class QTreeView;
|
||||
class SetsDisplayModel;
|
||||
class SetsModel;
|
||||
class SetsProxyModel;
|
||||
|
||||
class WndSets : public QMainWindow
|
||||
{
|
||||
Q_OBJECT
|
||||
private:
|
||||
SetsModel *model;
|
||||
SetsDisplayModel *displayModel;
|
||||
QGroupBox *hintsGroupBox;
|
||||
QTreeView *view;
|
||||
QPushButton *toggleAllButton, *toggleSelectedButton;
|
||||
QPushButton *enableAllButton, *disableAllButton, *enableSomeButton, *disableSomeButton;
|
||||
QPushButton *defaultSortButton;
|
||||
QAction *aUp, *aDown, *aBottom, *aTop;
|
||||
QToolBar *setsEditToolBar;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QLabel *labNotes, *searchLabel;
|
||||
QGroupBox *sortWarning;
|
||||
QLabel *sortWarningText;
|
||||
QPushButton *sortWarningButton;
|
||||
LineEditUnfocusable *searchField;
|
||||
QGridLayout *mainLayout;
|
||||
QHBoxLayout *filterBox;
|
||||
int sortIndex;
|
||||
Qt::SortOrder sortOrder;
|
||||
void closeEvent(QCloseEvent *ev) override;
|
||||
void saveHeaderState();
|
||||
void rebuildMainLayout(int actionToTake);
|
||||
bool setOrderIsSorted;
|
||||
bool includeRebalancedCards;
|
||||
enum
|
||||
{
|
||||
NO_SETS_SELECTED,
|
||||
SOME_SETS_SELECTED
|
||||
};
|
||||
|
||||
public:
|
||||
explicit WndSets(QWidget *parent = nullptr);
|
||||
~WndSets() override;
|
||||
|
||||
protected:
|
||||
void selectRows(QSet<int> rows);
|
||||
private slots:
|
||||
void actEnableAll();
|
||||
void actDisableAll();
|
||||
void actEnableSome();
|
||||
void actDisableSome();
|
||||
void actSave();
|
||||
void actRestore();
|
||||
void actUp();
|
||||
void actDown();
|
||||
void actTop();
|
||||
void actBottom();
|
||||
void actToggleButtons(const QItemSelection &selected, const QItemSelection &deselected);
|
||||
void actDisableSortButtons(int index);
|
||||
void actRestoreOriginalOrder();
|
||||
void actDisableResetButton(const QString &filterText);
|
||||
void actSort(int index);
|
||||
void actIgnoreWarning();
|
||||
void includeRebalancedCardsChanged(bool _includeRebalancedCardsChanged);
|
||||
};
|
||||
|
||||
#endif
|
||||
378
cockatrice/src/interface/widgets/dialogs/dlg_register.cpp
Normal file
378
cockatrice/src/interface/widgets/dialogs/dlg_register.cpp
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
#include "dlg_register.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <libcockatrice/protocol/pb/serverinfo_user.pb.h>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/trice_limits.h>
|
||||
|
||||
DlgRegister::DlgRegister(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
ServersSettings &servers = SettingsCache::instance().servers();
|
||||
infoLabel = new QLabel(tr("Enter your information and the information of the server you'd like to register to.\n"
|
||||
"Your email will be used to verify your account."));
|
||||
infoLabel->setWordWrap(true);
|
||||
|
||||
hostLabel = new QLabel(tr("&Host:"));
|
||||
hostEdit = new QLineEdit(servers.getHostname());
|
||||
hostEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
hostLabel->setBuddy(hostEdit);
|
||||
|
||||
portLabel = new QLabel(tr("&Port:"));
|
||||
portEdit = new QLineEdit(servers.getPort());
|
||||
portEdit->setValidator(new QIntValidator(0, 0xffff, portEdit));
|
||||
portLabel->setBuddy(portEdit);
|
||||
|
||||
playernameLabel = new QLabel(tr("Player &name:"));
|
||||
playernameEdit = new QLineEdit(servers.getPlayerName());
|
||||
playernameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
playernameLabel->setBuddy(playernameEdit);
|
||||
|
||||
passwordLabel = new QLabel(tr("P&assword:"));
|
||||
passwordEdit = new QLineEdit();
|
||||
passwordEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordLabel->setBuddy(passwordEdit);
|
||||
passwordEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
passwordConfirmationLabel = new QLabel(tr("Password (again):"));
|
||||
passwordConfirmationEdit = new QLineEdit();
|
||||
passwordConfirmationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
passwordConfirmationLabel->setBuddy(passwordConfirmationEdit);
|
||||
passwordConfirmationEdit->setEchoMode(QLineEdit::Password);
|
||||
|
||||
emailLabel = new QLabel(tr("Email:"));
|
||||
emailEdit = new QLineEdit();
|
||||
emailEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailLabel->setBuddy(emailEdit);
|
||||
|
||||
emailConfirmationLabel = new QLabel(tr("Email (again):"));
|
||||
emailConfirmationEdit = new QLineEdit();
|
||||
emailConfirmationEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
emailConfirmationLabel->setBuddy(emailConfirmationEdit);
|
||||
|
||||
countryLabel = new QLabel(tr("Country:"));
|
||||
countryEdit = new QComboBox();
|
||||
countryLabel->setBuddy(countryEdit);
|
||||
countryEdit->insertItem(0, tr("Undefined"));
|
||||
countryEdit->addItem(QPixmap("theme:countries/ad"), "ad");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ae"), "ae");
|
||||
countryEdit->addItem(QPixmap("theme:countries/af"), "af");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ag"), "ag");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ai"), "ai");
|
||||
countryEdit->addItem(QPixmap("theme:countries/al"), "al");
|
||||
countryEdit->addItem(QPixmap("theme:countries/am"), "am");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ao"), "ao");
|
||||
countryEdit->addItem(QPixmap("theme:countries/aq"), "aq");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ar"), "ar");
|
||||
countryEdit->addItem(QPixmap("theme:countries/as"), "as");
|
||||
countryEdit->addItem(QPixmap("theme:countries/at"), "at");
|
||||
countryEdit->addItem(QPixmap("theme:countries/au"), "au");
|
||||
countryEdit->addItem(QPixmap("theme:countries/aw"), "aw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ax"), "ax");
|
||||
countryEdit->addItem(QPixmap("theme:countries/az"), "az");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ba"), "ba");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bb"), "bb");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bd"), "bd");
|
||||
countryEdit->addItem(QPixmap("theme:countries/be"), "be");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bf"), "bf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bg"), "bg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bh"), "bh");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bi"), "bi");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bj"), "bj");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bl"), "bl");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bm"), "bm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bn"), "bn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bo"), "bo");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bq"), "bq");
|
||||
countryEdit->addItem(QPixmap("theme:countries/br"), "br");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bs"), "bs");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bt"), "bt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bv"), "bv");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bw"), "bw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/by"), "by");
|
||||
countryEdit->addItem(QPixmap("theme:countries/bz"), "bz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ca"), "ca");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cc"), "cc");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cd"), "cd");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cf"), "cf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cg"), "cg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ch"), "ch");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ci"), "ci");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ck"), "ck");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cl"), "cl");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cm"), "cm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cn"), "cn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/co"), "co");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cr"), "cr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cu"), "cu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cv"), "cv");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cw"), "cw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cx"), "cx");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cy"), "cy");
|
||||
countryEdit->addItem(QPixmap("theme:countries/cz"), "cz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/de"), "de");
|
||||
countryEdit->addItem(QPixmap("theme:countries/dj"), "dj");
|
||||
countryEdit->addItem(QPixmap("theme:countries/dk"), "dk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/dm"), "dm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/do"), "do");
|
||||
countryEdit->addItem(QPixmap("theme:countries/dz"), "dz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ec"), "ec");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ee"), "ee");
|
||||
countryEdit->addItem(QPixmap("theme:countries/eg"), "eg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/eh"), "eh");
|
||||
countryEdit->addItem(QPixmap("theme:countries/er"), "er");
|
||||
countryEdit->addItem(QPixmap("theme:countries/es"), "es");
|
||||
countryEdit->addItem(QPixmap("theme:countries/et"), "et");
|
||||
countryEdit->addItem(QPixmap("theme:countries/eu"), "eu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fi"), "fi");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fj"), "fj");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fk"), "fk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fm"), "fm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fo"), "fo");
|
||||
countryEdit->addItem(QPixmap("theme:countries/fr"), "fr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ga"), "ga");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gb"), "gb");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gd"), "gd");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ge"), "ge");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gf"), "gf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gg"), "gg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gh"), "gh");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gi"), "gi");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gl"), "gl");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gm"), "gm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gn"), "gn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gp"), "gp");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gq"), "gq");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gr"), "gr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gs"), "gs");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gt"), "gt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gu"), "gu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gw"), "gw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/gy"), "gy");
|
||||
countryEdit->addItem(QPixmap("theme:countries/hk"), "hk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/hm"), "hm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/hn"), "hn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/hr"), "hr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ht"), "ht");
|
||||
countryEdit->addItem(QPixmap("theme:countries/hu"), "hu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/id"), "id");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ie"), "ie");
|
||||
countryEdit->addItem(QPixmap("theme:countries/il"), "il");
|
||||
countryEdit->addItem(QPixmap("theme:countries/im"), "im");
|
||||
countryEdit->addItem(QPixmap("theme:countries/in"), "in");
|
||||
countryEdit->addItem(QPixmap("theme:countries/io"), "io");
|
||||
countryEdit->addItem(QPixmap("theme:countries/iq"), "iq");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ir"), "ir");
|
||||
countryEdit->addItem(QPixmap("theme:countries/is"), "is");
|
||||
countryEdit->addItem(QPixmap("theme:countries/it"), "it");
|
||||
countryEdit->addItem(QPixmap("theme:countries/je"), "je");
|
||||
countryEdit->addItem(QPixmap("theme:countries/jm"), "jm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/jo"), "jo");
|
||||
countryEdit->addItem(QPixmap("theme:countries/jp"), "jp");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ke"), "ke");
|
||||
countryEdit->addItem(QPixmap("theme:countries/kg"), "kg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/kh"), "kh");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ki"), "ki");
|
||||
countryEdit->addItem(QPixmap("theme:countries/km"), "km");
|
||||
countryEdit->addItem(QPixmap("theme:countries/kn"), "kn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/kp"), "kp");
|
||||
countryEdit->addItem(QPixmap("theme:countries/kr"), "kr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/kw"), "kw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ky"), "ky");
|
||||
countryEdit->addItem(QPixmap("theme:countries/kz"), "kz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/la"), "la");
|
||||
countryEdit->addItem(QPixmap("theme:countries/lb"), "lb");
|
||||
countryEdit->addItem(QPixmap("theme:countries/lc"), "lc");
|
||||
countryEdit->addItem(QPixmap("theme:countries/li"), "li");
|
||||
countryEdit->addItem(QPixmap("theme:countries/lk"), "lk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/lr"), "lr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ls"), "ls");
|
||||
countryEdit->addItem(QPixmap("theme:countries/lt"), "lt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/lu"), "lu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/lv"), "lv");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ly"), "ly");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ma"), "ma");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mc"), "mc");
|
||||
countryEdit->addItem(QPixmap("theme:countries/md"), "md");
|
||||
countryEdit->addItem(QPixmap("theme:countries/me"), "me");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mf"), "mf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mg"), "mg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mh"), "mh");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mk"), "mk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ml"), "ml");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mm"), "mm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mn"), "mn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mo"), "mo");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mp"), "mp");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mq"), "mq");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mr"), "mr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ms"), "ms");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mt"), "mt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mu"), "mu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mv"), "mv");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mw"), "mw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mx"), "mx");
|
||||
countryEdit->addItem(QPixmap("theme:countries/my"), "my");
|
||||
countryEdit->addItem(QPixmap("theme:countries/mz"), "mz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/na"), "na");
|
||||
countryEdit->addItem(QPixmap("theme:countries/nc"), "nc");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ne"), "ne");
|
||||
countryEdit->addItem(QPixmap("theme:countries/nf"), "nf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ng"), "ng");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ni"), "ni");
|
||||
countryEdit->addItem(QPixmap("theme:countries/nl"), "nl");
|
||||
countryEdit->addItem(QPixmap("theme:countries/no"), "no");
|
||||
countryEdit->addItem(QPixmap("theme:countries/np"), "np");
|
||||
countryEdit->addItem(QPixmap("theme:countries/nr"), "nr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/nu"), "nu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/nz"), "nz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/om"), "om");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pa"), "pa");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pe"), "pe");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pf"), "pf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pg"), "pg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ph"), "ph");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pk"), "pk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pl"), "pl");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pm"), "pm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pn"), "pn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pr"), "pr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ps"), "ps");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pt"), "pt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/pw"), "pw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/py"), "py");
|
||||
countryEdit->addItem(QPixmap("theme:countries/qa"), "qa");
|
||||
countryEdit->addItem(QPixmap("theme:countries/re"), "re");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ro"), "ro");
|
||||
countryEdit->addItem(QPixmap("theme:countries/rs"), "rs");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ru"), "ru");
|
||||
countryEdit->addItem(QPixmap("theme:countries/rw"), "rw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sa"), "sa");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sb"), "sb");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sc"), "sc");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sd"), "sd");
|
||||
countryEdit->addItem(QPixmap("theme:countries/se"), "se");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sg"), "sg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sh"), "sh");
|
||||
countryEdit->addItem(QPixmap("theme:countries/si"), "si");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sj"), "sj");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sk"), "sk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sl"), "sl");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sm"), "sm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sn"), "sn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/so"), "so");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sr"), "sr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ss"), "ss");
|
||||
countryEdit->addItem(QPixmap("theme:countries/st"), "st");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sv"), "sv");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sx"), "sx");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sy"), "sy");
|
||||
countryEdit->addItem(QPixmap("theme:countries/sz"), "sz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tc"), "tc");
|
||||
countryEdit->addItem(QPixmap("theme:countries/td"), "td");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tf"), "tf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tg"), "tg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/th"), "th");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tj"), "tj");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tk"), "tk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tl"), "tl");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tm"), "tm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tn"), "tn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/to"), "to");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tr"), "tr");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tt"), "tt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tv"), "tv");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tw"), "tw");
|
||||
countryEdit->addItem(QPixmap("theme:countries/tz"), "tz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ua"), "ua");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ug"), "ug");
|
||||
countryEdit->addItem(QPixmap("theme:countries/um"), "um");
|
||||
countryEdit->addItem(QPixmap("theme:countries/us"), "us");
|
||||
countryEdit->addItem(QPixmap("theme:countries/uy"), "uy");
|
||||
countryEdit->addItem(QPixmap("theme:countries/uz"), "uz");
|
||||
countryEdit->addItem(QPixmap("theme:countries/va"), "va");
|
||||
countryEdit->addItem(QPixmap("theme:countries/vc"), "vc");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ve"), "ve");
|
||||
countryEdit->addItem(QPixmap("theme:countries/vg"), "vg");
|
||||
countryEdit->addItem(QPixmap("theme:countries/vi"), "vi");
|
||||
countryEdit->addItem(QPixmap("theme:countries/vn"), "vn");
|
||||
countryEdit->addItem(QPixmap("theme:countries/vu"), "vu");
|
||||
countryEdit->addItem(QPixmap("theme:countries/wf"), "wf");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ws"), "ws");
|
||||
countryEdit->addItem(QPixmap("theme:countries/xk"), "xk");
|
||||
countryEdit->addItem(QPixmap("theme:countries/ye"), "ye");
|
||||
countryEdit->addItem(QPixmap("theme:countries/yt"), "yt");
|
||||
countryEdit->addItem(QPixmap("theme:countries/za"), "za");
|
||||
countryEdit->addItem(QPixmap("theme:countries/zm"), "zm");
|
||||
countryEdit->addItem(QPixmap("theme:countries/zw"), "zw");
|
||||
countryEdit->setCurrentIndex(0);
|
||||
QStringList countries = SettingsCache::instance().getCountries();
|
||||
for (const QString &c : countries)
|
||||
countryEdit->addItem(QPixmap("theme:countries/" + c.toLower()), c);
|
||||
|
||||
realnameLabel = new QLabel(tr("Real name:"));
|
||||
realnameEdit = new QLineEdit();
|
||||
realnameEdit->setMaxLength(MAX_NAME_LENGTH);
|
||||
realnameLabel->setBuddy(realnameEdit);
|
||||
|
||||
QGridLayout *grid = new QGridLayout;
|
||||
grid->addWidget(infoLabel, 0, 0, 1, 2);
|
||||
grid->addWidget(hostLabel, 1, 0);
|
||||
grid->addWidget(hostEdit, 1, 1);
|
||||
grid->addWidget(portLabel, 2, 0);
|
||||
grid->addWidget(portEdit, 2, 1);
|
||||
grid->addWidget(playernameLabel, 3, 0);
|
||||
grid->addWidget(playernameEdit, 3, 1);
|
||||
grid->addWidget(passwordLabel, 4, 0);
|
||||
grid->addWidget(passwordEdit, 4, 1);
|
||||
grid->addWidget(passwordConfirmationLabel, 5, 0);
|
||||
grid->addWidget(passwordConfirmationEdit, 5, 1);
|
||||
grid->addWidget(emailLabel, 6, 0);
|
||||
grid->addWidget(emailEdit, 6, 1);
|
||||
grid->addWidget(emailConfirmationLabel, 7, 0);
|
||||
grid->addWidget(emailConfirmationEdit, 7, 1);
|
||||
grid->addWidget(countryLabel, 9, 0);
|
||||
grid->addWidget(countryEdit, 9, 1);
|
||||
grid->addWidget(realnameLabel, 10, 0);
|
||||
grid->addWidget(realnameEdit, 10, 1);
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgRegister::actOk);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &DlgRegister::reject);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(grid);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Register to server"));
|
||||
setFixedHeight(sizeHint().height());
|
||||
setMinimumWidth(300);
|
||||
}
|
||||
|
||||
void DlgRegister::actOk()
|
||||
{
|
||||
// TODO this stuff should be using qvalidators
|
||||
if (passwordEdit->text().length() < 8) {
|
||||
QMessageBox::critical(this, tr("Registration Warning"), tr("Your password is too short."));
|
||||
return;
|
||||
} else if (passwordEdit->text() != passwordConfirmationEdit->text()) {
|
||||
QMessageBox::critical(this, tr("Registration Warning"), tr("Your passwords do not match, please try again."));
|
||||
return;
|
||||
} else if (emailConfirmationEdit->text() != emailEdit->text()) {
|
||||
QMessageBox::critical(this, tr("Registration Warning"),
|
||||
tr("Your email addresses do not match, please try again."));
|
||||
return;
|
||||
}
|
||||
if (playernameEdit->text().isEmpty()) {
|
||||
QMessageBox::critical(this, tr("Registration Warning"), tr("The player name can't be empty."));
|
||||
return;
|
||||
}
|
||||
|
||||
accept();
|
||||
}
|
||||
62
cockatrice/src/interface/widgets/dialogs/dlg_register.h
Normal file
62
cockatrice/src/interface/widgets/dialogs/dlg_register.h
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* @file dlg_register.h
|
||||
* @ingroup AccountDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_REGISTER_H
|
||||
#define DLG_REGISTER_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QLineEdit>
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
|
||||
class DlgRegister : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgRegister(QWidget *parent = nullptr);
|
||||
QString getHost() const
|
||||
{
|
||||
return hostEdit->text();
|
||||
}
|
||||
int getPort() const
|
||||
{
|
||||
return portEdit->text().toInt();
|
||||
}
|
||||
QString getPlayerName() const
|
||||
{
|
||||
return playernameEdit->text();
|
||||
}
|
||||
QString getPassword() const
|
||||
{
|
||||
return passwordEdit->text();
|
||||
}
|
||||
QString getEmail() const
|
||||
{
|
||||
return emailEdit->text();
|
||||
}
|
||||
QString getCountry() const
|
||||
{
|
||||
return countryEdit->currentIndex() == 0 ? "" : countryEdit->currentText();
|
||||
}
|
||||
QString getRealName() const
|
||||
{
|
||||
return realnameEdit->text();
|
||||
}
|
||||
private slots:
|
||||
void actOk();
|
||||
|
||||
private:
|
||||
QLabel *infoLabel, *hostLabel, *portLabel, *playernameLabel, *passwordLabel, *passwordConfirmationLabel,
|
||||
*emailLabel, *emailConfirmationLabel, *countryLabel, *realnameLabel;
|
||||
QLineEdit *hostEdit, *portEdit, *playernameEdit, *passwordEdit, *passwordConfirmationEdit, *emailEdit,
|
||||
*emailConfirmationEdit, *realnameEdit;
|
||||
QComboBox *countryEdit;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,642 @@
|
|||
#include "dlg_select_set_for_cards.h"
|
||||
|
||||
#include "../interface/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../interface/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "dlg_select_set_for_cards.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QMimeData>
|
||||
#include <QPainter>
|
||||
#include <QPushButton>
|
||||
#include <QScrollBar>
|
||||
#include <QSplitter>
|
||||
#include <QVBoxLayout>
|
||||
#include <algorithm>
|
||||
#include <libcockatrice/card/card_database/card_database_manager.h>
|
||||
#include <libcockatrice/deck_list/deck_loader.h>
|
||||
#include <qdrag.h>
|
||||
#include <qevent.h>
|
||||
|
||||
DlgSelectSetForCards::DlgSelectSetForCards(QWidget *parent, DeckListModel *_model) : QDialog(parent), model(_model)
|
||||
{
|
||||
setMinimumSize(500, 500);
|
||||
setAcceptDrops(true);
|
||||
|
||||
instructionLabel = new QLabel(this);
|
||||
instructionLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
|
||||
QVBoxLayout *mainLayout = new QVBoxLayout(this);
|
||||
setLayout(mainLayout);
|
||||
|
||||
// Main vertical splitter
|
||||
QSplitter *splitter = new QSplitter(Qt::Vertical, this);
|
||||
|
||||
// Top scroll area
|
||||
scrollArea = new QScrollArea(this);
|
||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
|
||||
listContainer = new QWidget(scrollArea);
|
||||
listLayout = new QVBoxLayout(listContainer);
|
||||
listContainer->setLayout(listLayout);
|
||||
scrollArea->setWidget(listContainer);
|
||||
|
||||
// Bottom horizontal splitter
|
||||
QSplitter *bottomSplitter = new QSplitter(Qt::Horizontal, this);
|
||||
|
||||
// Left container
|
||||
QWidget *leftContainer = new QWidget(this);
|
||||
QVBoxLayout *leftLayout = new QVBoxLayout(leftContainer);
|
||||
leftLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
uneditedCardsLabel = new QLabel(this);
|
||||
uneditedCardsArea = new QScrollArea(this);
|
||||
uneditedCardsArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
uneditedCardsArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
uneditedCardsArea->setWidgetResizable(true);
|
||||
|
||||
uneditedCardsFlowWidget =
|
||||
new FlowWidget(uneditedCardsArea, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||
uneditedCardsArea->setWidget(uneditedCardsFlowWidget);
|
||||
|
||||
leftLayout->addWidget(uneditedCardsLabel);
|
||||
leftLayout->addWidget(uneditedCardsArea);
|
||||
leftContainer->setLayout(leftLayout);
|
||||
|
||||
// Right container
|
||||
QWidget *rightContainer = new QWidget(this);
|
||||
QVBoxLayout *rightLayout = new QVBoxLayout(rightContainer);
|
||||
rightLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
||||
modifiedCardsLabel = new QLabel(this);
|
||||
modifiedCardsArea = new QScrollArea(this);
|
||||
modifiedCardsArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
modifiedCardsArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
modifiedCardsArea->setWidgetResizable(true);
|
||||
|
||||
modifiedCardsFlowWidget =
|
||||
new FlowWidget(modifiedCardsArea, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAsNeeded);
|
||||
modifiedCardsArea->setWidget(modifiedCardsFlowWidget);
|
||||
|
||||
rightLayout->addWidget(modifiedCardsLabel);
|
||||
rightLayout->addWidget(modifiedCardsArea);
|
||||
rightContainer->setLayout(rightLayout);
|
||||
|
||||
// Add left and right containers to the bottom splitter
|
||||
bottomSplitter->addWidget(leftContainer);
|
||||
bottomSplitter->addWidget(rightContainer);
|
||||
|
||||
// Add widgets to the main splitter
|
||||
splitter->addWidget(scrollArea);
|
||||
splitter->addWidget(bottomSplitter);
|
||||
|
||||
cardsForSets = getCardsForSets();
|
||||
|
||||
sortSetsByCount();
|
||||
updateCardLists();
|
||||
|
||||
QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
connect(buttonBox, SIGNAL(accepted()), this, SLOT(actOK()));
|
||||
connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||
|
||||
clearButton = new QPushButton(buttonBox);
|
||||
connect(clearButton, &QPushButton::clicked, this, &DlgSelectSetForCards::actClear);
|
||||
|
||||
setAllToPreferredButton = new QPushButton(buttonBox);
|
||||
connect(setAllToPreferredButton, &QPushButton::clicked, this, &DlgSelectSetForCards::actSetAllToPreferred);
|
||||
|
||||
buttonBox->addButton(clearButton, QDialogButtonBox::ActionRole);
|
||||
buttonBox->addButton(setAllToPreferredButton, QDialogButtonBox::ActionRole);
|
||||
|
||||
// Set stretch factors
|
||||
splitter->setStretchFactor(0, 6); // Scroll area gets more space
|
||||
splitter->setStretchFactor(1, 2); // Bottom part gets less space
|
||||
splitter->setStretchFactor(2, 1); // Buttons take minimal space
|
||||
|
||||
bottomSplitter->setStretchFactor(0, 1); // Left and right equally split
|
||||
bottomSplitter->setStretchFactor(1, 1);
|
||||
|
||||
connect(this, &DlgSelectSetForCards::orderChanged, this, &DlgSelectSetForCards::updateLayoutOrder);
|
||||
connect(this, &DlgSelectSetForCards::widgetOrderChanged, this, &DlgSelectSetForCards::updateCardLists);
|
||||
|
||||
mainLayout->addWidget(instructionLabel);
|
||||
mainLayout->addWidget(splitter);
|
||||
mainLayout->addWidget(buttonBox);
|
||||
|
||||
retranslateUi();
|
||||
setWindowFlags(Qt::Window);
|
||||
showMaximized();
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::retranslateUi()
|
||||
{
|
||||
uneditedCardsLabel->setText(tr("Unmodified Cards:"));
|
||||
modifiedCardsLabel->setText(tr("Modified Cards:"));
|
||||
instructionLabel->setText(tr("Check Sets to enable them. Drag-and-Drop to reorder them and change their "
|
||||
"priority. Cards will use the printing of the highest priority enabled set."));
|
||||
clearButton->setText(tr("Clear all set information"));
|
||||
setAllToPreferredButton->setText(tr("Set all to preferred"));
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::actOK()
|
||||
{
|
||||
QMap<QString, QStringList> modifiedSetsAndCardsMap = getModifiedCards();
|
||||
for (QString modifiedSet : modifiedSetsAndCardsMap.keys()) {
|
||||
for (QString card : modifiedSetsAndCardsMap.value(modifiedSet)) {
|
||||
QModelIndex find_card = model->findCard(card, DECK_ZONE_MAIN);
|
||||
if (!find_card.isValid()) {
|
||||
continue;
|
||||
}
|
||||
model->removeRow(find_card.row(), find_card.parent());
|
||||
CardInfoPtr cardInfo = CardDatabaseManager::query()->getCardInfo(card);
|
||||
PrintingInfo printing = CardDatabaseManager::query()->getSpecificPrinting(card, modifiedSet, "");
|
||||
model->addCard(ExactCard(cardInfo, printing), DECK_ZONE_MAIN);
|
||||
}
|
||||
}
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::actClear()
|
||||
{
|
||||
model->getDeckList()->clearSetNamesAndNumbers();
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::actSetAllToPreferred()
|
||||
{
|
||||
model->getDeckList()->clearSetNamesAndNumbers();
|
||||
model->getDeckList()->setProviderIdToPreferredPrinting();
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::sortSetsByCount()
|
||||
{
|
||||
QMap<QString, int> setsForCards = getSetsForCards();
|
||||
|
||||
// Convert map to a sortable list
|
||||
QVector<QPair<QString, int>> setList;
|
||||
for (auto it = setsForCards.begin(); it != setsForCards.end(); ++it) {
|
||||
setList.append(qMakePair(it.key(), it.value()));
|
||||
}
|
||||
|
||||
// Sort in descending order of count
|
||||
std::sort(setList.begin(), setList.end(),
|
||||
[](const QPair<QString, int> &a, const QPair<QString, int> &b) { return a.second > b.second; });
|
||||
|
||||
// Clear existing entries
|
||||
qDeleteAll(setEntries);
|
||||
setEntries.clear();
|
||||
|
||||
// Populate with sorted entries
|
||||
for (const auto &entry : setList) {
|
||||
SetEntryWidget *widget = new SetEntryWidget(this, entry.first, entry.second);
|
||||
listLayout->addWidget(widget);
|
||||
setEntries.insert(entry.first, widget);
|
||||
}
|
||||
}
|
||||
|
||||
QMap<QString, int> DlgSelectSetForCards::getSetsForCards()
|
||||
{
|
||||
QMap<QString, int> setCounts;
|
||||
if (!model)
|
||||
return setCounts;
|
||||
|
||||
DeckList *decklist = model->getDeckList();
|
||||
if (!decklist)
|
||||
return setCounts;
|
||||
|
||||
InnerDecklistNode *listRoot = decklist->getRoot();
|
||||
if (!listRoot)
|
||||
return setCounts;
|
||||
|
||||
for (auto *i : *listRoot) {
|
||||
auto *countCurrentZone = dynamic_cast<InnerDecklistNode *>(i);
|
||||
if (!countCurrentZone)
|
||||
continue;
|
||||
|
||||
for (auto *cardNode : *countCurrentZone) {
|
||||
auto *currentCard = dynamic_cast<DecklistCardNode *>(cardNode);
|
||||
if (!currentCard)
|
||||
continue;
|
||||
|
||||
CardInfoPtr infoPtr = CardDatabaseManager::query()->getCardInfo(currentCard->getName());
|
||||
if (!infoPtr)
|
||||
continue;
|
||||
|
||||
SetToPrintingsMap setMap = infoPtr->getSets();
|
||||
for (auto &setName : setMap.keys()) {
|
||||
setCounts[setName]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
return setCounts;
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::updateCardLists()
|
||||
{
|
||||
for (SetEntryWidget *entryWidget : entry_widgets) {
|
||||
entryWidget->populateCardList();
|
||||
if (entryWidget->expanded) {
|
||||
entryWidget->updateCardDisplayWidgets();
|
||||
}
|
||||
entryWidget->checkVisibility();
|
||||
}
|
||||
|
||||
uneditedCardsFlowWidget->clearLayout();
|
||||
modifiedCardsFlowWidget->clearLayout();
|
||||
|
||||
// Map from set name to a set of selected cards in that set
|
||||
QMap<QString, QSet<QString>> selectedCardsBySet;
|
||||
for (SetEntryWidget *entryWidget : entry_widgets) {
|
||||
if (entryWidget->isChecked()) {
|
||||
QStringList cardsInSet = entryWidget->getAllCardsForSet();
|
||||
QSet<QString> cardSet = QSet<QString>(cardsInSet.begin(), cardsInSet.end()); // Convert list to set
|
||||
selectedCardsBySet.insert(entryWidget->setName, cardSet);
|
||||
}
|
||||
}
|
||||
|
||||
DeckList *decklist = model->getDeckList();
|
||||
if (!decklist)
|
||||
return;
|
||||
|
||||
InnerDecklistNode *listRoot = decklist->getRoot();
|
||||
if (!listRoot)
|
||||
return;
|
||||
|
||||
for (auto *i : *listRoot) {
|
||||
auto *countCurrentZone = dynamic_cast<InnerDecklistNode *>(i);
|
||||
if (!countCurrentZone)
|
||||
continue;
|
||||
|
||||
for (auto *cardNode : *countCurrentZone) {
|
||||
auto *currentCard = dynamic_cast<DecklistCardNode *>(cardNode);
|
||||
if (!currentCard)
|
||||
continue;
|
||||
|
||||
bool found = false;
|
||||
QString foundSetName;
|
||||
|
||||
// Check across all sets if the card is present
|
||||
for (auto it = selectedCardsBySet.begin(); it != selectedCardsBySet.end(); ++it) {
|
||||
if (it.value().contains(currentCard->getName())) {
|
||||
found = true;
|
||||
foundSetName = it.key(); // Store the set name where it was found
|
||||
break; // Stop at the first match
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
// The card was not in any selected set
|
||||
ExactCard card = CardDatabaseManager::query()->getCard({currentCard->getName()});
|
||||
CardInfoPictureWidget *picture_widget = new CardInfoPictureWidget(uneditedCardsFlowWidget);
|
||||
picture_widget->setCard(card);
|
||||
uneditedCardsFlowWidget->addWidget(picture_widget);
|
||||
} else {
|
||||
ExactCard card = CardDatabaseManager::query()->getCard(
|
||||
{currentCard->getName(), CardDatabaseManager::getInstance()
|
||||
->query()
|
||||
->getSpecificPrinting(currentCard->getName(), foundSetName, "")
|
||||
.getUuid()});
|
||||
CardInfoPictureWidget *picture_widget = new CardInfoPictureWidget(modifiedCardsFlowWidget);
|
||||
picture_widget->setCard(card);
|
||||
modifiedCardsFlowWidget->addWidget(picture_widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (event->mimeData()->hasFormat("application/x-setentrywidget")) {
|
||||
// Highlight the drop target area
|
||||
event->acceptProposedAction();
|
||||
// Optionally, change cursor to indicate a valid drop area
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::dropEvent(QDropEvent *event)
|
||||
{
|
||||
QByteArray itemData = event->mimeData()->data("application/x-setentrywidget");
|
||||
QString draggedSetName = QString::fromUtf8(itemData);
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
QPoint adjustedPos = event->position().toPoint() + QPoint(0, scrollArea->verticalScrollBar()->value());
|
||||
#else
|
||||
QPoint adjustedPos = event->pos() + QPoint(0, scrollArea->verticalScrollBar()->value());
|
||||
#endif
|
||||
int dropIndex = -1;
|
||||
for (int i = 0; i < listLayout->count(); ++i) {
|
||||
QWidget *widget = listLayout->itemAt(i)->widget();
|
||||
if (widget && widget->geometry().contains(adjustedPos)) {
|
||||
dropIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dropIndex != -1) {
|
||||
// Find the dragged widget and move it to the new position
|
||||
SetEntryWidget *draggedWidget = setEntries.value(draggedSetName, nullptr);
|
||||
if (draggedWidget) {
|
||||
listLayout->removeWidget(draggedWidget);
|
||||
listLayout->insertWidget(dropIndex, draggedWidget);
|
||||
}
|
||||
}
|
||||
|
||||
event->acceptProposedAction();
|
||||
// Reset cursor after drop
|
||||
unsetCursor();
|
||||
|
||||
// We need to execute this AFTER the current event-cycle so we use a timer.
|
||||
QTimer::singleShot(10, this, [this]() { emit orderChanged(); });
|
||||
}
|
||||
|
||||
QMap<QString, QStringList> DlgSelectSetForCards::getCardsForSets()
|
||||
{
|
||||
QMap<QString, QStringList> setCards;
|
||||
if (!model)
|
||||
return setCards;
|
||||
|
||||
DeckList *decklist = model->getDeckList();
|
||||
if (!decklist)
|
||||
return setCards;
|
||||
|
||||
InnerDecklistNode *listRoot = decklist->getRoot();
|
||||
if (!listRoot)
|
||||
return setCards;
|
||||
|
||||
for (auto *i : *listRoot) {
|
||||
auto *countCurrentZone = dynamic_cast<InnerDecklistNode *>(i);
|
||||
if (!countCurrentZone)
|
||||
continue;
|
||||
|
||||
for (auto *cardNode : *countCurrentZone) {
|
||||
auto *currentCard = dynamic_cast<DecklistCardNode *>(cardNode);
|
||||
if (!currentCard)
|
||||
continue;
|
||||
|
||||
CardInfoPtr infoPtr = CardDatabaseManager::query()->getCardInfo(currentCard->getName());
|
||||
if (!infoPtr)
|
||||
continue;
|
||||
|
||||
SetToPrintingsMap setMap = infoPtr->getSets();
|
||||
for (auto it = setMap.begin(); it != setMap.end(); ++it) {
|
||||
setCards[it.key()].append(currentCard->getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
return setCards;
|
||||
}
|
||||
|
||||
QMap<QString, QStringList> DlgSelectSetForCards::getModifiedCards()
|
||||
{
|
||||
QMap<QString, QStringList> modifiedCards;
|
||||
for (int i = 0; i < listLayout->count(); ++i) {
|
||||
QWidget *widget = listLayout->itemAt(i)->widget();
|
||||
if (auto entry = qobject_cast<SetEntryWidget *>(widget)) {
|
||||
if (entry->isChecked()) {
|
||||
QStringList cardsInSet = entry->getAllCardsForSet();
|
||||
|
||||
for (QString cardInSet : cardsInSet) {
|
||||
bool alreadyContained = false;
|
||||
for (QString key : modifiedCards.keys()) {
|
||||
if (modifiedCards[key].contains(cardInSet)) {
|
||||
alreadyContained = true;
|
||||
}
|
||||
}
|
||||
if (!alreadyContained) {
|
||||
modifiedCards[entry->setName].append(cardInSet);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return modifiedCards;
|
||||
}
|
||||
|
||||
void DlgSelectSetForCards::updateLayoutOrder()
|
||||
{
|
||||
entry_widgets.clear();
|
||||
for (int i = 0; i < listLayout->count(); ++i) {
|
||||
QWidget *widget = listLayout->itemAt(i)->widget();
|
||||
if (auto entry = qobject_cast<SetEntryWidget *>(widget)) {
|
||||
entry_widgets.append(entry);
|
||||
}
|
||||
}
|
||||
|
||||
emit widgetOrderChanged();
|
||||
}
|
||||
|
||||
SetEntryWidget::SetEntryWidget(DlgSelectSetForCards *_parent, const QString &_setName, int count)
|
||||
: QWidget(_parent), parent(_parent), setName(_setName), expanded(false)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
QHBoxLayout *headerLayout = new QHBoxLayout();
|
||||
CardSetPtr set = CardDatabaseManager::getInstance()->getSet(setName);
|
||||
checkBox = new QCheckBox("(" + set->getShortName() + ") - " + set->getLongName(), this);
|
||||
connect(checkBox, &QCheckBox::toggled, parent, &DlgSelectSetForCards::updateLayoutOrder);
|
||||
expandButton = new QPushButton("+", this);
|
||||
countLabel = new QLabel(QString::number(count), this);
|
||||
|
||||
connect(expandButton, &QPushButton::clicked, this, &SetEntryWidget::toggleExpansion);
|
||||
|
||||
headerLayout->addWidget(checkBox);
|
||||
headerLayout->addWidget(countLabel);
|
||||
headerLayout->addWidget(expandButton);
|
||||
layout->addLayout(headerLayout);
|
||||
|
||||
possibleCardsLabel = new QLabel(this);
|
||||
possibleCardsLabel->setText("Unselected cards in set:");
|
||||
possibleCardsLabel->hide();
|
||||
|
||||
cardListContainer = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
|
||||
cardListContainer->hide();
|
||||
|
||||
alreadySelectedCardsLabel = new QLabel(this);
|
||||
alreadySelectedCardsLabel->setText("Cards in set already selected in higher priority set:");
|
||||
alreadySelectedCardsLabel->hide();
|
||||
|
||||
alreadySelectedCardListContainer =
|
||||
new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
|
||||
alreadySelectedCardListContainer->hide();
|
||||
|
||||
layout->addWidget(possibleCardsLabel);
|
||||
layout->addWidget(cardListContainer);
|
||||
layout->addWidget(alreadySelectedCardsLabel);
|
||||
layout->addWidget(alreadySelectedCardListContainer);
|
||||
setAttribute(Qt::WA_DeleteOnClose, false);
|
||||
setAttribute(Qt::WA_StyledBackground, true);
|
||||
}
|
||||
|
||||
void SetEntryWidget::mousePressEvent(QMouseEvent *event)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
// Create a drag object and set up mime data
|
||||
QDrag *drag = new QDrag(this);
|
||||
QMimeData *mimeData = new QMimeData;
|
||||
|
||||
// Set the mime data to store the dragged set's name
|
||||
mimeData->setData("application/x-setentrywidget", setName.toUtf8());
|
||||
drag->setMimeData(mimeData);
|
||||
|
||||
// Create a "ghost" pixmap to represent the widget during dragging
|
||||
QPixmap pixmap = this->grab();
|
||||
|
||||
// Ensure pixmap has a transparent background
|
||||
QImage image = pixmap.toImage();
|
||||
for (int y = 0; y < image.height(); ++y) {
|
||||
for (int x = 0; x < image.width(); ++x) {
|
||||
if (image.pixel(x, y) == Qt::transparent) {
|
||||
image.setPixel(x, y, QColor(0, 0, 0, 0).rgba()); // Set transparency where needed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pixmap = QPixmap::fromImage(image); // Convert back to pixmap after transparency manipulation
|
||||
|
||||
// Set the pixmap for the drag object
|
||||
drag->setPixmap(pixmap);
|
||||
|
||||
// Optionally adjust the pixmap position offset to align with the cursor
|
||||
drag->setHotSpot(event->pos());
|
||||
|
||||
drag->exec(Qt::MoveAction);
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
|
||||
void SetEntryWidget::enterEvent(QEnterEvent *event)
|
||||
#else
|
||||
void SetEntryWidget::enterEvent(QEvent *event)
|
||||
#endif
|
||||
{
|
||||
QWidget::enterEvent(event); // Call the base class handler
|
||||
// Highlight the widget by changing the background color only for the widget itself
|
||||
setStyleSheet("SetEntryWidget { background: gray; }");
|
||||
|
||||
// Change cursor to open hand
|
||||
setCursor(Qt::OpenHandCursor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
void SetEntryWidget::leaveEvent(QEvent *event)
|
||||
{
|
||||
QWidget::leaveEvent(event); // Call the base class handler
|
||||
// Reset the background color only for the widget itself
|
||||
setStyleSheet("SetEntryWidget { background: none; }");
|
||||
|
||||
// Reset cursor to default
|
||||
setCursor(Qt::ArrowCursor);
|
||||
repaint();
|
||||
}
|
||||
|
||||
void SetEntryWidget::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
// Check if the mime data is of the correct type
|
||||
if (event->mimeData()->hasFormat("application/x-setentrywidget")) {
|
||||
setCursor(Qt::ClosedHandCursor); // Hand cursor to indicate move
|
||||
// Get the current position of the widget being dragged
|
||||
|
||||
// For now, we will just highlight the widget when dragged.
|
||||
QPainter painter(this);
|
||||
QColor highlightColor(255, 255, 255, 128); // Semi-transparent white
|
||||
painter.setBrush(QBrush(highlightColor));
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.drawRect(this->rect()); // Highlight the widget area
|
||||
|
||||
// Allow the widget to be moved to the new position
|
||||
event->acceptProposedAction();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
bool SetEntryWidget::isChecked() const
|
||||
{
|
||||
return checkBox->isChecked();
|
||||
}
|
||||
|
||||
void SetEntryWidget::toggleExpansion()
|
||||
{
|
||||
expanded = !expanded;
|
||||
possibleCardsLabel->setVisible(expanded);
|
||||
cardListContainer->setVisible(expanded);
|
||||
alreadySelectedCardsLabel->setVisible(expanded);
|
||||
alreadySelectedCardListContainer->setVisible(expanded);
|
||||
expandButton->setText(expanded ? "-" : "+");
|
||||
|
||||
populateCardList();
|
||||
updateCardDisplayWidgets();
|
||||
|
||||
parent->updateCardLists();
|
||||
}
|
||||
|
||||
void SetEntryWidget::checkVisibility()
|
||||
{
|
||||
if (possibleCards.empty()) {
|
||||
setHidden(true);
|
||||
} else {
|
||||
setVisible(true);
|
||||
}
|
||||
}
|
||||
|
||||
QStringList SetEntryWidget::getAllCardsForSet()
|
||||
{
|
||||
QStringList list;
|
||||
QMap<QString, QStringList> setCards = parent->cardsForSets;
|
||||
if (setCards.contains(setName)) {
|
||||
for (const QString &cardName : setCards[setName]) {
|
||||
list << cardName;
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void SetEntryWidget::populateCardList()
|
||||
{
|
||||
possibleCards = getAllCardsForSet();
|
||||
|
||||
for (SetEntryWidget *entryWidget : parent->entry_widgets) {
|
||||
if (entryWidget == this) {
|
||||
break;
|
||||
}
|
||||
if (entryWidget->isChecked()) {
|
||||
for (const QString &cardName : entryWidget->possibleCards) {
|
||||
possibleCards.removeAll(cardName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unusedCards = getAllCardsForSet();
|
||||
for (const QString &cardName : possibleCards) {
|
||||
unusedCards.removeAll(cardName);
|
||||
}
|
||||
checkVisibility();
|
||||
countLabel->setText(QString::number(possibleCards.size()) + " (" +
|
||||
QString::number(possibleCards.size() + unusedCards.size()) + ")");
|
||||
}
|
||||
|
||||
void SetEntryWidget::updateCardDisplayWidgets()
|
||||
{
|
||||
cardListContainer->clearLayout();
|
||||
alreadySelectedCardListContainer->clearLayout();
|
||||
|
||||
for (const QString &cardName : possibleCards) {
|
||||
CardInfoPictureWidget *picture_widget = new CardInfoPictureWidget(cardListContainer);
|
||||
QString providerId = CardDatabaseManager::query()->getSpecificPrinting(cardName, setName, nullptr).getUuid();
|
||||
picture_widget->setCard(CardDatabaseManager::query()->getCard({cardName, providerId}));
|
||||
cardListContainer->addWidget(picture_widget);
|
||||
}
|
||||
|
||||
for (const QString &cardName : unusedCards) {
|
||||
CardInfoPictureWidget *picture_widget = new CardInfoPictureWidget(alreadySelectedCardListContainer);
|
||||
QString providerId = CardDatabaseManager::query()->getSpecificPrinting(cardName, setName, nullptr).getUuid();
|
||||
picture_widget->setCard(CardDatabaseManager::query()->getCard({cardName, providerId}));
|
||||
alreadySelectedCardListContainer->addWidget(picture_widget);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/**
|
||||
* @file dlg_select_set_for_cards.h
|
||||
* @ingroup Dialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_SELECT_SET_FOR_CARDS_H
|
||||
#define DLG_SELECT_SET_FOR_CARDS_H
|
||||
|
||||
#include "../interface/widgets/general/layout_containers/flow_widget.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QListWidget>
|
||||
#include <QMap>
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/deck_list/deck_list_model.h>
|
||||
|
||||
class SetEntryWidget; // Forward declaration
|
||||
|
||||
class DlgSelectSetForCards : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DlgSelectSetForCards(QWidget *parent, DeckListModel *_model);
|
||||
void retranslateUi();
|
||||
void sortSetsByCount();
|
||||
QMap<QString, QStringList> getCardsForSets();
|
||||
QMap<QString, QStringList> getModifiedCards();
|
||||
QVBoxLayout *listLayout;
|
||||
QList<SetEntryWidget *> entry_widgets;
|
||||
QMap<QString, QStringList> cardsForSets;
|
||||
|
||||
signals:
|
||||
void widgetOrderChanged();
|
||||
void orderChanged();
|
||||
|
||||
public slots:
|
||||
void actOK();
|
||||
void actClear();
|
||||
void actSetAllToPreferred();
|
||||
void updateLayoutOrder();
|
||||
void updateCardLists();
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
|
||||
private:
|
||||
QVBoxLayout *layout;
|
||||
QLabel *instructionLabel;
|
||||
QScrollArea *scrollArea;
|
||||
QScrollArea *uneditedCardsArea;
|
||||
FlowWidget *uneditedCardsFlowWidget;
|
||||
QLabel *uneditedCardsLabel;
|
||||
QScrollArea *modifiedCardsArea;
|
||||
FlowWidget *modifiedCardsFlowWidget;
|
||||
QLabel *modifiedCardsLabel;
|
||||
QWidget *listContainer;
|
||||
QListWidget *listWidget;
|
||||
DeckListModel *model;
|
||||
QMap<QString, SetEntryWidget *> setEntries;
|
||||
QPushButton *clearButton;
|
||||
QPushButton *setAllToPreferredButton;
|
||||
|
||||
QMap<QString, int> getSetsForCards();
|
||||
};
|
||||
|
||||
class SetEntryWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SetEntryWidget(DlgSelectSetForCards *parent, const QString &setName, int count);
|
||||
void toggleExpansion();
|
||||
void checkVisibility();
|
||||
QStringList getAllCardsForSet();
|
||||
void populateCardList();
|
||||
void updateCardDisplayWidgets();
|
||||
bool isChecked() const;
|
||||
DlgSelectSetForCards *parent;
|
||||
QString setName;
|
||||
bool expanded;
|
||||
|
||||
public slots:
|
||||
void mousePressEvent(QMouseEvent *event) override;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
void enterEvent(QEnterEvent *event) override;
|
||||
#else
|
||||
void enterEvent(QEvent *event) override;
|
||||
#endif
|
||||
void leaveEvent(QEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
|
||||
private:
|
||||
QVBoxLayout *layout;
|
||||
QCheckBox *checkBox;
|
||||
QPushButton *expandButton;
|
||||
QLabel *countLabel;
|
||||
QLabel *possibleCardsLabel;
|
||||
FlowWidget *cardListContainer;
|
||||
QLabel *alreadySelectedCardsLabel;
|
||||
FlowWidget *alreadySelectedCardListContainer;
|
||||
QVBoxLayout *cardListLayout;
|
||||
QStringList possibleCards;
|
||||
QStringList unusedCards;
|
||||
};
|
||||
|
||||
#endif // DLG_SELECT_SET_FOR_CARDS_H
|
||||
1947
cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp
Normal file
1947
cockatrice/src/interface/widgets/dialogs/dlg_settings.cpp
Normal file
File diff suppressed because it is too large
Load diff
358
cockatrice/src/interface/widgets/dialogs/dlg_settings.h
Normal file
358
cockatrice/src/interface/widgets/dialogs/dlg_settings.h
Normal file
|
|
@ -0,0 +1,358 @@
|
|||
/**
|
||||
* @file dlg_settings.h
|
||||
* @ingroup Dialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_SETTINGS_H
|
||||
#define DLG_SETTINGS_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QGroupBox>
|
||||
#include <QLabel>
|
||||
#include <QLoggingCategory>
|
||||
#include <QPushButton>
|
||||
#include <QSpinBox>
|
||||
#include <libcockatrice/utility/macros.h>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DlgSettingsLog, "dlg_settings");
|
||||
|
||||
class ShortcutTreeView;
|
||||
class SearchLineEdit;
|
||||
class QTreeView;
|
||||
class QStandardItemModel;
|
||||
class CardDatabase;
|
||||
class QCloseEvent;
|
||||
class QGridLayout;
|
||||
class QHBoxLayout;
|
||||
class QLineEdit;
|
||||
class QListWidget;
|
||||
class QListWidgetItem;
|
||||
class QRadioButton;
|
||||
class QSlider;
|
||||
class QStackedWidget;
|
||||
class QVBoxLayout;
|
||||
class SequenceEdit;
|
||||
|
||||
class AbstractSettingsPage : public QWidget
|
||||
{
|
||||
public:
|
||||
virtual void retranslateUi() = 0;
|
||||
};
|
||||
|
||||
class GeneralSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
GeneralSettingsPage();
|
||||
void retranslateUi() override;
|
||||
|
||||
private slots:
|
||||
void deckPathButtonClicked();
|
||||
void filtersPathButtonClicked();
|
||||
void replaysPathButtonClicked();
|
||||
void picsPathButtonClicked();
|
||||
void cardDatabasePathButtonClicked();
|
||||
void customCardDatabaseButtonClicked();
|
||||
void tokenDatabasePathButtonClicked();
|
||||
void resetAllPathsClicked();
|
||||
void languageBoxChanged(int index);
|
||||
|
||||
private:
|
||||
QStringList findQmFiles();
|
||||
QString languageName(const QString &lang);
|
||||
QLineEdit *deckPathEdit;
|
||||
QLineEdit *filtersPathEdit;
|
||||
QLineEdit *replaysPathEdit;
|
||||
QLineEdit *picsPathEdit;
|
||||
QLineEdit *cardDatabasePathEdit;
|
||||
QLineEdit *customCardDatabasePathEdit;
|
||||
QLineEdit *tokenDatabasePathEdit;
|
||||
QPushButton *resetAllPathsButton;
|
||||
QLabel *allPathsResetLabel;
|
||||
QGroupBox *personalGroupBox;
|
||||
QGroupBox *pathsGroupBox;
|
||||
QComboBox languageBox;
|
||||
QCheckBox startupUpdateCheckCheckBox;
|
||||
QLabel startupCardUpdateCheckBehaviorLabel;
|
||||
QComboBox startupCardUpdateCheckBehaviorSelector;
|
||||
QLabel cardUpdateCheckIntervalLabel;
|
||||
QSpinBox cardUpdateCheckIntervalSpinBox;
|
||||
QLabel lastCardUpdateCheckDateLabel;
|
||||
QCheckBox updateNotificationCheckBox;
|
||||
QCheckBox newVersionOracleCheckBox;
|
||||
QComboBox updateReleaseChannelBox;
|
||||
QLabel languageLabel;
|
||||
QLabel deckPathLabel;
|
||||
QLabel filtersPathLabel;
|
||||
QLabel replaysPathLabel;
|
||||
QLabel picsPathLabel;
|
||||
QLabel cardDatabasePathLabel;
|
||||
QLabel customCardDatabasePathLabel;
|
||||
QLabel tokenDatabasePathLabel;
|
||||
QLabel updateReleaseChannelLabel;
|
||||
QLabel advertiseTranslationPageLabel;
|
||||
QCheckBox showTipsOnStartup;
|
||||
};
|
||||
|
||||
class AppearanceSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void themeBoxChanged(int index);
|
||||
void openThemeLocation();
|
||||
void showShortcutsChanged(QT_STATE_CHANGED_T enabled);
|
||||
void overrideAllCardArtWithPersonalPreferenceToggled(QT_STATE_CHANGED_T enabled);
|
||||
|
||||
void cardViewInitialRowsMaxChanged(int value);
|
||||
void cardViewExpandedRowsMaxChanged(int value);
|
||||
|
||||
private:
|
||||
QLabel themeLabel;
|
||||
QComboBox themeBox;
|
||||
QPushButton openThemeButton;
|
||||
QLabel homeTabBackgroundSourceLabel;
|
||||
QComboBox homeTabBackgroundSourceBox;
|
||||
QLabel homeTabBackgroundShuffleFrequencyLabel;
|
||||
QSpinBox homeTabBackgroundShuffleFrequencySpinBox;
|
||||
QLabel minPlayersForMultiColumnLayoutLabel;
|
||||
QLabel maxFontSizeForCardsLabel;
|
||||
QCheckBox showShortcutsCheckBox;
|
||||
QCheckBox displayCardNamesCheckBox;
|
||||
QCheckBox autoRotateSidewaysLayoutCardsCheckBox;
|
||||
QCheckBox overrideAllCardArtWithPersonalPreferenceCheckBox;
|
||||
QCheckBox bumpSetsWithCardsInDeckToTopCheckBox;
|
||||
QCheckBox cardScalingCheckBox;
|
||||
QCheckBox roundCardCornersCheckBox;
|
||||
QLabel verticalCardOverlapPercentLabel;
|
||||
QSpinBox verticalCardOverlapPercentBox;
|
||||
QLabel cardViewInitialRowsMaxLabel;
|
||||
QSpinBox cardViewInitialRowsMaxBox;
|
||||
QLabel cardViewExpandedRowsMaxLabel;
|
||||
QSpinBox cardViewExpandedRowsMaxBox;
|
||||
QCheckBox horizontalHandCheckBox;
|
||||
QCheckBox leftJustifiedHandCheckBox;
|
||||
QCheckBox invertVerticalCoordinateCheckBox;
|
||||
QGroupBox *themeGroupBox;
|
||||
QGroupBox *menuGroupBox;
|
||||
QGroupBox *cardsGroupBox;
|
||||
QGroupBox *handGroupBox;
|
||||
QGroupBox *tableGroupBox;
|
||||
QGroupBox *cardCountersGroupBox;
|
||||
QList<QLabel *> cardCounterNames;
|
||||
QSpinBox minPlayersForMultiColumnLayoutEdit;
|
||||
QSpinBox maxFontSizeForCardsEdit;
|
||||
|
||||
public:
|
||||
AppearanceSettingsPage();
|
||||
void retranslateUi() override;
|
||||
};
|
||||
|
||||
class UserInterfaceSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
private slots:
|
||||
void setNotificationEnabled(QT_STATE_CHANGED_T);
|
||||
|
||||
private:
|
||||
QCheckBox notificationsEnabledCheckBox;
|
||||
QCheckBox specNotificationsEnabledCheckBox;
|
||||
QCheckBox buddyConnectNotificationsEnabledCheckBox;
|
||||
QCheckBox doubleClickToPlayCheckBox;
|
||||
QCheckBox clickPlaysAllSelectedCheckBox;
|
||||
QCheckBox playToStackCheckBox;
|
||||
QCheckBox closeEmptyCardViewCheckBox;
|
||||
QCheckBox focusCardViewSearchBarCheckBox;
|
||||
QCheckBox annotateTokensCheckBox;
|
||||
QCheckBox useTearOffMenusCheckBox;
|
||||
QCheckBox tapAnimationCheckBox;
|
||||
QCheckBox openDeckInNewTabCheckBox;
|
||||
QLabel visualDeckStoragePromptForConversionLabel;
|
||||
QComboBox visualDeckStoragePromptForConversionSelector;
|
||||
QCheckBox visualDeckStorageInGameCheckBox;
|
||||
QCheckBox visualDeckStorageSelectionAnimationCheckBox;
|
||||
QLabel defaultDeckEditorTypeLabel;
|
||||
QComboBox defaultDeckEditorTypeSelector;
|
||||
QLabel rewindBufferingMsLabel;
|
||||
QSpinBox rewindBufferingMsBox;
|
||||
QGroupBox *generalGroupBox;
|
||||
QGroupBox *notificationsGroupBox;
|
||||
QGroupBox *animationGroupBox;
|
||||
QGroupBox *deckEditorGroupBox;
|
||||
QGroupBox *replayGroupBox;
|
||||
|
||||
public:
|
||||
UserInterfaceSettingsPage();
|
||||
void retranslateUi() override;
|
||||
};
|
||||
|
||||
class DeckEditorSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DeckEditorSettingsPage();
|
||||
void retranslateUi() override;
|
||||
QString getLastUpdateTime();
|
||||
|
||||
private slots:
|
||||
void storeSettings();
|
||||
void urlListChanged(const QModelIndex &, int, int, const QModelIndex &, int);
|
||||
void setSpoilersEnabled(bool);
|
||||
void spoilerPathButtonClicked();
|
||||
void updateSpoilers();
|
||||
void unlockSettings();
|
||||
void actAddURL();
|
||||
void actRemoveURL();
|
||||
void actEditURL();
|
||||
void clearDownloadedPicsButtonClicked();
|
||||
void resetDownloadedURLsButtonClicked();
|
||||
|
||||
private:
|
||||
QPushButton clearDownloadedPicsButton;
|
||||
QPushButton resetDownloadURLs;
|
||||
QLabel urlLinkLabel;
|
||||
QCheckBox picDownloadCheckBox;
|
||||
QListWidget *urlList;
|
||||
QAction *aAdd, *aEdit, *aRemove;
|
||||
QCheckBox mcDownloadSpoilersCheckBox;
|
||||
QLabel msDownloadSpoilersLabel;
|
||||
QGroupBox *mpGeneralGroupBox;
|
||||
QGroupBox *mpSpoilerGroupBox;
|
||||
QLineEdit *mpSpoilerSavePathLineEdit;
|
||||
QLabel mcSpoilerSaveLabel;
|
||||
QLabel lastUpdatedLabel;
|
||||
QLabel infoOnSpoilersLabel;
|
||||
QPushButton *mpSpoilerPathButton;
|
||||
QPushButton *updateNowButton;
|
||||
QLabel networkCacheLabel;
|
||||
QSpinBox networkCacheEdit;
|
||||
QLabel networkRedirectCacheTtlLabel;
|
||||
QSpinBox networkRedirectCacheTtlEdit;
|
||||
QSpinBox pixmapCacheEdit;
|
||||
QLabel pixmapCacheLabel;
|
||||
};
|
||||
|
||||
class MessagesSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MessagesSettingsPage();
|
||||
void retranslateUi() override;
|
||||
|
||||
private slots:
|
||||
void actAdd();
|
||||
void actEdit();
|
||||
void actRemove();
|
||||
void updateColor(const QString &value);
|
||||
void updateHighlightColor(const QString &value);
|
||||
void updateTextColor(QT_STATE_CHANGED_T value);
|
||||
void updateTextHighlightColor(QT_STATE_CHANGED_T value);
|
||||
|
||||
private:
|
||||
QListWidget *messageList;
|
||||
QAction *aAdd;
|
||||
QAction *aEdit;
|
||||
QAction *aRemove;
|
||||
QCheckBox chatMentionCheckBox;
|
||||
QCheckBox chatMentionCompleterCheckbox;
|
||||
QCheckBox invertMentionForeground;
|
||||
QCheckBox invertHighlightForeground;
|
||||
QCheckBox ignoreUnregUsersMainChat;
|
||||
QCheckBox ignoreUnregUserMessages;
|
||||
QCheckBox messagePopups;
|
||||
QCheckBox mentionPopups;
|
||||
QCheckBox roomHistory;
|
||||
QGroupBox *chatGroupBox;
|
||||
QGroupBox *highlightGroupBox;
|
||||
QGroupBox *messageGroupBox;
|
||||
QLineEdit *mentionColor;
|
||||
QLineEdit *highlightColor;
|
||||
QLineEdit *customAlertString;
|
||||
QLabel hexLabel;
|
||||
QLabel hexHighlightLabel;
|
||||
QLabel customAlertStringLabel;
|
||||
QLabel explainMessagesLabel;
|
||||
|
||||
void storeSettings();
|
||||
void updateMentionPreview();
|
||||
void updateHighlightPreview();
|
||||
};
|
||||
|
||||
class SoundSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SoundSettingsPage();
|
||||
void retranslateUi() override;
|
||||
|
||||
private:
|
||||
QLabel themeLabel;
|
||||
QComboBox themeBox;
|
||||
QGroupBox *soundGroupBox;
|
||||
QPushButton soundTestButton;
|
||||
QCheckBox soundEnabledCheckBox;
|
||||
QLabel masterVolumeLabel;
|
||||
QSlider *masterVolumeSlider;
|
||||
QSpinBox *masterVolumeSpinBox;
|
||||
|
||||
private slots:
|
||||
void masterVolumeChanged(int value);
|
||||
void themeBoxChanged(int index);
|
||||
};
|
||||
|
||||
class ShortcutSettingsPage : public AbstractSettingsPage
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ShortcutSettingsPage();
|
||||
void retranslateUi() override;
|
||||
|
||||
private:
|
||||
SearchLineEdit *searchEdit;
|
||||
ShortcutTreeView *shortcutsTable;
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *buttonsLayout;
|
||||
QGroupBox *editShortcutGroupBox;
|
||||
QGridLayout *editLayout;
|
||||
QLabel *currentActionGroupLabel;
|
||||
QLabel *currentActionGroupName;
|
||||
QLabel *currentActionLabel;
|
||||
QLabel *currentActionName;
|
||||
QLabel *currentShortcutLabel;
|
||||
SequenceEdit *editTextBox;
|
||||
QLabel *faqLabel;
|
||||
QPushButton *btnResetAll;
|
||||
QPushButton *btnClearAll;
|
||||
|
||||
private slots:
|
||||
void resetShortcuts();
|
||||
void clearShortcuts();
|
||||
void currentItemChanged(const QString &key);
|
||||
};
|
||||
|
||||
class DlgSettings : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgSettings(QWidget *parent = nullptr);
|
||||
void setTab(int index);
|
||||
|
||||
private slots:
|
||||
void changePage(QListWidgetItem *current, QListWidgetItem *previous);
|
||||
void updateLanguage();
|
||||
|
||||
private:
|
||||
QListWidget *contentsWidget;
|
||||
QStackedWidget *pagesWidget;
|
||||
QListWidgetItem *generalButton, *appearanceButton, *userInterfaceButton, *deckEditorButton, *messagesButton,
|
||||
*soundButton, *shortcutsButton;
|
||||
void createIcons();
|
||||
void retranslateUi();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
#include "dlg_startup_card_check.h"
|
||||
|
||||
#include <QDate>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
DlgStartupCardCheck::DlgStartupCardCheck(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
setWindowTitle(tr("Card Update Check"));
|
||||
|
||||
layout = new QVBoxLayout(this);
|
||||
|
||||
QDate lastCheckDate = SettingsCache::instance().getLastCardUpdateCheck();
|
||||
int daysAgo = lastCheckDate.daysTo(QDate::currentDate());
|
||||
|
||||
instructionLabel = new QLabel(
|
||||
tr("It has been more than %2 days since you last checked your card database for updates.\nChoose how you would "
|
||||
"like to run the card database updater.\nYou can always change this behavior in the 'General' settings tab.")
|
||||
.arg(daysAgo));
|
||||
|
||||
layout->addWidget(instructionLabel);
|
||||
|
||||
group = new QButtonGroup(this);
|
||||
|
||||
foregroundBtn = new QRadioButton(tr("Run in foreground"));
|
||||
backgroundBtn = new QRadioButton(tr("Run in background"));
|
||||
backgroundAlwaysBtn = new QRadioButton(tr("Run in background and always from now on"));
|
||||
dontPromptBtn = new QRadioButton(tr("Don't prompt again and don't run"));
|
||||
dontRunBtn = new QRadioButton(tr("Don't run this time"));
|
||||
|
||||
group->addButton(foregroundBtn, 0);
|
||||
group->addButton(backgroundBtn, 1);
|
||||
group->addButton(backgroundAlwaysBtn, 2);
|
||||
group->addButton(dontPromptBtn, 3);
|
||||
group->addButton(dontRunBtn, 4);
|
||||
|
||||
foregroundBtn->setChecked(true); // default
|
||||
|
||||
layout->addWidget(foregroundBtn);
|
||||
layout->addWidget(backgroundBtn);
|
||||
layout->addWidget(backgroundAlwaysBtn);
|
||||
layout->addWidget(dontPromptBtn);
|
||||
layout->addWidget(dontRunBtn);
|
||||
|
||||
buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
|
||||
layout->addWidget(buttonBox);
|
||||
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &QDialog::accept);
|
||||
connect(buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/**
|
||||
* @file dlg_startup_card_check.h
|
||||
* @ingroup CardDatabaseUpdateDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_STARTUP_CARD_CHECK_H
|
||||
#define DLG_STARTUP_CARD_CHECK_H
|
||||
|
||||
#include <QButtonGroup>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLabel>
|
||||
#include <QRadioButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class DlgStartupCardCheck : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgStartupCardCheck(QWidget *parent);
|
||||
|
||||
QVBoxLayout *layout;
|
||||
QLabel *instructionLabel;
|
||||
QButtonGroup *group;
|
||||
QRadioButton *foregroundBtn, *backgroundBtn, *backgroundAlwaysBtn, *dontPromptBtn, *dontRunBtn;
|
||||
QDialogButtonBox *buttonBox;
|
||||
};
|
||||
|
||||
#endif // DLG_STARTUP_CARD_CHECK_H
|
||||
172
cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp
Normal file
172
cockatrice/src/interface/widgets/dialogs/dlg_tip_of_the_day.cpp
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
#include "dlg_tip_of_the_day.h"
|
||||
|
||||
#include "tip_of_the_day.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDate>
|
||||
#include <QDebug>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QGridLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
|
||||
#define MIN_TIP_IMAGE_HEIGHT 200
|
||||
#define MIN_TIP_IMAGE_WIDTH 200
|
||||
#define MAX_TIP_IMAGE_HEIGHT 300
|
||||
#define MAX_TIP_IMAGE_WIDTH 500
|
||||
|
||||
DlgTipOfTheDay::DlgTipOfTheDay(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
successfulInit = false;
|
||||
QString xmlPath = "theme:tips/tips_of_the_day.xml";
|
||||
tipDatabase = new TipsOfTheDay(xmlPath, this);
|
||||
|
||||
if (tipDatabase->rowCount() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
title = new QLabel();
|
||||
title->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
tipTextContent = new QLabel();
|
||||
tipTextContent->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||
tipTextContent->setWordWrap(true);
|
||||
tipTextContent->setTextInteractionFlags(Qt::TextBrowserInteraction);
|
||||
tipTextContent->setOpenExternalLinks(true);
|
||||
imageLabel = new QLabel();
|
||||
imageLabel->setFixedHeight(MAX_TIP_IMAGE_HEIGHT + 50);
|
||||
imageLabel->setFixedWidth(MAX_TIP_IMAGE_WIDTH + 50);
|
||||
image = new QPixmap();
|
||||
date = new QLabel();
|
||||
date->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
tipNumber = new QLabel();
|
||||
tipNumber->setAlignment(Qt::AlignCenter);
|
||||
|
||||
QList<int> seenTips = SettingsCache::instance().getSeenTips();
|
||||
newTipsAvailable = false;
|
||||
currentTip = 0;
|
||||
for (int i = 0; i < tipDatabase->rowCount(); i++) {
|
||||
if (!seenTips.contains(i)) {
|
||||
newTipsAvailable = true;
|
||||
currentTip = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
connect(this, &DlgTipOfTheDay::newTipRequested, this, &DlgTipOfTheDay::updateTip);
|
||||
newTipRequested(currentTip);
|
||||
|
||||
content = new QVBoxLayout;
|
||||
content->addWidget(title);
|
||||
content->addWidget(tipTextContent);
|
||||
content->addWidget(imageLabel);
|
||||
content->addWidget(date);
|
||||
|
||||
buttonBox = new QDialogButtonBox(Qt::Horizontal);
|
||||
nextButton = new QPushButton(tr("Next"));
|
||||
previousButton = new QPushButton(tr("Previous"));
|
||||
buttonBox->addButton(previousButton, QDialogButtonBox::ActionRole);
|
||||
buttonBox->addButton(nextButton, QDialogButtonBox::ActionRole);
|
||||
buttonBox->addButton(QDialogButtonBox::Ok);
|
||||
buttonBox->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
|
||||
connect(buttonBox, &QDialogButtonBox::accepted, this, &DlgTipOfTheDay::accept);
|
||||
connect(nextButton, &QPushButton::clicked, this, &DlgTipOfTheDay::nextClicked);
|
||||
connect(previousButton, &QPushButton::clicked, this, &DlgTipOfTheDay::previousClicked);
|
||||
|
||||
showTipsOnStartupCheck = new QCheckBox("Show tips on startup");
|
||||
showTipsOnStartupCheck->setChecked(SettingsCache::instance().getShowTipsOnStartup());
|
||||
connect(showTipsOnStartupCheck, &QCheckBox::clicked, &SettingsCache::instance(),
|
||||
&SettingsCache::setShowTipsOnStartup);
|
||||
buttonBar = new QHBoxLayout();
|
||||
buttonBar->addWidget(showTipsOnStartupCheck);
|
||||
buttonBar->addWidget(tipNumber);
|
||||
buttonBar->addWidget(buttonBox);
|
||||
|
||||
mainLayout = new QVBoxLayout;
|
||||
mainLayout->addLayout(content);
|
||||
mainLayout->addLayout(buttonBar);
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Tip of the Day"));
|
||||
setMinimumWidth(700);
|
||||
setMinimumHeight(500);
|
||||
successfulInit = true;
|
||||
}
|
||||
|
||||
DlgTipOfTheDay::~DlgTipOfTheDay()
|
||||
{
|
||||
tipDatabase->deleteLater();
|
||||
title->deleteLater();
|
||||
tipTextContent->deleteLater();
|
||||
imageLabel->deleteLater();
|
||||
tipNumber->deleteLater();
|
||||
showTipsOnStartupCheck->deleteLater();
|
||||
content->deleteLater();
|
||||
mainLayout->deleteLater();
|
||||
buttonBox->deleteLater();
|
||||
nextButton->deleteLater();
|
||||
previousButton->deleteLater();
|
||||
buttonBar->deleteLater();
|
||||
delete image;
|
||||
}
|
||||
|
||||
void DlgTipOfTheDay::nextClicked()
|
||||
{
|
||||
emit newTipRequested(currentTip + 1);
|
||||
}
|
||||
|
||||
void DlgTipOfTheDay::previousClicked()
|
||||
{
|
||||
emit newTipRequested(currentTip - 1);
|
||||
}
|
||||
|
||||
void DlgTipOfTheDay::updateTip(int tipId)
|
||||
{
|
||||
QString titleText, contentText, imagePath;
|
||||
|
||||
if (tipId < 0) {
|
||||
tipId = tipDatabase->rowCount() - 1;
|
||||
} else if (tipId >= tipDatabase->rowCount()) {
|
||||
tipId = tipId % tipDatabase->rowCount();
|
||||
}
|
||||
|
||||
// Store tip id as seen
|
||||
QList<int> seenTips = SettingsCache::instance().getSeenTips();
|
||||
if (!seenTips.contains(tipId)) {
|
||||
seenTips.append(tipId);
|
||||
SettingsCache::instance().setSeenTips(seenTips);
|
||||
}
|
||||
|
||||
TipOfTheDay tip = tipDatabase->getTip(tipId);
|
||||
titleText = tip.getTitle();
|
||||
contentText = tip.getContent();
|
||||
imagePath = tip.getImagePath();
|
||||
|
||||
title->setText("<h2>" + titleText + "</h2>");
|
||||
tipTextContent->setText(contentText);
|
||||
tipTextContent->setTextFormat(Qt::RichText);
|
||||
|
||||
if (!image->load(imagePath)) {
|
||||
qCWarning(DlgTipOfTheDayLog) << "Image failed to load from" << imagePath;
|
||||
imageLabel->clear();
|
||||
} else {
|
||||
int h = std::min(std::max(imageLabel->height(), MIN_TIP_IMAGE_HEIGHT), MAX_TIP_IMAGE_HEIGHT);
|
||||
int w = std::min(std::max(imageLabel->width(), MIN_TIP_IMAGE_WIDTH), MAX_TIP_IMAGE_WIDTH);
|
||||
imageLabel->setPixmap(image->scaled(w, h, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
}
|
||||
|
||||
date->setText("<i>Tip added on: " + tip.getDate().toString("yyyy-MM-dd") + "</i>");
|
||||
|
||||
tipNumber->setText("Tip " + QString::number(tipId + 1) + " / " + QString::number(tipDatabase->rowCount()));
|
||||
|
||||
currentTip = static_cast<unsigned int>(tipId);
|
||||
|
||||
adjustSize();
|
||||
}
|
||||
|
||||
void DlgTipOfTheDay::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
imageLabel->setPixmap(image->scaled(imageLabel->size(), Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* @file dlg_tip_of_the_day.h
|
||||
* @ingroup Dialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_TIPOFDAY_H
|
||||
#define DLG_TIPOFDAY_H
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QDialog>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QLoggingCategory>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DlgTipOfTheDayLog, "dlg_tip_of_the_day");
|
||||
|
||||
class QLabel;
|
||||
class QPushButton;
|
||||
class QCheckBox;
|
||||
class TipsOfTheDay;
|
||||
|
||||
class DlgTipOfTheDay : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgTipOfTheDay(QWidget *parent = nullptr);
|
||||
~DlgTipOfTheDay() override;
|
||||
bool successfulInit;
|
||||
bool newTipsAvailable;
|
||||
signals:
|
||||
void newTipRequested(int tipId);
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
unsigned int currentTip;
|
||||
TipsOfTheDay *tipDatabase;
|
||||
QLabel *title, *tipTextContent, *imageLabel, *tipNumber, *date;
|
||||
QCheckBox *showTipsOnStartupCheck;
|
||||
QPixmap *image;
|
||||
|
||||
QVBoxLayout *content, *mainLayout;
|
||||
QDialogButtonBox *buttonBox;
|
||||
QPushButton *nextButton, *previousButton;
|
||||
QHBoxLayout *buttonBar;
|
||||
|
||||
private slots:
|
||||
void nextClicked();
|
||||
void previousClicked();
|
||||
void updateTip(int tipId);
|
||||
};
|
||||
|
||||
#endif
|
||||
241
cockatrice/src/interface/widgets/dialogs/dlg_update.cpp
Normal file
241
cockatrice/src/interface/widgets/dialogs/dlg_update.cpp
Normal file
|
|
@ -0,0 +1,241 @@
|
|||
#include "dlg_update.h"
|
||||
|
||||
#include "../client/network/update/client/client_update_checker.h"
|
||||
#include "../client/network/update/client/release_channel.h"
|
||||
#include "../interface/window_main.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
#include <QProgressBar>
|
||||
#include <QProgressDialog>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QtNetwork>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <version_string.h>
|
||||
|
||||
DlgUpdate::DlgUpdate(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
|
||||
// Handle layout
|
||||
statusLabel = new QLabel(this);
|
||||
statusLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed);
|
||||
statusLabel->setWordWrap(true);
|
||||
descriptionLabel =
|
||||
new QLabel(tr("Current release channel") +
|
||||
QString(": %1").arg(tr(SettingsCache::instance().getUpdateReleaseChannel()->getName().toUtf8())),
|
||||
this);
|
||||
progress = new QProgressBar(this);
|
||||
|
||||
buttonBox = new QDialogButtonBox(this);
|
||||
buttonBox->setFixedWidth(350);
|
||||
|
||||
ok = new QPushButton("Close", this);
|
||||
manualDownload = new QPushButton(tr("Reinstall"), this);
|
||||
stopDownload = new QPushButton(tr("Cancel Download"), this);
|
||||
gotoDownload = new QPushButton(tr("Open Download Page"), this);
|
||||
|
||||
addStopDownloadAndRemoveOthers(false); // Add all buttons to box
|
||||
enableUpdateButton(false); // Unless we know there's an update available, you can't install
|
||||
buttonBox->addButton(ok, QDialogButtonBox::AcceptRole);
|
||||
|
||||
connect(gotoDownload, &QPushButton::clicked, this, &DlgUpdate::gotoDownloadPage);
|
||||
// TODO: make reinstall button actually do something when clicked
|
||||
// connect(manualDownload, &QPushButton::clicked, this, &DlgUpdate::downloadUpdate);
|
||||
connect(stopDownload, &QPushButton::clicked, this, &DlgUpdate::cancelDownload);
|
||||
connect(ok, &QPushButton::clicked, this, &DlgUpdate::closeDialog);
|
||||
|
||||
auto *parentLayout = new QVBoxLayout(this);
|
||||
parentLayout->addWidget(descriptionLabel);
|
||||
parentLayout->addWidget(statusLabel);
|
||||
parentLayout->addWidget(progress);
|
||||
parentLayout->addWidget(buttonBox);
|
||||
|
||||
setLayout(parentLayout);
|
||||
setWindowTitle(tr("Check for Client Updates"));
|
||||
|
||||
setFixedHeight(this->sizeHint().height());
|
||||
setFixedWidth(this->sizeHint().width());
|
||||
|
||||
// Check for SSL (this probably isn't necessary)
|
||||
if (!QSslSocket::supportsSsl()) {
|
||||
enableUpdateButton(false);
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Cockatrice was not built with SSL support, therefore you cannot download updates "
|
||||
"automatically! \nPlease visit the download page to update manually."));
|
||||
}
|
||||
|
||||
// Initialize the checker and downloader class
|
||||
uDownloader = new UpdateDownloader(this);
|
||||
connect(uDownloader, &UpdateDownloader::downloadSuccessful, this, &DlgUpdate::downloadSuccessful);
|
||||
connect(uDownloader, &UpdateDownloader::progressMade, this, &DlgUpdate::downloadProgressMade);
|
||||
connect(uDownloader, &UpdateDownloader::error, this, &DlgUpdate::downloadError);
|
||||
|
||||
// Check for updates
|
||||
beginUpdateCheck();
|
||||
}
|
||||
|
||||
void DlgUpdate::closeDialog()
|
||||
{
|
||||
accept();
|
||||
}
|
||||
|
||||
void DlgUpdate::gotoDownloadPage()
|
||||
{
|
||||
QDesktopServices::openUrl(SettingsCache::instance().getUpdateReleaseChannel()->getManualDownloadUrl());
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadUpdate(const QString &releaseName)
|
||||
{
|
||||
setLabel(tr("Downloading update: %1").arg(releaseName));
|
||||
addStopDownloadAndRemoveOthers(true); // Will remove all other buttons
|
||||
uDownloader->beginDownload(updateUrl);
|
||||
}
|
||||
|
||||
void DlgUpdate::cancelDownload()
|
||||
{
|
||||
emit uDownloader->stopDownload();
|
||||
setLabel("Download canceled");
|
||||
addStopDownloadAndRemoveOthers(false);
|
||||
downloadProgressMade(0, 1);
|
||||
}
|
||||
|
||||
void DlgUpdate::beginUpdateCheck()
|
||||
{
|
||||
progress->setMinimum(0);
|
||||
progress->setMaximum(0);
|
||||
setLabel(tr("Checking for updates..."));
|
||||
|
||||
auto checker = new ClientUpdateChecker(this);
|
||||
connect(checker, &ClientUpdateChecker::finishedCheck, this, &DlgUpdate::finishedUpdateCheck);
|
||||
connect(checker, &ClientUpdateChecker::error, this, &DlgUpdate::updateCheckError);
|
||||
checker->check();
|
||||
}
|
||||
|
||||
void DlgUpdate::finishedUpdateCheck(bool needToUpdate, bool isCompatible, Release *release)
|
||||
{
|
||||
|
||||
QString publishDate, versionName;
|
||||
|
||||
// Update the UI to say we've finished
|
||||
progress->setMaximum(100);
|
||||
setLabel(tr("Finished checking for updates"));
|
||||
|
||||
// If there are no available builds, then they can't auto update.
|
||||
enableUpdateButton(isCompatible);
|
||||
|
||||
if (isCompatible) {
|
||||
// If there is an update, save its URL and work out its name
|
||||
updateUrl = release->getDownloadUrl();
|
||||
}
|
||||
|
||||
// Give the user the appropriate message
|
||||
if (!needToUpdate) {
|
||||
// If there's no need to update, tell them that. However we still allow them to run the
|
||||
// downloader themselves if there's a compatible build
|
||||
QMessageBox::information(
|
||||
this, tr("No Update Available"),
|
||||
tr("Cockatrice is up to date!") + "<br><br>" +
|
||||
tr("You are already running the latest version available in the chosen release channel.") + "<br>" +
|
||||
"<b>" + tr("Current version") + QString(":</b> %1<br>").arg(VERSION_STRING) + "<b>" +
|
||||
tr("Selected release channel") +
|
||||
QString(":</b> %1").arg(tr(SettingsCache::instance().getUpdateReleaseChannel()->getName().toUtf8())));
|
||||
return;
|
||||
}
|
||||
|
||||
publishDate = release->getPublishDate().toString(QLocale().dateFormat(QLocale::LongFormat));
|
||||
if (isCompatible) {
|
||||
int reply;
|
||||
reply = QMessageBox::question(
|
||||
this, tr("Update Available"),
|
||||
tr("A new version of Cockatrice is available!") + "<br><br>" + "<b>" + tr("New version") +
|
||||
QString(":</b> %1<br>").arg(release->getName()) + "<b>" + tr("Released") +
|
||||
QString(":</b> %1 (<a href=\"%2\">").arg(publishDate, release->getDescriptionUrl()) + tr("Changelog") +
|
||||
"</a>)<br><br>" + tr("Do you want to update now?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (reply == QMessageBox::Yes)
|
||||
downloadUpdate(release->getName());
|
||||
} else {
|
||||
QMessageBox::information(
|
||||
this, tr("Update Available"),
|
||||
tr("A new version of Cockatrice is available!") + "<br><br>" + "<b>" + tr("New version") +
|
||||
QString(":</b> %1<br>").arg(release->getName()) + "<b>" + tr("Released") +
|
||||
QString(":</b> %1 (<a href=\"%2\">").arg(publishDate, release->getDescriptionUrl()) + tr("Changelog") +
|
||||
"</a>)<br><br>" +
|
||||
tr("Unfortunately, the automatic updater failed to find a compatible download. \nYou may have to "
|
||||
"manually download the new version.") +
|
||||
"<br><br>" +
|
||||
tr("Please check the <a href=\"%1\">releases page</a> on our Github and download the build for your "
|
||||
"system.")
|
||||
.arg(release->getDescriptionUrl()));
|
||||
}
|
||||
}
|
||||
|
||||
void DlgUpdate::enableUpdateButton(bool enable)
|
||||
{
|
||||
manualDownload->setEnabled(enable);
|
||||
}
|
||||
|
||||
void DlgUpdate::addStopDownloadAndRemoveOthers(bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
buttonBox->addButton(stopDownload, QDialogButtonBox::ActionRole);
|
||||
buttonBox->removeButton(manualDownload);
|
||||
buttonBox->removeButton(gotoDownload);
|
||||
} else {
|
||||
buttonBox->removeButton(stopDownload);
|
||||
buttonBox->addButton(manualDownload, QDialogButtonBox::ActionRole);
|
||||
buttonBox->addButton(gotoDownload, QDialogButtonBox::ActionRole);
|
||||
}
|
||||
}
|
||||
|
||||
void DlgUpdate::enableOkButton(bool enable)
|
||||
{
|
||||
ok->setEnabled(enable);
|
||||
}
|
||||
|
||||
void DlgUpdate::setLabel(const QString &newText)
|
||||
{
|
||||
statusLabel->setText(newText);
|
||||
}
|
||||
|
||||
void DlgUpdate::updateCheckError(const QString &errorString)
|
||||
{
|
||||
setLabel(tr("Error"));
|
||||
QMessageBox::critical(this, tr("Update Error"),
|
||||
tr("An error occurred while checking for updates:") + QString(" ") + errorString);
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadError(const QString &errorString)
|
||||
{
|
||||
setLabel(tr("Error"));
|
||||
enableUpdateButton(true);
|
||||
QMessageBox::critical(this, tr("Update Error"),
|
||||
tr("An error occurred while downloading an update:") + QString(" ") + errorString);
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadSuccessful(const QUrl &filepath)
|
||||
{
|
||||
setLabel(tr("Installing..."));
|
||||
// Try to open the installer. If it opens, quit Cockatrice
|
||||
if (QDesktopServices::openUrl(filepath)) {
|
||||
QMetaObject::invokeMethod(static_cast<MainWindow *>(parent()), "close", Qt::QueuedConnection);
|
||||
qCInfo(DlgUpdateLog) << "Opened downloaded update file successfully - closing Cockatrice";
|
||||
close();
|
||||
} else {
|
||||
setLabel(tr("Error"));
|
||||
QMessageBox::critical(this, tr("Update Error"),
|
||||
tr("Cockatrice is unable to open the installer.") + "<br><br>" +
|
||||
tr("Try to update manually by closing Cockatrice and running the installer.") +
|
||||
"<br>" + tr("Download location") + QString(": %1").arg(filepath.toLocalFile()));
|
||||
}
|
||||
}
|
||||
|
||||
void DlgUpdate::downloadProgressMade(qint64 bytesRead, qint64 totalBytes)
|
||||
{
|
||||
progress->setMaximum(totalBytes);
|
||||
progress->setValue(bytesRead);
|
||||
}
|
||||
53
cockatrice/src/interface/widgets/dialogs/dlg_update.h
Normal file
53
cockatrice/src/interface/widgets/dialogs/dlg_update.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/**
|
||||
* @file dlg_update.h
|
||||
* @ingroup ClientUpdateDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_UPDATE_H
|
||||
#define DLG_UPDATE_H
|
||||
|
||||
#include "../client/network/update/client/update_downloader.h"
|
||||
|
||||
#include <QDialogButtonBox>
|
||||
#include <QLoggingCategory>
|
||||
#include <QProgressDialog>
|
||||
#include <QtNetwork>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(DlgUpdateLog, "dlg_update");
|
||||
|
||||
class Release;
|
||||
|
||||
class DlgUpdate : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgUpdate(QWidget *parent);
|
||||
|
||||
private slots:
|
||||
void finishedUpdateCheck(bool needToUpdate, bool isCompatible, Release *release);
|
||||
void gotoDownloadPage();
|
||||
void downloadUpdate(const QString &releaseName);
|
||||
void cancelDownload();
|
||||
void updateCheckError(const QString &errorString);
|
||||
void downloadSuccessful(const QUrl &filepath);
|
||||
void downloadProgressMade(qint64 bytesRead, qint64 totalBytes);
|
||||
void downloadError(const QString &errorString);
|
||||
void closeDialog();
|
||||
|
||||
private:
|
||||
QUrl updateUrl;
|
||||
void enableUpdateButton(bool enable);
|
||||
void enableOkButton(bool enable);
|
||||
void addStopDownloadAndRemoveOthers(bool enable);
|
||||
void beginUpdateCheck();
|
||||
void setLabel(const QString &text);
|
||||
QLabel *statusLabel, *descriptionLabel;
|
||||
QProgressBar *progress;
|
||||
QPushButton *manualDownload, *gotoDownload, *ok, *stopDownload;
|
||||
QPushButton *cancel;
|
||||
UpdateDownloader *uDownloader;
|
||||
QDialogButtonBox *buttonBox;
|
||||
};
|
||||
|
||||
#endif
|
||||
84
cockatrice/src/interface/widgets/dialogs/dlg_view_log.cpp
Normal file
84
cockatrice/src/interface/widgets/dialogs/dlg_view_log.cpp
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
#include "dlg_view_log.h"
|
||||
|
||||
#include <QClipboard>
|
||||
#include <QPlainTextEdit>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QVBoxLayout>
|
||||
#include <libcockatrice/settings/cache_settings.h>
|
||||
#include <libcockatrice/utility/logger.h>
|
||||
|
||||
DlgViewLog::DlgViewLog(QWidget *parent) : QDialog(parent)
|
||||
{
|
||||
logArea = new QPlainTextEdit;
|
||||
logArea->setReadOnly(true);
|
||||
|
||||
auto *mainLayout = new QVBoxLayout;
|
||||
mainLayout->setSpacing(3);
|
||||
mainLayout->setContentsMargins(20, 20, 20, 6);
|
||||
|
||||
mainLayout->addWidget(logArea);
|
||||
|
||||
auto *bottomLayout = new QHBoxLayout;
|
||||
|
||||
coClearLog = new QCheckBox;
|
||||
coClearLog->setText(tr("Clear log when closing"));
|
||||
coClearLog->setChecked(SettingsCache::instance().servers().getClearDebugLogStatus(false));
|
||||
connect(coClearLog, &QCheckBox::toggled, this, &DlgViewLog::actCheckBoxChanged);
|
||||
|
||||
copyToClipboardButton = new QPushButton;
|
||||
copyToClipboardButton->setText(tr("Copy to clipboard"));
|
||||
copyToClipboardButton->setAutoDefault(false);
|
||||
connect(copyToClipboardButton, &QPushButton::clicked, this, &DlgViewLog::actCopyToClipboard);
|
||||
|
||||
bottomLayout->addWidget(coClearLog);
|
||||
bottomLayout->addStretch();
|
||||
bottomLayout->addWidget(copyToClipboardButton);
|
||||
|
||||
mainLayout->addLayout(bottomLayout);
|
||||
|
||||
setLayout(mainLayout);
|
||||
|
||||
setWindowTitle(tr("Debug Log"));
|
||||
resize(800, 500);
|
||||
|
||||
loadInitialLogBuffer();
|
||||
connect(&Logger::getInstance(), &Logger::logEntryAdded, this, &DlgViewLog::appendLogEntry);
|
||||
}
|
||||
|
||||
void DlgViewLog::actCheckBoxChanged(bool abNewValue)
|
||||
{
|
||||
SettingsCache::instance().servers().setClearDebugLogStatus(abNewValue);
|
||||
}
|
||||
|
||||
void DlgViewLog::actCopyToClipboard()
|
||||
{
|
||||
QApplication::clipboard()->setText(logArea->toPlainText());
|
||||
}
|
||||
|
||||
void DlgViewLog::loadInitialLogBuffer()
|
||||
{
|
||||
QList<QString> logBuffer = Logger::getInstance().getLogBuffer();
|
||||
for (const QString &message : logBuffer)
|
||||
appendLogEntry(message);
|
||||
}
|
||||
|
||||
void DlgViewLog::appendLogEntry(const QString &message)
|
||||
{
|
||||
static auto colorEscapeCodePattern = QRegularExpression("\033\\[\\d+m");
|
||||
|
||||
QString sanitizedMessage = message;
|
||||
sanitizedMessage.replace(colorEscapeCodePattern, "");
|
||||
|
||||
logArea->appendPlainText(sanitizedMessage);
|
||||
}
|
||||
|
||||
void DlgViewLog::closeEvent(QCloseEvent * /* event */)
|
||||
{
|
||||
if (coClearLog->isChecked()) {
|
||||
logArea->clear();
|
||||
|
||||
logArea->appendPlainText(Logger::getInstance().getClientVersion());
|
||||
logArea->appendPlainText(Logger::getInstance().getSystemArchitecture());
|
||||
}
|
||||
}
|
||||
37
cockatrice/src/interface/widgets/dialogs/dlg_view_log.h
Normal file
37
cockatrice/src/interface/widgets/dialogs/dlg_view_log.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* @file dlg_view_log.h
|
||||
* @ingroup ServerLogDialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef DLG_VIEWLOG_H
|
||||
#define DLG_VIEWLOG_H
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDialog>
|
||||
|
||||
class QPlainTextEdit;
|
||||
class QCloseEvent;
|
||||
|
||||
class DlgViewLog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DlgViewLog(QWidget *parent);
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent *event) override;
|
||||
|
||||
private:
|
||||
QPlainTextEdit *logArea;
|
||||
QCheckBox *coClearLog;
|
||||
QPushButton *copyToClipboardButton;
|
||||
|
||||
void loadInitialLogBuffer();
|
||||
private slots:
|
||||
void appendLogEntry(const QString &message);
|
||||
void actCheckBoxChanged(bool abNewValue);
|
||||
void actCopyToClipboard();
|
||||
};
|
||||
|
||||
#endif
|
||||
103
cockatrice/src/interface/widgets/dialogs/tip_of_the_day.cpp
Normal file
103
cockatrice/src/interface/widgets/dialogs/tip_of_the_day.cpp
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
#include "tip_of_the_day.h"
|
||||
|
||||
#include <QDate>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
#include <QTextStream>
|
||||
#include <QXmlStreamReader>
|
||||
#include <utility>
|
||||
|
||||
#define TIPDDBMODEL_COLUMNS 3
|
||||
|
||||
TipOfTheDay::TipOfTheDay(QString _title, QString _content, QString _imagePath, QDate _date)
|
||||
: title(std::move(_title)), content(std::move(_content)), imagePath(std::move(_imagePath)), date(_date)
|
||||
{
|
||||
}
|
||||
|
||||
TipsOfTheDay::TipsOfTheDay(QString xmlPath, QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
tipList = new QList<TipOfTheDay>;
|
||||
|
||||
QFile xmlFile(xmlPath);
|
||||
|
||||
QTextStream errorStream(stderr);
|
||||
if (!QFile::exists(xmlPath)) {
|
||||
errorStream << tr("File does not exist.\n");
|
||||
return;
|
||||
} else if (!xmlFile.open(QIODevice::ReadOnly)) {
|
||||
errorStream << tr("Failed to open file.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
QXmlStreamReader reader(&xmlFile);
|
||||
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
auto readerName = reader.name().toString();
|
||||
|
||||
if (readerName == "tip") {
|
||||
QString title, content, imagePath;
|
||||
QDate date;
|
||||
reader.readNext();
|
||||
while (!reader.atEnd()) {
|
||||
if (reader.readNext() == QXmlStreamReader::EndElement) {
|
||||
break;
|
||||
}
|
||||
|
||||
readerName = reader.name().toString();
|
||||
|
||||
if (readerName == "title") {
|
||||
title = reader.readElementText();
|
||||
} else if (readerName == "text") {
|
||||
content = reader.readElementText();
|
||||
} else if (readerName == "image") {
|
||||
imagePath = "theme:tips/images/" + reader.readElementText();
|
||||
} else if (readerName == "date") {
|
||||
date = QDate::fromString(reader.readElementText(), Qt::ISODate);
|
||||
} else {
|
||||
// unknown element, do nothing
|
||||
}
|
||||
}
|
||||
tipList->append(TipOfTheDay(title, content, imagePath, date));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TipsOfTheDay::~TipsOfTheDay()
|
||||
{
|
||||
delete tipList;
|
||||
}
|
||||
|
||||
QVariant TipsOfTheDay::data(const QModelIndex &index, int /*role*/) const
|
||||
{
|
||||
if (!index.isValid() || index.row() >= tipList->size() || index.column() >= TIPDDBMODEL_COLUMNS)
|
||||
return QVariant();
|
||||
|
||||
TipOfTheDay tip = tipList->at(index.row());
|
||||
switch (index.column()) {
|
||||
case TitleColumn:
|
||||
return tip.getTitle();
|
||||
case ContentColumn:
|
||||
return tip.getContent();
|
||||
case ImagePathColumn:
|
||||
return tip.getImagePath();
|
||||
case DateColumn:
|
||||
return tip.getDate();
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
}
|
||||
|
||||
TipOfTheDay TipsOfTheDay::getTip(int tipId)
|
||||
{
|
||||
return tipList->at(tipId);
|
||||
}
|
||||
|
||||
int TipsOfTheDay::rowCount(const QModelIndex &parent) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return tipList->size();
|
||||
}
|
||||
61
cockatrice/src/interface/widgets/dialogs/tip_of_the_day.h
Normal file
61
cockatrice/src/interface/widgets/dialogs/tip_of_the_day.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* @file tip_of_the_day.h
|
||||
* @ingroup Dialogs
|
||||
* @brief TODO: Document this.
|
||||
*/
|
||||
|
||||
#ifndef TIP_OF_DAY_H
|
||||
#define TIP_OF_DAY_H
|
||||
|
||||
#include <QAbstractListModel>
|
||||
#include <QDate>
|
||||
|
||||
class TipOfTheDay
|
||||
{
|
||||
public:
|
||||
explicit TipOfTheDay(QString _title, QString _content, QString _imagePath, QDate _date);
|
||||
QString getTitle() const
|
||||
{
|
||||
return title;
|
||||
}
|
||||
QString getContent() const
|
||||
{
|
||||
return content;
|
||||
}
|
||||
QString getImagePath() const
|
||||
{
|
||||
return imagePath;
|
||||
}
|
||||
QDate getDate() const
|
||||
{
|
||||
return date;
|
||||
}
|
||||
|
||||
private:
|
||||
QString title, content, imagePath;
|
||||
QDate date;
|
||||
};
|
||||
|
||||
class TipsOfTheDay : public QAbstractListModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum Columns
|
||||
{
|
||||
TitleColumn,
|
||||
ContentColumn,
|
||||
ImagePathColumn,
|
||||
DateColumn,
|
||||
};
|
||||
|
||||
explicit TipsOfTheDay(QString xmlPath, QObject *parent = nullptr);
|
||||
~TipsOfTheDay() override;
|
||||
TipOfTheDay getTip(int tipId);
|
||||
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
|
||||
QVariant data(const QModelIndex &index, int role) const override;
|
||||
|
||||
private:
|
||||
QList<TipOfTheDay> *tipList;
|
||||
};
|
||||
|
||||
#endif
|
||||
Loading…
Add table
Add a link
Reference in a new issue