mirror of
https://github.com/Cockatrice/Cockatrice.git
synced 2026-07-16 15:32:15 -07:00
Merge branch 'master' into mergingCheckout
This commit is contained in:
commit
0879bc3430
290 changed files with 50236 additions and 34560 deletions
|
|
@ -3,14 +3,13 @@
|
|||
#include "../../../settings/cache_settings.h"
|
||||
#include "../../../settings/shortcuts_settings.h"
|
||||
|
||||
DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEditor)
|
||||
: QMenu(parent), deckEditor(_deckEditor)
|
||||
DeckEditorMenu::DeckEditorMenu(AbstractTabDeckEditor *parent) : QMenu(parent), deckEditor(parent)
|
||||
{
|
||||
aNewDeck = new QAction(QString(), this);
|
||||
connect(aNewDeck, SIGNAL(triggered()), deckEditor, SLOT(actNewDeck()));
|
||||
connect(aNewDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actNewDeck);
|
||||
|
||||
aLoadDeck = new QAction(QString(), this);
|
||||
connect(aLoadDeck, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeck()));
|
||||
connect(aLoadDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actLoadDeck);
|
||||
|
||||
loadRecentDeckMenu = new QMenu(this);
|
||||
connect(&SettingsCache::instance().recents(), &RecentsSettings::recentlyOpenedDeckPathsChanged, this,
|
||||
|
|
@ -22,47 +21,50 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit
|
|||
updateRecentlyOpened();
|
||||
|
||||
aSaveDeck = new QAction(QString(), this);
|
||||
connect(aSaveDeck, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeck()));
|
||||
connect(aSaveDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actSaveDeck);
|
||||
|
||||
aSaveDeckAs = new QAction(QString(), this);
|
||||
connect(aSaveDeckAs, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckAs()));
|
||||
connect(aSaveDeckAs, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actSaveDeckAs);
|
||||
|
||||
aLoadDeckFromClipboard = new QAction(QString(), this);
|
||||
connect(aLoadDeckFromClipboard, SIGNAL(triggered()), deckEditor, SLOT(actLoadDeckFromClipboard()));
|
||||
connect(aLoadDeckFromClipboard, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actLoadDeckFromClipboard);
|
||||
|
||||
aEditDeckInClipboard = new QAction(QString(), this);
|
||||
connect(aEditDeckInClipboard, SIGNAL(triggered()), deckEditor, SLOT(actEditDeckInClipboard()));
|
||||
connect(aEditDeckInClipboard, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actEditDeckInClipboard);
|
||||
|
||||
aEditDeckInClipboardRaw = new QAction(QString(), this);
|
||||
connect(aEditDeckInClipboardRaw, SIGNAL(triggered()), deckEditor, SLOT(actEditDeckInClipboardRaw()));
|
||||
connect(aEditDeckInClipboardRaw, &QAction::triggered, deckEditor,
|
||||
&AbstractTabDeckEditor::actEditDeckInClipboardRaw);
|
||||
|
||||
aSaveDeckToClipboard = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboard, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboard()));
|
||||
connect(aSaveDeckToClipboard, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actSaveDeckToClipboard);
|
||||
|
||||
aSaveDeckToClipboardNoSetInfo = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboardNoSetInfo, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboardNoSetInfo()));
|
||||
connect(aSaveDeckToClipboardNoSetInfo, &QAction::triggered, deckEditor,
|
||||
&AbstractTabDeckEditor::actSaveDeckToClipboardNoSetInfo);
|
||||
|
||||
aSaveDeckToClipboardRaw = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboardRaw, SIGNAL(triggered()), deckEditor, SLOT(actSaveDeckToClipboardRaw()));
|
||||
connect(aSaveDeckToClipboardRaw, &QAction::triggered, deckEditor,
|
||||
&AbstractTabDeckEditor::actSaveDeckToClipboardRaw);
|
||||
|
||||
aSaveDeckToClipboardRawNoSetInfo = new QAction(QString(), this);
|
||||
connect(aSaveDeckToClipboardRawNoSetInfo, SIGNAL(triggered()), deckEditor,
|
||||
SLOT(actSaveDeckToClipboardRawNoSetInfo()));
|
||||
connect(aSaveDeckToClipboardRawNoSetInfo, &QAction::triggered, deckEditor,
|
||||
&AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo);
|
||||
|
||||
aPrintDeck = new QAction(QString(), this);
|
||||
connect(aPrintDeck, SIGNAL(triggered()), deckEditor, SLOT(actPrintDeck()));
|
||||
connect(aPrintDeck, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actPrintDeck);
|
||||
|
||||
aExportDeckDecklist = new QAction(QString(), this);
|
||||
connect(aExportDeckDecklist, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklist()));
|
||||
connect(aExportDeckDecklist, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actExportDeckDecklist);
|
||||
|
||||
aExportDeckDecklistXyz = new QAction(QString(), this);
|
||||
connect(aExportDeckDecklistXyz, SIGNAL(triggered()), deckEditor, SLOT(actExportDeckDecklistXyz()));
|
||||
connect(aExportDeckDecklistXyz, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actExportDeckDecklistXyz);
|
||||
|
||||
aAnalyzeDeckDeckstats = new QAction(QString(), this);
|
||||
connect(aAnalyzeDeckDeckstats, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckDeckstats()));
|
||||
connect(aAnalyzeDeckDeckstats, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actAnalyzeDeckDeckstats);
|
||||
|
||||
aAnalyzeDeckTappedout = new QAction(QString(), this);
|
||||
connect(aAnalyzeDeckTappedout, SIGNAL(triggered()), deckEditor, SLOT(actAnalyzeDeckTappedout()));
|
||||
connect(aAnalyzeDeckTappedout, &QAction::triggered, deckEditor, &AbstractTabDeckEditor::actAnalyzeDeckTappedout);
|
||||
|
||||
analyzeDeckMenu = new QMenu(this);
|
||||
analyzeDeckMenu->addAction(aExportDeckDecklist);
|
||||
|
|
@ -103,7 +105,8 @@ DeckEditorMenu::DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *_deckEdit
|
|||
addAction(aClose);
|
||||
|
||||
retranslateUi();
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&DeckEditorMenu::refreshShortcuts);
|
||||
refreshShortcuts();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ class DeckEditorMenu : public QMenu
|
|||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DeckEditorMenu(QWidget *parent, AbstractTabDeckEditor *deckEditor);
|
||||
explicit DeckEditorMenu(AbstractTabDeckEditor *parent);
|
||||
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ ReleaseChannel::~ReleaseChannel()
|
|||
void ReleaseChannel::checkForUpdates()
|
||||
{
|
||||
QString releaseChannelUrl = getReleaseChannelUrl();
|
||||
qCDebug(ReleaseChannelLog) << "Searching for updates on the channel: " << releaseChannelUrl;
|
||||
qCInfo(ReleaseChannelLog) << "Searching for updates on the channel: " << releaseChannelUrl;
|
||||
response = netMan->get(QNetworkRequest(releaseChannelUrl));
|
||||
connect(response, &QNetworkReply::finished, this, &ReleaseChannel::releaseListFinished);
|
||||
}
|
||||
|
|
@ -152,15 +152,15 @@ void StableReleaseChannel::releaseListFinished()
|
|||
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qCDebug(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
qCInfo(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
||||
qCDebug(ReleaseChannelLog) << "Got reply from release server, name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl()
|
||||
<< "date=" << lastRelease->getPublishDate() << "url=" << lastRelease->getDownloadUrl();
|
||||
qCInfo(ReleaseChannelLog) << "Got reply from release server, name=" << lastRelease->getName()
|
||||
<< "desc=" << lastRelease->getDescriptionUrl() << "date=" << lastRelease->getPublishDate()
|
||||
<< "url=" << lastRelease->getDownloadUrl();
|
||||
|
||||
const QString &tagName = resultMap["tag_name"].toString();
|
||||
QString url = QString(STABLETAG_URL) + tagName;
|
||||
qCDebug(ReleaseChannelLog) << "Searching for commit hash corresponding to stable channel tag: " << tagName;
|
||||
qCInfo(ReleaseChannelLog) << "Searching for commit hash corresponding to stable channel tag: " << tagName;
|
||||
response = netMan->get(QNetworkRequest(url));
|
||||
connect(response, &QNetworkReply::finished, this, &StableReleaseChannel::tagListFinished);
|
||||
}
|
||||
|
|
@ -185,11 +185,11 @@ void StableReleaseChannel::tagListFinished()
|
|||
}
|
||||
|
||||
lastRelease->setCommitHash(resultMap["object"].toMap()["sha"].toString());
|
||||
qCDebug(ReleaseChannelLog) << "Got reply from tag server, commit=" << lastRelease->getCommitHash();
|
||||
qCInfo(ReleaseChannelLog) << "Got reply from tag server, commit=" << lastRelease->getCommitHash();
|
||||
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qCDebug(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
qCInfo(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
const bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
||||
|
||||
emit finishedCheck(needToUpdate, lastRelease->isCompatibleVersionFound(), lastRelease);
|
||||
|
|
@ -256,13 +256,13 @@ void BetaReleaseChannel::releaseListFinished()
|
|||
lastRelease->setName(QString("%1 (%2)").arg(resultMap["tag_name"].toString()).arg(shortHash));
|
||||
lastRelease->setDescriptionUrl(QString(BETARELEASE_CHANGESURL).arg(VERSION_COMMIT, shortHash));
|
||||
|
||||
qCDebug(ReleaseChannelLog) << "Got reply from release server, size=" << resultMap.size()
|
||||
<< "name=" << lastRelease->getName() << "desc=" << lastRelease->getDescriptionUrl()
|
||||
<< "commit=" << lastRelease->getCommitHash() << "date=" << lastRelease->getPublishDate();
|
||||
qCInfo(ReleaseChannelLog) << "Got reply from release server, size=" << resultMap.size()
|
||||
<< "name=" << lastRelease->getName() << "desc=" << lastRelease->getDescriptionUrl()
|
||||
<< "commit=" << lastRelease->getCommitHash() << "date=" << lastRelease->getPublishDate();
|
||||
|
||||
QString betaBuildDownloadUrl = resultMap["assets_url"].toString();
|
||||
|
||||
qCDebug(ReleaseChannelLog) << "Searching for a corresponding file on the beta channel: " << betaBuildDownloadUrl;
|
||||
qCInfo(ReleaseChannelLog) << "Searching for a corresponding file on the beta channel: " << betaBuildDownloadUrl;
|
||||
response = netMan->get(QNetworkRequest(betaBuildDownloadUrl));
|
||||
connect(response, &QNetworkReply::finished, this, &BetaReleaseChannel::fileListFinished);
|
||||
}
|
||||
|
|
@ -282,7 +282,7 @@ void BetaReleaseChannel::fileListFinished()
|
|||
QVariantList resultList = jsonResponse.toVariant().toList();
|
||||
QString shortHash = lastRelease->getCommitHash().left(GIT_SHORT_HASH_LEN);
|
||||
QString myHash = QString(VERSION_COMMIT);
|
||||
qCDebug(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
qCInfo(ReleaseChannelLog) << "Current hash=" << myHash << "update hash=" << shortHash;
|
||||
|
||||
bool needToUpdate = (QString::compare(shortHash, myHash, Qt::CaseInsensitive) != 0);
|
||||
bool compatibleVersion = false;
|
||||
|
|
@ -299,7 +299,7 @@ void BetaReleaseChannel::fileListFinished()
|
|||
if (downloadMatchesCurrentOS(*url)) {
|
||||
compatibleVersion = true;
|
||||
lastRelease->setDownloadUrl(*url);
|
||||
qCDebug(ReleaseChannelLog) << "Found compatible version url=" << *url;
|
||||
qCInfo(ReleaseChannelLog) << "Found compatible version url=" << *url;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ SpoilerBackgroundUpdater::SpoilerBackgroundUpdater(QObject *apParent) : QObject(
|
|||
// File exists means we're in spoiler season
|
||||
startSpoilerDownloadProcess(SPOILERS_STATUS_URL, false);
|
||||
} else {
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoilers Disabled";
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Spoilers Disabled";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ void SpoilerBackgroundUpdater::actDownloadFinishedSpoilersFile()
|
|||
reply->deleteLater();
|
||||
emit spoilerCheckerDone();
|
||||
} else {
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Error downloading spoilers file" << errorCode;
|
||||
qCWarning(SpoilerBackgroundUpdaterLog) << "Error downloading spoilers file" << errorCode;
|
||||
emit spoilerCheckerDone();
|
||||
}
|
||||
}
|
||||
|
|
@ -81,11 +81,11 @@ bool SpoilerBackgroundUpdater::deleteSpoilerFile()
|
|||
|
||||
// Delete the spoiler.xml file
|
||||
if (file.exists() && file.remove()) {
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Deleting spoiler.xml";
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Deleting spoiler.xml";
|
||||
return true;
|
||||
}
|
||||
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Error: Spoiler.xml not found or not deleted";
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Error: Spoiler.xml not found or not deleted";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -101,24 +101,24 @@ void SpoilerBackgroundUpdater::actCheckIfSpoilerSeasonEnabled()
|
|||
trayIcon->showMessage(tr("Spoilers season has ended"), tr("Deleting spoiler.xml. Please run Oracle"));
|
||||
}
|
||||
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Season Offline";
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Spoiler Season Offline";
|
||||
emit spoilerCheckerDone();
|
||||
} else if (errorCode == QNetworkReply::NoError) {
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Online";
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Spoiler Service Online";
|
||||
startSpoilerDownloadProcess(SPOILERS_URL, true);
|
||||
} else if (errorCode == QNetworkReply::HostNotFoundError) {
|
||||
if (trayIcon) {
|
||||
trayIcon->showMessage(tr("Spoilers download failed"), tr("No internet connection"));
|
||||
}
|
||||
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler download failed due to no internet connection";
|
||||
qCWarning(SpoilerBackgroundUpdaterLog) << "Spoiler download failed due to no internet connection";
|
||||
emit spoilerCheckerDone();
|
||||
} else {
|
||||
if (trayIcon) {
|
||||
trayIcon->showMessage(tr("Spoilers download failed"), tr("Error") + " " + (short)errorCode);
|
||||
}
|
||||
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler download failed with reason" << errorCode;
|
||||
qCWarning(SpoilerBackgroundUpdaterLog) << "Spoiler download failed with reason" << errorCode;
|
||||
emit spoilerCheckerDone();
|
||||
}
|
||||
}
|
||||
|
|
@ -139,19 +139,19 @@ bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
|
|||
trayIcon->showMessage(tr("Spoilers already up to date"), tr("No new spoilers added"));
|
||||
}
|
||||
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoilers Up to Date";
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Spoilers Up to Date";
|
||||
return false;
|
||||
}
|
||||
|
||||
QFile file(fileName);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Error: File open (w) failed for" << fileName;
|
||||
qCWarning(SpoilerBackgroundUpdaterLog) << "Spoiler Service Error: File open (w) failed for" << fileName;
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (file.write(data) == -1) {
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Error: File write (w) failed for" << fileName;
|
||||
qCWarning(SpoilerBackgroundUpdaterLog) << "Spoiler Service Error: File write (w) failed for" << fileName;
|
||||
file.close();
|
||||
return false;
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ bool SpoilerBackgroundUpdater::saveDownloadedFile(QByteArray data)
|
|||
file.close();
|
||||
|
||||
// Data written, so reload the card database
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Spoiler Service Data Written";
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Spoiler Service Data Written";
|
||||
const auto reloadOk = QtConcurrent::run([] { CardDatabaseManager::getInstance()->loadCardDatabases(); });
|
||||
|
||||
// If the user has notifications enabled, let them know
|
||||
|
|
@ -202,12 +202,12 @@ QByteArray SpoilerBackgroundUpdater::getHash(const QString fileName)
|
|||
QCryptographicHash hash(QCryptographicHash::Algorithm::Md5);
|
||||
hash.addData(bytes);
|
||||
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "File Hash =" << hash.result();
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "File Hash =" << hash.result();
|
||||
|
||||
file.close();
|
||||
return hash.result();
|
||||
} else {
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "getHash ReadOnly failed!";
|
||||
qCWarning(SpoilerBackgroundUpdaterLog) << "getHash ReadOnly failed!";
|
||||
file.close();
|
||||
return QByteArray();
|
||||
}
|
||||
|
|
@ -221,7 +221,7 @@ QByteArray SpoilerBackgroundUpdater::getHash(QByteArray data)
|
|||
QCryptographicHash hash(QCryptographicHash::Algorithm::Md5);
|
||||
hash.addData(bytes);
|
||||
|
||||
qCDebug(SpoilerBackgroundUpdaterLog) << "Data Hash =" << hash.result();
|
||||
qCInfo(SpoilerBackgroundUpdaterLog) << "Data Hash =" << hash.result();
|
||||
|
||||
return hash.result();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ SoundEngine::~SoundEngine()
|
|||
void SoundEngine::soundEnabledChanged()
|
||||
{
|
||||
if (SettingsCache::instance().getSoundEnabled()) {
|
||||
qCDebug(SoundEngineLog) << "SoundEngine: enabling sound with" << audioData.size() << "sounds";
|
||||
qCInfo(SoundEngineLog) << "SoundEngine: enabling sound with" << audioData.size() << "sounds";
|
||||
if (!player) {
|
||||
player = new QMediaPlayer;
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
|
||||
|
|
@ -46,7 +46,7 @@ void SoundEngine::soundEnabledChanged()
|
|||
#endif
|
||||
}
|
||||
} else {
|
||||
qCDebug(SoundEngineLog) << "SoundEngine: disabling sound";
|
||||
qCInfo(SoundEngineLog) << "SoundEngine: disabling sound";
|
||||
if (player) {
|
||||
player->stop();
|
||||
player->deleteLater();
|
||||
|
|
@ -90,7 +90,7 @@ void SoundEngine::ensureThemeDirectoryExists()
|
|||
{
|
||||
if (SettingsCache::instance().getSoundThemeName().isEmpty() ||
|
||||
!getAvailableThemes().contains(SettingsCache::instance().getSoundThemeName())) {
|
||||
qCDebug(SoundEngineLog) << "Sounds theme name not set, setting default value";
|
||||
qCInfo(SoundEngineLog) << "Sounds theme name not set, setting default value";
|
||||
SettingsCache::instance().setSoundThemeName(DEFAULT_THEME_NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -131,7 +131,7 @@ QStringMap &SoundEngine::getAvailableThemes()
|
|||
void SoundEngine::themeChangedSlot()
|
||||
{
|
||||
QString themeName = SettingsCache::instance().getSoundThemeName();
|
||||
qCDebug(SoundEngineLog) << "Sound theme changed:" << themeName;
|
||||
qCInfo(SoundEngineLog) << "Sound theme changed:" << themeName;
|
||||
|
||||
QDir dir = getAvailableThemes().value(themeName);
|
||||
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QPrintPreviewDialog>
|
||||
#include <QPrinter>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
|
|
@ -65,7 +66,8 @@ AbstractTabDeckEditor::AbstractTabDeckEditor(TabSupervisor *_tabSupervisor) : Ta
|
|||
connect(filterDockWidget, &DeckEditorFilterDockWidget::clearAllDatabaseFilters, databaseDisplayDockWidget,
|
||||
&DeckEditorDatabaseDisplayWidget::clearAllDatabaseFilters);
|
||||
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&AbstractTabDeckEditor::refreshShortcuts);
|
||||
}
|
||||
|
||||
void AbstractTabDeckEditor::updateCard(CardInfoPtr _card)
|
||||
|
|
@ -124,8 +126,13 @@ void AbstractTabDeckEditor::actSwapCard(CardInfoPtr info, QString zoneName)
|
|||
{
|
||||
QString providerId = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("uuid");
|
||||
QString collectorNumber = CardDatabaseManager::getInstance()->getSetInfoForCard(info).getProperty("num");
|
||||
deckDockWidget->swapCard(
|
||||
deckDockWidget->deckModel->findCard(info->getName(), zoneName, providerId, collectorNumber));
|
||||
|
||||
QModelIndex foundCard = deckDockWidget->deckModel->findCard(info->getName(), zoneName, providerId, collectorNumber);
|
||||
if (!foundCard.isValid()) {
|
||||
foundCard = deckDockWidget->deckModel->findCard(info->getName(), zoneName);
|
||||
}
|
||||
|
||||
deckDockWidget->swapCard(foundCard);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -332,8 +339,7 @@ bool AbstractTabDeckEditor::actSaveDeck()
|
|||
cmd.set_deck_list(deckString.toStdString());
|
||||
|
||||
PendingCommand *pend = AbstractClient::prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(saveDeckRemoteFinished(Response)));
|
||||
connect(pend, &PendingCommand::finished, this, &AbstractTabDeckEditor::saveDeckRemoteFinished);
|
||||
tabSupervisor->getClient()->sendCommand(pend);
|
||||
|
||||
return true;
|
||||
|
|
@ -357,6 +363,7 @@ bool AbstractTabDeckEditor::actSaveDeckAs()
|
|||
dialog.setDefaultSuffix("cod");
|
||||
dialog.setNameFilters(DeckLoader::FILE_NAME_FILTERS);
|
||||
dialog.selectFile(getDeckList()->getName().trimmed());
|
||||
|
||||
if (!dialog.exec())
|
||||
return false;
|
||||
|
||||
|
|
@ -451,7 +458,7 @@ void AbstractTabDeckEditor::actSaveDeckToClipboardRawNoSetInfo()
|
|||
void AbstractTabDeckEditor::actPrintDeck()
|
||||
{
|
||||
auto *dlg = new QPrintPreviewDialog(this);
|
||||
connect(dlg, SIGNAL(paintRequested(QPrinter *)), deckDockWidget->deckModel, SLOT(printDeckList(QPrinter *)));
|
||||
connect(dlg, &QPrintPreviewDialog::paintRequested, deckDockWidget->deckModel, &DeckListModel::printDeckList);
|
||||
dlg->exec();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef TAB_GENERIC_DECK_EDITOR_H
|
||||
#define TAB_GENERIC_DECK_EDITOR_H
|
||||
|
||||
#include "../../game/cards/card_database.h"
|
||||
#include "../../game/cards/card_info.h"
|
||||
#include "../menus/deck_editor/deck_editor_menu.h"
|
||||
#include "../ui/widgets/deck_editor/deck_editor_card_info_dock_widget.h"
|
||||
#include "../ui/widgets/deck_editor/deck_editor_database_display_widget.h"
|
||||
|
|
@ -44,6 +44,8 @@ class AbstractTabDeckEditor : public Tab
|
|||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class DeckEditorMenu;
|
||||
|
||||
public:
|
||||
explicit AbstractTabDeckEditor(TabSupervisor *_tabSupervisor);
|
||||
|
||||
|
|
@ -67,7 +69,7 @@ public:
|
|||
DeckEditorPrintingSelectorDockWidget *printingSelectorDockWidget;
|
||||
|
||||
public slots:
|
||||
void onDeckChanged();
|
||||
virtual void onDeckChanged();
|
||||
void updateCard(CardInfoPtr _card);
|
||||
void actAddCard(CardInfoPtr info);
|
||||
void actAddCardToSideboard(CardInfoPtr info);
|
||||
|
|
@ -90,7 +92,7 @@ protected slots:
|
|||
void cleanDeckAndResetModified();
|
||||
virtual void actLoadDeck();
|
||||
bool actSaveDeck();
|
||||
bool actSaveDeckAs();
|
||||
virtual bool actSaveDeckAs();
|
||||
virtual void actLoadDeckFromClipboard();
|
||||
void actEditDeckInClipboard();
|
||||
void actEditDeckInClipboardRaw();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
#include "edhrec_average_deck_api_response.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
|
||||
void EdhrecAverageDeckApiResponse::fromJson(const QJsonObject &json)
|
||||
{
|
||||
// Parse the collapsed DeckStatistics
|
||||
deckStats.fromJson(json);
|
||||
|
||||
// Parse Archidekt section
|
||||
QJsonArray archidektJson = json.value("archidekt").toArray();
|
||||
archidekt.fromJson(archidektJson);
|
||||
|
||||
// Parse other fields
|
||||
similar = json.value("similar").toObject();
|
||||
header = json.value("header").toString();
|
||||
panels = json.value("panels").toObject();
|
||||
description = json.value("description").toString();
|
||||
QJsonObject containerJson = json.value("container").toObject();
|
||||
container.fromJson(containerJson);
|
||||
QJsonArray cardsJson = json.value("deck").toArray();
|
||||
deck.fromJson(cardsJson);
|
||||
}
|
||||
|
||||
void EdhrecAverageDeckApiResponse::debugPrint() const
|
||||
{
|
||||
qDebug() << "Deck Statistics:";
|
||||
qDebug() << " Creature:" << deckStats.creature;
|
||||
qDebug() << " Instant:" << deckStats.instant;
|
||||
qDebug() << " Sorcery:" << deckStats.sorcery;
|
||||
qDebug() << " Artifact:" << deckStats.artifact;
|
||||
qDebug() << " Enchantment:" << deckStats.enchantment;
|
||||
qDebug() << " Battle:" << deckStats.battle;
|
||||
qDebug() << " Planeswalker:" << deckStats.planeswalker;
|
||||
qDebug() << " Land:" << deckStats.land;
|
||||
qDebug() << " Basic:" << deckStats.basic;
|
||||
qDebug() << " Nonbasic:" << deckStats.nonbasic;
|
||||
|
||||
archidekt.debugPrint();
|
||||
|
||||
qDebug() << "Similar:" << similar;
|
||||
qDebug() << "Header:" << header;
|
||||
qDebug() << "Panels:" << panels;
|
||||
qDebug() << "Description:" << description;
|
||||
container.debugPrint();
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef EDHREC_AVERAGE_DECK_API_RESPONSE_H
|
||||
#define EDHREC_AVERAGE_DECK_API_RESPONSE_H
|
||||
|
||||
#include "../commander/edhrec_commander_api_response_archidekt_links.h"
|
||||
#include "../commander/edhrec_commander_api_response_average_deck_statistics.h"
|
||||
#include "../commander/edhrec_commander_api_response_card_container.h"
|
||||
#include "edhrec_deck_api_response.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
// Represents the main structure of the JSON
|
||||
class EdhrecAverageDeckApiResponse
|
||||
{
|
||||
public:
|
||||
EdhrecCommanderApiResponseAverageDeckStatistics deckStats;
|
||||
EdhrecCommanderApiResponseArchidektLinks archidekt;
|
||||
QJsonObject similar;
|
||||
QString header;
|
||||
QJsonObject panels;
|
||||
QString description;
|
||||
EdhrecCommanderApiResponseCardContainer container;
|
||||
EdhrecDeckApiResponse deck;
|
||||
|
||||
void fromJson(const QJsonObject &json);
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // EDHREC_AVERAGE_DECK_API_RESPONSE_H
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#include "edhrec_deck_api_response.h"
|
||||
|
||||
#include "../../../../../../deck/deck_loader.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QMainWindow>
|
||||
|
||||
void EdhrecDeckApiResponse::fromJson(const QJsonArray &json)
|
||||
{
|
||||
QString deckList;
|
||||
for (const QJsonValue &cardlistValue : json) {
|
||||
deckList += cardlistValue.toString() + "\n";
|
||||
}
|
||||
|
||||
deckLoader = new DeckLoader();
|
||||
|
||||
QTextStream stream(&deckList);
|
||||
deckLoader->loadFromStream_Plain(stream, true);
|
||||
}
|
||||
|
||||
void EdhrecDeckApiResponse::debugPrint() const
|
||||
{
|
||||
qDebug() << "Breadcrumb:";
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
#ifndef EDHREC_DECK_API_RESPONSE_H
|
||||
#define EDHREC_DECK_API_RESPONSE_H
|
||||
|
||||
#include "../../../../../../deck/deck_loader.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
#include <QVector>
|
||||
|
||||
class EdhrecDeckApiResponse
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
EdhrecDeckApiResponse() = default;
|
||||
|
||||
// Parse deck-related data from JSON
|
||||
void fromJson(const QJsonArray &json);
|
||||
|
||||
// Debug method for logging
|
||||
void debugPrint() const;
|
||||
|
||||
DeckLoader *deckLoader;
|
||||
};
|
||||
|
||||
#endif // EDHREC_DECK_API_RESPONSE_H
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include "edhrec_top_cards_api_response.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
|
||||
void EdhrecTopCardsApiResponse::fromJson(const QJsonObject &json)
|
||||
{
|
||||
header = json.value("header").toString();
|
||||
description = json.value("description").toString();
|
||||
QJsonObject containerJson = json.value("container").toObject();
|
||||
container.fromJson(containerJson);
|
||||
}
|
||||
|
||||
void EdhrecTopCardsApiResponse::debugPrint() const
|
||||
{
|
||||
qDebug() << "Header:" << header;
|
||||
qDebug() << "Description:" << description;
|
||||
container.debugPrint();
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef EDHREC_TOP_CARDS_API_RESPONSE_H
|
||||
#define EDHREC_TOP_CARDS_API_RESPONSE_H
|
||||
|
||||
#include "../commander/edhrec_commander_api_response_card_container.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
// Represents the main structure of the JSON
|
||||
class EdhrecTopCardsApiResponse
|
||||
{
|
||||
public:
|
||||
QString header;
|
||||
QString description;
|
||||
EdhrecCommanderApiResponseCardContainer container;
|
||||
|
||||
void fromJson(const QJsonObject &json);
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // EDHREC_TOP_CARDS_API_RESPONSE_H
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include "edhrec_top_commanders_api_response.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
|
||||
void EdhrecTopCommandersApiResponse::fromJson(const QJsonObject &json)
|
||||
{
|
||||
header = json.value("header").toString();
|
||||
description = json.value("description").toString();
|
||||
QJsonObject containerJson = json.value("container").toObject();
|
||||
container.fromJson(containerJson);
|
||||
}
|
||||
|
||||
void EdhrecTopCommandersApiResponse::debugPrint() const
|
||||
{
|
||||
qDebug() << "Header:" << header;
|
||||
qDebug() << "Description:" << description;
|
||||
container.debugPrint();
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef EDHREC_TOP_COMMANDERS_API_RESPONSE_H
|
||||
#define EDHREC_TOP_COMMANDERS_API_RESPONSE_H
|
||||
|
||||
#include "../commander/edhrec_commander_api_response_card_container.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
// Represents the main structure of the JSON
|
||||
class EdhrecTopCommandersApiResponse
|
||||
{
|
||||
public:
|
||||
QString header;
|
||||
QString description;
|
||||
EdhrecCommanderApiResponseCardContainer container;
|
||||
|
||||
void fromJson(const QJsonObject &json);
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // EDHREC_TOP_COMMANDERS_API_RESPONSE_H
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#include "edhrec_top_tags_api_response.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
|
||||
void EdhrecTopTagsApiResponse::fromJson(const QJsonObject &json)
|
||||
{
|
||||
header = json.value("header").toString();
|
||||
description = json.value("description").toString();
|
||||
QJsonObject containerJson = json.value("container").toObject();
|
||||
container.fromJson(containerJson);
|
||||
}
|
||||
|
||||
void EdhrecTopTagsApiResponse::debugPrint() const
|
||||
{
|
||||
qDebug() << "Header:" << header;
|
||||
qDebug() << "Description:" << description;
|
||||
container.debugPrint();
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
#ifndef EDHREC_TOP_TAGS_API_RESPONSE_H
|
||||
#define EDHREC_TOP_TAGS_API_RESPONSE_H
|
||||
|
||||
#include "../commander/edhrec_commander_api_response_card_container.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QJsonObject>
|
||||
#include <QString>
|
||||
|
||||
// Represents the main structure of the JSON
|
||||
class EdhrecTopTagsApiResponse
|
||||
{
|
||||
public:
|
||||
QString header;
|
||||
QString description;
|
||||
EdhrecCommanderApiResponseCardContainer container;
|
||||
|
||||
void fromJson(const QJsonObject &json);
|
||||
void debugPrint() const;
|
||||
};
|
||||
|
||||
#endif // EDHREC_TOP_TAGS_API_RESPONSE_H
|
||||
|
|
@ -1,6 +1,7 @@
|
|||
#include "edhrec_commander_api_response_card_details_display_widget.h"
|
||||
|
||||
#include "../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../../../../game/cards/card_database_manager.h"
|
||||
#include "../../tab_edhrec_main.h"
|
||||
|
||||
EdhrecCommanderApiResponseCardDetailsDisplayWidget::EdhrecCommanderApiResponseCardDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
|
|
@ -11,14 +12,17 @@ EdhrecCommanderApiResponseCardDetailsDisplayWidget::EdhrecCommanderApiResponseCa
|
|||
setLayout(layout);
|
||||
|
||||
cardPictureWidget = new CardInfoPictureWidget(this);
|
||||
cardPictureWidget->setCard(CardDatabaseManager::getInstance()->getCard(toDisplay.name));
|
||||
cardPictureWidget->setCard(CardDatabaseManager::getInstance()->guessCard(toDisplay.sanitized));
|
||||
|
||||
label = new QLabel(this);
|
||||
label->setText(toDisplay.name + "\n" + toDisplay.label);
|
||||
label->setAlignment(Qt::AlignHCenter);
|
||||
|
||||
int inclusionRate = 0;
|
||||
// Set label color based on inclusion rate
|
||||
int inclusionRate = (toDisplay.numDecks * 100) / toDisplay.potentialDecks;
|
||||
if (toDisplay.potentialDecks != 0) {
|
||||
inclusionRate = (toDisplay.numDecks * 100) / toDisplay.potentialDecks;
|
||||
}
|
||||
|
||||
QColor labelColor;
|
||||
if (inclusionRate <= 30) {
|
||||
|
|
@ -38,4 +42,26 @@ EdhrecCommanderApiResponseCardDetailsDisplayWidget::EdhrecCommanderApiResponseCa
|
|||
|
||||
layout->addWidget(cardPictureWidget);
|
||||
layout->addWidget(label);
|
||||
|
||||
QWidget *currentParent = parentWidget();
|
||||
TabEdhRecMain *parentTab = nullptr;
|
||||
|
||||
while (currentParent) {
|
||||
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
|
||||
break;
|
||||
}
|
||||
currentParent = currentParent->parentWidget();
|
||||
}
|
||||
|
||||
if (parentTab) {
|
||||
connect(cardPictureWidget, &CardInfoPictureWidget::cardClicked, this,
|
||||
&EdhrecCommanderApiResponseCardDetailsDisplayWidget::actRequestPageNavigation);
|
||||
connect(this, &EdhrecCommanderApiResponseCardDetailsDisplayWidget::requestUrl, parentTab,
|
||||
&TabEdhRecMain::actNavigatePage);
|
||||
}
|
||||
}
|
||||
|
||||
void EdhrecCommanderApiResponseCardDetailsDisplayWidget::actRequestPageNavigation()
|
||||
{
|
||||
emit requestUrl(toDisplay.url);
|
||||
}
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_CARD_DETAILS_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response_card_details.h"
|
||||
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../../api_response/commander/edhrec_commander_api_response_card_details.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
|
|
@ -15,6 +15,10 @@ public:
|
|||
explicit EdhrecCommanderApiResponseCardDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
const EdhrecCommanderApiResponseCardDetails &_toDisplay);
|
||||
public slots:
|
||||
void actRequestPageNavigation();
|
||||
signals:
|
||||
void requestUrl(QString url);
|
||||
|
||||
private:
|
||||
EdhrecCommanderApiResponseCardDetails toDisplay;
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
#include "edhrec_commander_api_response_card_list_display_widget.h"
|
||||
|
||||
#include "../../../ui/widgets/general/display/banner_widget.h"
|
||||
#include "../../../../../ui/widgets/general/display/banner_widget.h"
|
||||
#include "edhrec_commander_api_response_card_details_display_widget.h"
|
||||
|
||||
#include <QLabel>
|
||||
|
|
@ -1,9 +1,9 @@
|
|||
#ifndef EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_CARD_LIST_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../ui/widgets/general/display/banner_widget.h"
|
||||
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response_card_list.h"
|
||||
#include "../../../../../ui/widgets/general/display/banner_widget.h"
|
||||
#include "../../../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "../../api_response/commander/edhrec_commander_api_response_card_list.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
#include "edhrec_commander_api_response_commander_details_display_widget.h"
|
||||
|
||||
#include "../../../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../../tab_edhrec_main.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
|
||||
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails)
|
||||
: QWidget(parent), commanderDetails(_commanderDetails)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
commanderPicture = new CardInfoPictureWidget(this);
|
||||
commanderPicture->setCard(CardDatabaseManager::getInstance()->getCard(commanderDetails.getName()));
|
||||
|
||||
commanderDetails.debugPrint();
|
||||
|
||||
label = new QLabel(this);
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
salt = new QLabel(this);
|
||||
salt->setAlignment(Qt::AlignCenter);
|
||||
|
||||
comboPushButton = new QPushButton(this);
|
||||
averageDeckPushButton = new QPushButton(this);
|
||||
|
||||
layout->addWidget(commanderPicture);
|
||||
layout->addWidget(label);
|
||||
layout->addWidget(salt);
|
||||
layout->addWidget(comboPushButton);
|
||||
layout->addWidget(averageDeckPushButton);
|
||||
|
||||
QWidget *currentParent = parentWidget();
|
||||
TabEdhRecMain *parentTab = nullptr;
|
||||
|
||||
while (currentParent) {
|
||||
if ((parentTab = qobject_cast<TabEdhRecMain *>(currentParent))) {
|
||||
break;
|
||||
}
|
||||
currentParent = currentParent->parentWidget();
|
||||
}
|
||||
|
||||
if (parentTab) {
|
||||
connect(comboPushButton, &QPushButton::clicked, this,
|
||||
&EdhrecCommanderResponseCommanderDetailsDisplayWidget::actRequestComboNavigation);
|
||||
connect(averageDeckPushButton, &QPushButton::clicked, this,
|
||||
&EdhrecCommanderResponseCommanderDetailsDisplayWidget::actRequestAverageDeckNavigation);
|
||||
connect(this, &EdhrecCommanderResponseCommanderDetailsDisplayWidget::requestUrl, parentTab,
|
||||
&TabEdhRecMain::actNavigatePage);
|
||||
}
|
||||
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void EdhrecCommanderResponseCommanderDetailsDisplayWidget::retranslateUi()
|
||||
{
|
||||
label->setText(commanderDetails.getLabel());
|
||||
salt->setText(tr("Salt: ") + QString::number(commanderDetails.getSalt()));
|
||||
comboPushButton->setText(tr("Combos"));
|
||||
averageDeckPushButton->setText(tr("Average Deck"));
|
||||
}
|
||||
|
||||
void EdhrecCommanderResponseCommanderDetailsDisplayWidget::actRequestComboNavigation()
|
||||
{
|
||||
emit requestUrl("/combos/" + commanderDetails.getSanitized());
|
||||
}
|
||||
|
||||
void EdhrecCommanderResponseCommanderDetailsDisplayWidget::actRequestAverageDeckNavigation()
|
||||
{
|
||||
emit requestUrl("/average-decks/" + commanderDetails.getSanitized());
|
||||
}
|
||||
|
|
@ -1,10 +1,11 @@
|
|||
#ifndef EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_COMMANDER_DETAILS_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response_commander_details.h"
|
||||
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../../api_response/commander/edhrec_commander_api_response_commander_details.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
|
|
@ -17,9 +18,17 @@ public:
|
|||
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails);
|
||||
void retranslateUi();
|
||||
|
||||
public slots:
|
||||
void actRequestComboNavigation();
|
||||
void actRequestAverageDeckNavigation();
|
||||
signals:
|
||||
void requestUrl(QString url);
|
||||
|
||||
private:
|
||||
QLabel *label;
|
||||
QLabel *salt;
|
||||
QPushButton *comboPushButton;
|
||||
QPushButton *averageDeckPushButton;
|
||||
QVBoxLayout *layout;
|
||||
CardInfoPictureWidget *commanderPicture;
|
||||
EdhrecCommanderApiResponseCommanderDetails commanderDetails;
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include "edhrec_commander_api_response_display_widget.h"
|
||||
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "api_response/edhrec_commander_api_response.h"
|
||||
#include "../../../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
#include "../../api_response/commander/edhrec_commander_api_response.h"
|
||||
#include "edhrec_commander_api_response_card_list_display_widget.h"
|
||||
#include "edhrec_commander_api_response_commander_details_display_widget.h"
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
#define EDHREC_COMMANDER_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "api_response/edhrec_commander_api_response.h"
|
||||
#include "../../api_response/commander/edhrec_commander_api_response.h"
|
||||
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#include "edhrec_top_cards_api_response_display_widget.h"
|
||||
|
||||
#include "../../api_response/top_cards/edhrec_top_cards_api_response.h"
|
||||
#include "../commander/edhrec_commander_api_response_card_list_display_widget.h"
|
||||
|
||||
EdhrecTopCardsApiResponseDisplayWidget::EdhrecTopCardsApiResponseDisplayWidget(QWidget *parent,
|
||||
EdhrecTopCardsApiResponse response)
|
||||
: QWidget(parent)
|
||||
{
|
||||
layout = new QHBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
cardDisplayLayout = new QVBoxLayout(this);
|
||||
|
||||
// Add card list widgets
|
||||
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||
for (const EdhrecCommanderApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||
auto cardListDisplayWidget = new EdhrecCommanderApiResponseCardListDisplayWidget(this, card_list);
|
||||
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||
}
|
||||
|
||||
// Create a QScrollArea to hold the card display widgets
|
||||
scrollArea = new QScrollArea(this);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
// Set the cardDisplayLayout inside the scroll area
|
||||
auto scrollWidget = new QWidget(scrollArea);
|
||||
scrollWidget->setLayout(cardDisplayLayout);
|
||||
scrollArea->setWidget(scrollWidget);
|
||||
|
||||
layout->addWidget(scrollArea);
|
||||
}
|
||||
|
||||
void EdhrecTopCardsApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
layout->invalidate();
|
||||
layout->activate();
|
||||
layout->update();
|
||||
if (scrollArea && scrollArea->widget()) {
|
||||
scrollArea->widget()->resize(event->size());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
#define EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../api_response/top_cards/edhrec_top_cards_api_response.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class EdhrecTopCardsApiResponseDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EdhrecTopCardsApiResponseDisplayWidget(QWidget *parent, EdhrecTopCardsApiResponse response);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
QHBoxLayout *layout;
|
||||
QVBoxLayout *cardDisplayLayout;
|
||||
QScrollArea *scrollArea;
|
||||
};
|
||||
|
||||
#endif // EDHREC_TOP_CARDS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
#include "edhrec_top_commanders_api_response_display_widget.h"
|
||||
|
||||
#include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h"
|
||||
#include "../commander/edhrec_commander_api_response_card_list_display_widget.h"
|
||||
|
||||
EdhrecTopCommandersApiResponseDisplayWidget::EdhrecTopCommandersApiResponseDisplayWidget(
|
||||
QWidget *parent,
|
||||
EdhrecTopCommandersApiResponse response)
|
||||
: QWidget(parent)
|
||||
{
|
||||
layout = new QHBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
cardDisplayLayout = new QVBoxLayout(this);
|
||||
|
||||
// Add card list widgets
|
||||
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||
for (const EdhrecCommanderApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||
auto cardListDisplayWidget = new EdhrecCommanderApiResponseCardListDisplayWidget(this, card_list);
|
||||
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||
}
|
||||
|
||||
// Create a QScrollArea to hold the card display widgets
|
||||
scrollArea = new QScrollArea(this);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
// Set the cardDisplayLayout inside the scroll area
|
||||
auto scrollWidget = new QWidget(scrollArea);
|
||||
scrollWidget->setLayout(cardDisplayLayout);
|
||||
scrollArea->setWidget(scrollWidget);
|
||||
|
||||
layout->addWidget(scrollArea);
|
||||
}
|
||||
|
||||
void EdhrecTopCommandersApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
qDebug() << event->size();
|
||||
layout->invalidate();
|
||||
layout->activate();
|
||||
layout->update();
|
||||
if (scrollArea && scrollArea->widget()) {
|
||||
scrollArea->widget()->resize(event->size());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
#define EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../api_response/top_commanders/edhrec_top_commanders_api_response.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class EdhrecTopCommandersApiResponseDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EdhrecTopCommandersApiResponseDisplayWidget(QWidget *parent, EdhrecTopCommandersApiResponse response);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
QHBoxLayout *layout;
|
||||
QVBoxLayout *cardDisplayLayout;
|
||||
QScrollArea *scrollArea;
|
||||
};
|
||||
|
||||
#endif // EDHREC_TOP_COMMANDERS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
#include "edhrec_top_tags_api_response_display_widget.h"
|
||||
|
||||
#include "../../api_response/top_tags/edhrec_top_tags_api_response.h"
|
||||
#include "../commander/edhrec_commander_api_response_card_list_display_widget.h"
|
||||
|
||||
EdhrecTopTagsApiResponseDisplayWidget::EdhrecTopTagsApiResponseDisplayWidget(QWidget *parent,
|
||||
EdhrecTopTagsApiResponse response)
|
||||
: QWidget(parent)
|
||||
{
|
||||
layout = new QHBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
cardDisplayLayout = new QVBoxLayout(this);
|
||||
|
||||
// Add card list widgets
|
||||
auto edhrec_commander_api_response_card_lists = response.container.getCardlists();
|
||||
for (const EdhrecCommanderApiResponseCardList &card_list : edhrec_commander_api_response_card_lists) {
|
||||
auto cardListDisplayWidget = new EdhrecCommanderApiResponseCardListDisplayWidget(this, card_list);
|
||||
cardDisplayLayout->addWidget(cardListDisplayWidget);
|
||||
}
|
||||
|
||||
// Create a QScrollArea to hold the card display widgets
|
||||
scrollArea = new QScrollArea(this);
|
||||
scrollArea->setWidgetResizable(true);
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
|
||||
// Set the cardDisplayLayout inside the scroll area
|
||||
auto scrollWidget = new QWidget(scrollArea);
|
||||
scrollWidget->setLayout(cardDisplayLayout);
|
||||
scrollArea->setWidget(scrollWidget);
|
||||
|
||||
layout->addWidget(scrollArea);
|
||||
}
|
||||
|
||||
void EdhrecTopTagsApiResponseDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
layout->invalidate();
|
||||
layout->activate();
|
||||
layout->update();
|
||||
if (scrollArea && scrollArea->widget()) {
|
||||
scrollArea->widget()->resize(event->size());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#ifndef EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
#define EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../api_response/top_tags/edhrec_top_tags_api_response.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
#include <QScrollArea>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class EdhrecTopTagsApiResponseDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit EdhrecTopTagsApiResponseDisplayWidget(QWidget *parent, EdhrecTopTagsApiResponse response);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
private:
|
||||
QHBoxLayout *layout;
|
||||
QVBoxLayout *cardDisplayLayout;
|
||||
QScrollArea *scrollArea;
|
||||
};
|
||||
|
||||
#endif // EDHREC_TOP_TAGS_API_RESPONSE_DISPLAY_WIDGET_H
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#include "edhrec_commander_api_response_commander_details_display_widget.h"
|
||||
|
||||
#include "../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../ui/widgets/cards/card_info_picture_widget.h"
|
||||
|
||||
#include <QLabel>
|
||||
|
||||
EdhrecCommanderResponseCommanderDetailsDisplayWidget::EdhrecCommanderResponseCommanderDetailsDisplayWidget(
|
||||
QWidget *parent,
|
||||
const EdhrecCommanderApiResponseCommanderDetails &_commanderDetails)
|
||||
: QWidget(parent), commanderDetails(_commanderDetails)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
commanderPicture = new CardInfoPictureWidget(this);
|
||||
commanderPicture->setCard(CardDatabaseManager::getInstance()->getCard(commanderDetails.getName()));
|
||||
|
||||
commanderDetails.debugPrint();
|
||||
|
||||
label = new QLabel(this);
|
||||
label->setAlignment(Qt::AlignCenter);
|
||||
salt = new QLabel(this);
|
||||
salt->setAlignment(Qt::AlignCenter);
|
||||
|
||||
layout->addWidget(commanderPicture);
|
||||
layout->addWidget(label);
|
||||
layout->addWidget(salt);
|
||||
retranslateUi();
|
||||
}
|
||||
|
||||
void EdhrecCommanderResponseCommanderDetailsDisplayWidget::retranslateUi()
|
||||
{
|
||||
label->setText(commanderDetails.getLabel());
|
||||
salt->setText(tr("Salt: ") + QString::number(commanderDetails.getSalt()));
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include "tab_edhrec.h"
|
||||
|
||||
#include "api_response/edhrec_commander_api_response.h"
|
||||
#include "edhrec_commander_api_response_display_widget.h"
|
||||
#include "api_response/commander/edhrec_commander_api_response.h"
|
||||
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
|
|
@ -21,7 +21,7 @@ TabEdhRec::TabEdhRec(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
|||
#endif
|
||||
|
||||
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(processApiJson(QNetworkReply *)));
|
||||
connect(networkManager, &QNetworkAccessManager::finished, this, &TabEdhRec::processApiJson);
|
||||
}
|
||||
|
||||
void TabEdhRec::retranslateUi()
|
||||
|
|
|
|||
|
|
@ -1,12 +1,11 @@
|
|||
#ifndef TAB_EDHREC_H
|
||||
#define TAB_EDHREC_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../../game/cards/card_info.h"
|
||||
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "../../tab.h"
|
||||
#include "edhrec_commander_api_response_display_widget.h"
|
||||
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QNetworkAccessManager>
|
||||
|
||||
class TabEdhRec : public Tab
|
||||
|
|
|
|||
378
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.cpp
Normal file
378
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.cpp
Normal file
|
|
@ -0,0 +1,378 @@
|
|||
#include "tab_edhrec_main.h"
|
||||
|
||||
#include "../../../../game/cards/card_completer_proxy_model.h"
|
||||
#include "../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../../game/cards/card_search_model.h"
|
||||
#include "../../tab_supervisor.h"
|
||||
#include "api_response/average_deck/edhrec_average_deck_api_response.h"
|
||||
#include "api_response/commander/edhrec_commander_api_response.h"
|
||||
#include "api_response/top_cards/edhrec_top_cards_api_response.h"
|
||||
#include "api_response/top_commanders/edhrec_top_commanders_api_response.h"
|
||||
#include "api_response/top_tags/edhrec_top_tags_api_response.h"
|
||||
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||
#include "display/top_cards/edhrec_top_cards_api_response_display_widget.h"
|
||||
#include "display/top_commander/edhrec_top_commanders_api_response_display_widget.h"
|
||||
#include "display/top_tags/edhrec_top_tags_api_response_display_widget.h"
|
||||
|
||||
#include <QCompleter>
|
||||
#include <QDebug>
|
||||
#include <QHBoxLayout>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QPushButton>
|
||||
#include <QRegularExpression>
|
||||
#include <QResizeEvent>
|
||||
|
||||
static bool canBeCommander(const CardInfoPtr &cardInfo)
|
||||
{
|
||||
return ((cardInfo->getCardType().contains("Legendary", Qt::CaseInsensitive) &&
|
||||
cardInfo->getCardType().contains("Creature", Qt::CaseInsensitive))) ||
|
||||
cardInfo->getText().contains("can be your commander", Qt::CaseInsensitive);
|
||||
}
|
||||
|
||||
TabEdhRecMain::TabEdhRecMain(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||
{
|
||||
networkManager = new QNetworkAccessManager(this);
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(5, 15, 0))
|
||||
networkManager->setTransferTimeout(); // Use Qt's default timeout
|
||||
#endif
|
||||
|
||||
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(processApiJson(QNetworkReply *)));
|
||||
|
||||
container = new QWidget(this);
|
||||
mainLayout = new QVBoxLayout(container);
|
||||
container->setLayout(mainLayout);
|
||||
|
||||
navigationContainer = new QWidget(container);
|
||||
navigationContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
navigationLayout = new QHBoxLayout(navigationContainer);
|
||||
navigationLayout->setSpacing(5);
|
||||
navigationContainer->setLayout(navigationLayout);
|
||||
|
||||
cardsPushButton = new QPushButton(navigationContainer);
|
||||
connect(cardsPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopCards);
|
||||
topCommandersPushButton = new QPushButton(navigationContainer);
|
||||
connect(topCommandersPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopCommanders);
|
||||
tagsPushButton = new QPushButton(navigationContainer);
|
||||
connect(tagsPushButton, &QPushButton::clicked, this, &TabEdhRecMain::getTopTags);
|
||||
|
||||
searchBar = new QLineEdit(this);
|
||||
auto cardDatabaseModel = new CardDatabaseModel(CardDatabaseManager::getInstance(), false, this);
|
||||
auto displayModel = new CardDatabaseDisplayModel(this);
|
||||
displayModel->setSourceModel(cardDatabaseModel);
|
||||
CardSearchModel *searchModel = new CardSearchModel(displayModel, this);
|
||||
|
||||
CardCompleterProxyModel *proxyModel = new CardCompleterProxyModel(this);
|
||||
proxyModel->setSourceModel(searchModel);
|
||||
proxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive);
|
||||
proxyModel->setFilterRole(Qt::DisplayRole);
|
||||
|
||||
QCompleter *completer = new QCompleter(proxyModel, this);
|
||||
completer->setCompletionRole(Qt::DisplayRole);
|
||||
completer->setCompletionMode(QCompleter::PopupCompletion);
|
||||
completer->setCaseSensitivity(Qt::CaseInsensitive);
|
||||
completer->setFilterMode(Qt::MatchContains);
|
||||
completer->setMaxVisibleItems(10);
|
||||
searchBar->setCompleter(completer);
|
||||
|
||||
// Update suggestions dynamically
|
||||
connect(searchBar, &QLineEdit::textChanged, searchModel, &CardSearchModel::updateSearchResults);
|
||||
connect(searchBar, &QLineEdit::textChanged, this, [=](const QString &text) {
|
||||
// Ensure substring matching
|
||||
QString pattern = ".*" + QRegularExpression::escape(text) + ".*";
|
||||
proxyModel->setFilterRegularExpression(QRegularExpression(pattern, QRegularExpression::CaseInsensitiveOption));
|
||||
|
||||
if (!text.isEmpty()) {
|
||||
completer->complete(); // Force the dropdown to appear
|
||||
}
|
||||
});
|
||||
|
||||
searchPushButton = new QPushButton(navigationContainer);
|
||||
connect(searchPushButton, &QPushButton::clicked, this, [=, this]() { doSearch(); });
|
||||
|
||||
navigationLayout->addWidget(cardsPushButton);
|
||||
navigationLayout->addWidget(topCommandersPushButton);
|
||||
navigationLayout->addWidget(tagsPushButton);
|
||||
navigationLayout->addWidget(searchBar);
|
||||
navigationLayout->addWidget(searchPushButton);
|
||||
|
||||
currentPageDisplay = new QWidget(container);
|
||||
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||
currentPageDisplay->setLayout(currentPageLayout);
|
||||
|
||||
mainLayout->addWidget(navigationContainer);
|
||||
mainLayout->addWidget(currentPageDisplay);
|
||||
|
||||
// Ensure navigation stays at the top and currentPageDisplay takes remaining space
|
||||
mainLayout->setStretch(0, 0); // navigationContainer gets minimum space
|
||||
mainLayout->setStretch(1, 1); // currentPageDisplay expands as much as possible
|
||||
|
||||
setCentralWidget(container);
|
||||
|
||||
TabEdhRecMain::retranslateUi();
|
||||
|
||||
getTopCards();
|
||||
}
|
||||
|
||||
void TabEdhRecMain::retranslateUi()
|
||||
{
|
||||
cardsPushButton->setText(tr("&Cards"));
|
||||
topCommandersPushButton->setText(tr("Top Commanders"));
|
||||
tagsPushButton->setText(tr("Tags"));
|
||||
searchBar->setPlaceholderText(tr("Search for a card ..."));
|
||||
searchPushButton->setText(tr("Search"));
|
||||
}
|
||||
|
||||
void TabEdhRecMain::doSearch()
|
||||
{
|
||||
CardInfoPtr searchedCard = CardDatabaseManager::getInstance()->getCard(searchBar->text());
|
||||
if (!searchedCard) {
|
||||
return;
|
||||
}
|
||||
|
||||
setCard(searchedCard, canBeCommander(searchedCard));
|
||||
}
|
||||
|
||||
void TabEdhRecMain::setCard(CardInfoPtr _cardToQuery, bool isCommander)
|
||||
{
|
||||
cardToQuery = _cardToQuery;
|
||||
|
||||
if (!cardToQuery) {
|
||||
qDebug() << "Invalid card information provided.";
|
||||
return;
|
||||
}
|
||||
|
||||
QString cardName = cardToQuery->getName();
|
||||
QString formattedName = cardName.toLower().replace(" ", "-").remove(QRegularExpression("[^a-z0-9\\-]"));
|
||||
|
||||
QString url;
|
||||
if (isCommander) {
|
||||
url = QString("https://json.edhrec.com/pages/commanders/%1.json").arg(formattedName);
|
||||
} else {
|
||||
url = QString("https://json.edhrec.com/pages/cards/%1.json").arg(formattedName);
|
||||
}
|
||||
|
||||
QNetworkRequest request{QUrl(url)};
|
||||
|
||||
networkManager->get(request);
|
||||
}
|
||||
|
||||
void TabEdhRecMain::actNavigatePage(QString url)
|
||||
{
|
||||
QNetworkRequest request{QUrl("https://json.edhrec.com/pages" + url + ".json")};
|
||||
|
||||
networkManager->get(request);
|
||||
}
|
||||
|
||||
void TabEdhRecMain::getTopCards()
|
||||
{
|
||||
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/top/year.json")};
|
||||
|
||||
networkManager->get(request);
|
||||
}
|
||||
|
||||
void TabEdhRecMain::getTopCommanders()
|
||||
{
|
||||
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/commanders/year.json")};
|
||||
|
||||
networkManager->get(request);
|
||||
}
|
||||
|
||||
void TabEdhRecMain::getTopTags()
|
||||
{
|
||||
QNetworkRequest request{QUrl("https://json.edhrec.com/pages/tags.json")};
|
||||
|
||||
networkManager->get(request);
|
||||
}
|
||||
|
||||
void TabEdhRecMain::processApiJson(QNetworkReply *reply)
|
||||
{
|
||||
if (reply->error() != QNetworkReply::NoError) {
|
||||
qDebug() << "Network error occurred:" << reply->errorString();
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray responseData = reply->readAll();
|
||||
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
|
||||
|
||||
if (!jsonDoc.isObject()) {
|
||||
qDebug() << "Invalid JSON response received.";
|
||||
reply->deleteLater();
|
||||
return;
|
||||
}
|
||||
|
||||
QJsonObject jsonObj = jsonDoc.object();
|
||||
|
||||
// Get the actual URL from the reply
|
||||
QString responseUrl = reply->url().toString();
|
||||
|
||||
// Check if the response URL matches a commander request
|
||||
if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/year.json")) {
|
||||
processTopCommandersResponse(jsonObj);
|
||||
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/commanders/")) {
|
||||
processCommanderResponse(jsonObj);
|
||||
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/cards/")) {
|
||||
processCommanderResponse(jsonObj);
|
||||
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags/")) {
|
||||
processCommanderResponse(jsonObj);
|
||||
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/tags.json")) {
|
||||
processTopTagsResponse(jsonObj);
|
||||
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/top/year.json")) {
|
||||
processTopCardsResponse(jsonObj);
|
||||
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/combos/")) {
|
||||
processCommanderResponse(jsonObj);
|
||||
} else if (responseUrl.startsWith("https://json.edhrec.com/pages/average-decks/")) {
|
||||
processAverageDeckResponse(jsonObj);
|
||||
} else {
|
||||
prettyPrintJson(jsonObj, 4);
|
||||
}
|
||||
|
||||
reply->deleteLater();
|
||||
}
|
||||
|
||||
void TabEdhRecMain::processTopCardsResponse(QJsonObject reply)
|
||||
{
|
||||
EdhrecTopCardsApiResponse deckData;
|
||||
deckData.fromJson(reply);
|
||||
|
||||
// **Remove previous page display to prevent stacking**
|
||||
if (currentPageDisplay) {
|
||||
mainLayout->removeWidget(currentPageDisplay);
|
||||
delete currentPageDisplay;
|
||||
currentPageDisplay = nullptr;
|
||||
}
|
||||
|
||||
// **Create new currentPageDisplay**
|
||||
currentPageDisplay = new QWidget(container);
|
||||
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||
currentPageDisplay->setLayout(currentPageLayout);
|
||||
|
||||
auto display = new EdhrecTopCardsApiResponseDisplayWidget(currentPageDisplay, deckData);
|
||||
currentPageLayout->addWidget(display);
|
||||
|
||||
mainLayout->addWidget(currentPageDisplay);
|
||||
|
||||
// **Ensure layout stays correct**
|
||||
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||
}
|
||||
|
||||
void TabEdhRecMain::processTopTagsResponse(QJsonObject reply)
|
||||
{
|
||||
EdhrecTopTagsApiResponse deckData;
|
||||
deckData.fromJson(reply);
|
||||
|
||||
// **Remove previous page display to prevent stacking**
|
||||
if (currentPageDisplay) {
|
||||
mainLayout->removeWidget(currentPageDisplay);
|
||||
delete currentPageDisplay;
|
||||
currentPageDisplay = nullptr;
|
||||
}
|
||||
|
||||
// **Create new currentPageDisplay**
|
||||
currentPageDisplay = new QWidget(container);
|
||||
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||
currentPageDisplay->setLayout(currentPageLayout);
|
||||
|
||||
auto display = new EdhrecTopTagsApiResponseDisplayWidget(currentPageDisplay, deckData);
|
||||
currentPageLayout->addWidget(display);
|
||||
|
||||
mainLayout->addWidget(currentPageDisplay);
|
||||
|
||||
// **Ensure layout stays correct**
|
||||
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||
}
|
||||
|
||||
void TabEdhRecMain::processTopCommandersResponse(QJsonObject reply)
|
||||
{
|
||||
EdhrecTopCommandersApiResponse deckData;
|
||||
deckData.fromJson(reply);
|
||||
|
||||
// **Remove previous page display to prevent stacking**
|
||||
if (currentPageDisplay) {
|
||||
mainLayout->removeWidget(currentPageDisplay);
|
||||
delete currentPageDisplay;
|
||||
currentPageDisplay = nullptr;
|
||||
}
|
||||
|
||||
// **Create new currentPageDisplay**
|
||||
currentPageDisplay = new QWidget(container);
|
||||
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||
currentPageDisplay->setLayout(currentPageLayout);
|
||||
|
||||
auto display = new EdhrecTopCommandersApiResponseDisplayWidget(currentPageDisplay, deckData);
|
||||
currentPageLayout->addWidget(display);
|
||||
|
||||
mainLayout->addWidget(currentPageDisplay);
|
||||
|
||||
// **Ensure layout stays correct**
|
||||
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||
}
|
||||
|
||||
void TabEdhRecMain::processCommanderResponse(QJsonObject reply)
|
||||
{
|
||||
EdhrecCommanderApiResponse deckData;
|
||||
deckData.fromJson(reply);
|
||||
|
||||
// **Remove previous page display to prevent stacking**
|
||||
if (currentPageDisplay) {
|
||||
mainLayout->removeWidget(currentPageDisplay);
|
||||
delete currentPageDisplay;
|
||||
currentPageDisplay = nullptr;
|
||||
}
|
||||
|
||||
// **Create new currentPageDisplay**
|
||||
currentPageDisplay = new QWidget(container);
|
||||
currentPageLayout = new QVBoxLayout(currentPageDisplay);
|
||||
currentPageDisplay->setLayout(currentPageLayout);
|
||||
|
||||
auto display = new EdhrecCommanderApiResponseDisplayWidget(currentPageDisplay, deckData);
|
||||
currentPageLayout->addWidget(display);
|
||||
|
||||
mainLayout->addWidget(currentPageDisplay);
|
||||
|
||||
// **Ensure layout stays correct**
|
||||
mainLayout->setStretch(0, 0); // Keep navigationContainer at the top
|
||||
mainLayout->setStretch(1, 1); // Make sure currentPageDisplay takes remaining space
|
||||
}
|
||||
|
||||
void TabEdhRecMain::processAverageDeckResponse(QJsonObject reply)
|
||||
{
|
||||
EdhrecAverageDeckApiResponse deckData;
|
||||
deckData.fromJson(reply);
|
||||
tabSupervisor->addVisualDeckEditorTab(deckData.deck.deckLoader);
|
||||
}
|
||||
|
||||
void TabEdhRecMain::prettyPrintJson(const QJsonValue &value, int indentLevel)
|
||||
{
|
||||
const QString indent(indentLevel * 2, ' '); // Adjust spacing as needed for pretty printing
|
||||
|
||||
if (value.isObject()) {
|
||||
QJsonObject obj = value.toObject();
|
||||
for (auto it = obj.begin(); it != obj.end(); ++it) {
|
||||
qDebug().noquote() << indent + it.key() + ":";
|
||||
prettyPrintJson(it.value(), indentLevel + 1);
|
||||
}
|
||||
} else if (value.isArray()) {
|
||||
QJsonArray array = value.toArray();
|
||||
for (int i = 0; i < array.size(); ++i) {
|
||||
qDebug().noquote() << indent + QString("[%1]:").arg(i);
|
||||
prettyPrintJson(array[i], indentLevel + 1);
|
||||
}
|
||||
} else if (value.isString()) {
|
||||
qDebug().noquote() << indent + "\"" + value.toString() + "\"";
|
||||
} else if (value.isDouble()) {
|
||||
qDebug().noquote() << indent + QString::number(value.toDouble());
|
||||
} else if (value.isBool()) {
|
||||
qDebug().noquote() << indent + (value.toBool() ? "true" : "false");
|
||||
} else if (value.isNull()) {
|
||||
qDebug().noquote() << indent + "null";
|
||||
}
|
||||
}
|
||||
61
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.h
Normal file
61
cockatrice/src/client/tabs/api/edhrec/tab_edhrec_main.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
#ifndef TAB_EDHREC_MAIN_H
|
||||
#define TAB_EDHREC_MAIN_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../ui/widgets/general/layout_containers/flow_widget.h"
|
||||
#include "../../tab.h"
|
||||
#include "display/commander/edhrec_commander_api_response_display_widget.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QLineEdit>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QPushButton>
|
||||
|
||||
class TabEdhRecMain : public Tab
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TabEdhRecMain(TabSupervisor *_tabSupervisor);
|
||||
|
||||
void retranslateUi() override;
|
||||
void doSearch();
|
||||
QString getTabText() const override
|
||||
{
|
||||
auto cardName = cardToQuery.isNull() ? QString() : cardToQuery->getName();
|
||||
return tr("EDHREC: ") + cardName;
|
||||
}
|
||||
|
||||
QNetworkAccessManager *networkManager;
|
||||
|
||||
public slots:
|
||||
void processApiJson(QNetworkReply *reply);
|
||||
void processTopCardsResponse(QJsonObject reply);
|
||||
void processTopTagsResponse(QJsonObject reply);
|
||||
void processTopCommandersResponse(QJsonObject reply);
|
||||
void processAverageDeckResponse(QJsonObject reply);
|
||||
void prettyPrintJson(const QJsonValue &value, int indentLevel);
|
||||
void setCard(CardInfoPtr _cardToQuery, bool isCommander = false);
|
||||
void actNavigatePage(QString url);
|
||||
void getTopCards();
|
||||
void getTopCommanders();
|
||||
void getTopTags();
|
||||
|
||||
private:
|
||||
QWidget *container;
|
||||
QWidget *navigationContainer;
|
||||
QWidget *currentPageDisplay;
|
||||
QVBoxLayout *mainLayout;
|
||||
QHBoxLayout *navigationLayout;
|
||||
QVBoxLayout *currentPageLayout;
|
||||
QPushButton *cardsPushButton;
|
||||
QPushButton *topCommandersPushButton;
|
||||
QPushButton *tagsPushButton;
|
||||
QLineEdit *searchBar;
|
||||
QPushButton *searchPushButton;
|
||||
CardInfoPtr cardToQuery;
|
||||
EdhrecCommanderApiResponseDisplayWidget *displayWidget;
|
||||
|
||||
void processCommanderResponse(QJsonObject reply);
|
||||
};
|
||||
|
||||
#endif // TAB_EDHREC_MAIN_H
|
||||
|
|
@ -55,7 +55,7 @@ TabDeckEditor::TabDeckEditor(TabSupervisor *_tabSupervisor) : AbstractTabDeckEdi
|
|||
|
||||
void TabDeckEditor::createMenus()
|
||||
{
|
||||
deckMenu = new DeckEditorMenu(this, this);
|
||||
deckMenu = new DeckEditorMenu(this);
|
||||
addTabMenu(deckMenu);
|
||||
|
||||
viewMenu = new QMenu(this);
|
||||
|
|
@ -67,36 +67,36 @@ void TabDeckEditor::createMenus()
|
|||
|
||||
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockVisible->setCheckable(true);
|
||||
connect(aCardInfoDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aCardInfoDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockFloating->setCheckable(true);
|
||||
connect(aCardInfoDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aCardInfoDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||
|
||||
aDeckDockVisible = deckDockMenu->addAction(QString());
|
||||
aDeckDockVisible->setCheckable(true);
|
||||
connect(aDeckDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aDeckDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||
aDeckDockFloating = deckDockMenu->addAction(QString());
|
||||
aDeckDockFloating->setCheckable(true);
|
||||
connect(aDeckDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aDeckDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||
|
||||
aFilterDockVisible = filterDockMenu->addAction(QString());
|
||||
aFilterDockVisible->setCheckable(true);
|
||||
connect(aFilterDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aFilterDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||
aFilterDockFloating = filterDockMenu->addAction(QString());
|
||||
aFilterDockFloating->setCheckable(true);
|
||||
connect(aFilterDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aFilterDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||
|
||||
aPrintingSelectorDockVisible = printingSelectorDockMenu->addAction(QString());
|
||||
aPrintingSelectorDockVisible->setCheckable(true);
|
||||
connect(aPrintingSelectorDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aPrintingSelectorDockVisible, &QAction::triggered, this, &TabDeckEditor::dockVisibleTriggered);
|
||||
aPrintingSelectorDockFloating = printingSelectorDockMenu->addAction(QString());
|
||||
aPrintingSelectorDockFloating->setCheckable(true);
|
||||
connect(aPrintingSelectorDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aPrintingSelectorDockFloating, &QAction::triggered, this, &TabDeckEditor::dockFloatingTriggered);
|
||||
|
||||
viewMenu->addSeparator();
|
||||
|
||||
aResetLayout = viewMenu->addAction(QString());
|
||||
connect(aResetLayout, SIGNAL(triggered()), this, SLOT(restartLayout()));
|
||||
connect(aResetLayout, &QAction::triggered, this, &TabDeckEditor::restartLayout);
|
||||
viewMenu->addAction(aResetLayout);
|
||||
|
||||
deckMenu->setSaveStatus(false);
|
||||
|
|
@ -200,7 +200,7 @@ void TabDeckEditor::loadLayout()
|
|||
databaseDisplayDockWidget->setMinimumSize(100, 100);
|
||||
databaseDisplayDockWidget->setMaximumSize(1400, 5000);
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
||||
QTimer::singleShot(100, this, &TabDeckEditor::freeDocksSize);
|
||||
}
|
||||
|
||||
void TabDeckEditor::restartLayout()
|
||||
|
|
@ -236,7 +236,7 @@ void TabDeckEditor::restartLayout()
|
|||
splitDockWidget(cardInfoDockWidget, printingSelectorDockWidget, Qt::Horizontal);
|
||||
splitDockWidget(cardInfoDockWidget, filterDockWidget, Qt::Vertical);
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
||||
QTimer::singleShot(100, this, &TabDeckEditor::freeDocksSize);
|
||||
}
|
||||
|
||||
void TabDeckEditor::freeDocksSize()
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef WINDOW_DECKEDITOR_H
|
||||
#define WINDOW_DECKEDITOR_H
|
||||
|
||||
#include "../../game/cards/card_database.h"
|
||||
#include "../../game/cards/card_info.h"
|
||||
#include "../game_logic/key_signals.h"
|
||||
#include "../ui/widgets/visual_deck_storage/deck_preview/deck_preview_deck_tags_display_widget.h"
|
||||
#include "abstract_tab_deck_editor.h"
|
||||
|
|
|
|||
|
|
@ -105,19 +105,19 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
|||
// Left side actions
|
||||
aOpenLocalDeck = new QAction(this);
|
||||
aOpenLocalDeck->setIcon(QPixmap("theme:icons/pencil"));
|
||||
connect(aOpenLocalDeck, SIGNAL(triggered()), this, SLOT(actOpenLocalDeck()));
|
||||
connect(aOpenLocalDeck, &QAction::triggered, this, &TabDeckStorage::actOpenLocalDeck);
|
||||
aRenameLocal = new QAction(this);
|
||||
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
||||
connect(aRenameLocal, &QAction::triggered, this, &TabDeckStorage::actRenameLocal);
|
||||
aUpload = new QAction(this);
|
||||
aUpload->setIcon(QPixmap("theme:icons/arrow_right_green"));
|
||||
connect(aUpload, SIGNAL(triggered()), this, SLOT(actUpload()));
|
||||
connect(aUpload, &QAction::triggered, this, &TabDeckStorage::actUpload);
|
||||
aNewLocalFolder = new QAction(this);
|
||||
aNewLocalFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_FileDialogNewFolder));
|
||||
connect(aNewLocalFolder, &QAction::triggered, this, &TabDeckStorage::actNewLocalFolder);
|
||||
aDeleteLocalDeck = new QAction(this);
|
||||
aDeleteLocalDeck->setIcon(QPixmap("theme:icons/remove_row"));
|
||||
connect(aDeleteLocalDeck, SIGNAL(triggered()), this, SLOT(actDeleteLocalDeck()));
|
||||
connect(aDeleteLocalDeck, &QAction::triggered, this, &TabDeckStorage::actDeleteLocalDeck);
|
||||
|
||||
aOpenDecksFolder = new QAction(this);
|
||||
aOpenDecksFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_DirOpenIcon));
|
||||
|
|
@ -126,16 +126,16 @@ TabDeckStorage::TabDeckStorage(TabSupervisor *_tabSupervisor,
|
|||
// Right side actions
|
||||
aOpenRemoteDeck = new QAction(this);
|
||||
aOpenRemoteDeck->setIcon(QPixmap("theme:icons/pencil"));
|
||||
connect(aOpenRemoteDeck, SIGNAL(triggered()), this, SLOT(actOpenRemoteDeck()));
|
||||
connect(aOpenRemoteDeck, &QAction::triggered, this, &TabDeckStorage::actOpenRemoteDeck);
|
||||
aDownload = new QAction(this);
|
||||
aDownload->setIcon(QPixmap("theme:icons/arrow_left_green"));
|
||||
connect(aDownload, SIGNAL(triggered()), this, SLOT(actDownload()));
|
||||
connect(aDownload, &QAction::triggered, this, &TabDeckStorage::actDownload);
|
||||
aNewFolder = new QAction(this);
|
||||
aNewFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_FileDialogNewFolder));
|
||||
connect(aNewFolder, SIGNAL(triggered()), this, SLOT(actNewFolder()));
|
||||
connect(aNewFolder, &QAction::triggered, this, &TabDeckStorage::actNewFolder);
|
||||
aDeleteRemoteDeck = new QAction(this);
|
||||
aDeleteRemoteDeck->setIcon(QPixmap("theme:icons/remove_row"));
|
||||
connect(aDeleteRemoteDeck, SIGNAL(triggered()), this, SLOT(actDeleteRemoteDeck()));
|
||||
connect(aDeleteRemoteDeck, &QAction::triggered, this, &TabDeckStorage::actDeleteRemoteDeck);
|
||||
|
||||
// Add actions to toolbars
|
||||
leftToolBar->addAction(aOpenLocalDeck);
|
||||
|
|
@ -339,8 +339,7 @@ void TabDeckStorage::uploadDeck(const QString &filePath, const QString &targetPa
|
|||
cmd.set_deck_list(deckString.toStdString());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(uploadFinished(Response, CommandContainer)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::uploadFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
|
|
@ -421,8 +420,7 @@ void TabDeckStorage::actOpenRemoteDeck()
|
|||
cmd.set_deck_id(node->getId());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(openRemoteDeckFinished(Response, CommandContainer)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::openRemoteDeckFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
}
|
||||
|
|
@ -479,8 +477,7 @@ void TabDeckStorage::downloadNodeAtIndex(const QModelIndex &curLeft, const QMode
|
|||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
pend->setExtraData(filePath);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(downloadFinished(Response, CommandContainer, QVariant)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::downloadFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
// node at index is invalid
|
||||
|
|
@ -522,8 +519,7 @@ void TabDeckStorage::actNewFolder()
|
|||
cmd.set_dir_name(folder);
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(newFolderFinished(Response, CommandContainer)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::newFolderFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
|
|
@ -573,15 +569,13 @@ void TabDeckStorage::deleteRemoteDeck(const RemoteDeckList_TreeModel::Node *curR
|
|||
Command_DeckDelDir cmd;
|
||||
cmd.set_path(targetPath.toStdString());
|
||||
pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(deleteFolderFinished(Response, CommandContainer)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::deleteFolderFinished);
|
||||
} else {
|
||||
const auto *deckNode = dynamic_cast<const RemoteDeckList_TreeModel::FileNode *>(curRight);
|
||||
Command_DeckDel cmd;
|
||||
cmd.set_deck_id(deckNode->getId());
|
||||
pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(deleteDeckFinished(Response, CommandContainer)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabDeckStorage::deleteDeckFinished);
|
||||
}
|
||||
|
||||
client->sendCommand(pend);
|
||||
|
|
|
|||
|
|
@ -115,11 +115,12 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor, GameReplay *_replay)
|
|||
createReplayMenuItems();
|
||||
createViewMenuItems();
|
||||
retranslateUi();
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&TabGame::refreshShortcuts);
|
||||
refreshShortcuts();
|
||||
messageLog->logReplayStarted(gameInfo.game_id());
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(loadLayout()));
|
||||
QTimer::singleShot(0, this, &TabGame::loadLayout);
|
||||
}
|
||||
|
||||
TabGame::TabGame(TabSupervisor *_tabSupervisor,
|
||||
|
|
@ -156,14 +157,15 @@ TabGame::TabGame(TabSupervisor *_tabSupervisor,
|
|||
createMenuItems();
|
||||
createViewMenuItems();
|
||||
retranslateUi();
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&TabGame::refreshShortcuts);
|
||||
refreshShortcuts();
|
||||
|
||||
// append game to rooms game list for others to see
|
||||
for (int i = gameInfo.game_types_size() - 1; i >= 0; i--)
|
||||
gameTypes.append(roomGameTypes.find(gameInfo.game_types(i)).value());
|
||||
|
||||
QTimer::singleShot(0, this, SLOT(loadLayout()));
|
||||
QTimer::singleShot(0, this, &TabGame::loadLayout);
|
||||
}
|
||||
|
||||
void TabGame::addMentionTag(const QString &value)
|
||||
|
|
@ -626,7 +628,7 @@ Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info)
|
|||
}
|
||||
scene->addPlayer(newPlayer);
|
||||
|
||||
connect(newPlayer, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
|
||||
connect(newPlayer, &Player::newCardAdded, this, &TabGame::newCardAdded);
|
||||
messageLog->connectToPlayer(newPlayer);
|
||||
|
||||
if (local && !spectator) {
|
||||
|
|
@ -634,7 +636,7 @@ Player *TabGame::addPlayer(int playerId, const ServerInfo_User &info)
|
|||
newPlayer->setShortcutsActive();
|
||||
|
||||
auto *deckView = new DeckViewContainer(playerId, this);
|
||||
connect(deckView, SIGNAL(newCardAdded(AbstractCardItem *)), this, SLOT(newCardAdded(AbstractCardItem *)));
|
||||
connect(deckView, &DeckViewContainer::newCardAdded, this, &TabGame::newCardAdded);
|
||||
deckViewContainers.insert(playerId, deckView);
|
||||
deckViewContainerLayout->addWidget(deckView);
|
||||
|
||||
|
|
@ -751,7 +753,7 @@ void TabGame::processGameEventContainer(const GameEventContainer &cont,
|
|||
default: {
|
||||
Player *player = players.value(playerId, 0);
|
||||
if (!player) {
|
||||
qCDebug(TabGameLog) << "unhandled game event: invalid player id";
|
||||
qCWarning(TabGameLog) << "unhandled game event: invalid player id";
|
||||
break;
|
||||
}
|
||||
player->processGameEvent(eventType, event, context, options);
|
||||
|
|
@ -782,8 +784,7 @@ void TabGame::sendGameCommand(PendingCommand *pend, int playerId)
|
|||
if (!client)
|
||||
return;
|
||||
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(commandFinished(const Response &)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabGame::commandFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
|
|
@ -794,8 +795,7 @@ void TabGame::sendGameCommand(const google::protobuf::Message &command, int play
|
|||
return;
|
||||
|
||||
PendingCommand *pend = prepareGameCommand(command);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(commandFinished(const Response &)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabGame::commandFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
|
|
@ -1196,10 +1196,11 @@ void TabGame::eventSetActivePhase(const Event_SetActivePhase &event,
|
|||
|
||||
void TabGame::newCardAdded(AbstractCardItem *card)
|
||||
{
|
||||
connect(card, SIGNAL(hovered(AbstractCardItem *)), cardInfoFrameWidget, SLOT(setCard(AbstractCardItem *)));
|
||||
connect(card, &AbstractCardItem::hovered, cardInfoFrameWidget,
|
||||
qOverload<AbstractCardItem *>(&CardInfoFrameWidget::setCard));
|
||||
connect(card, &AbstractCardItem::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
||||
connect(card, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
connect(card, SIGNAL(cardShiftClicked(QString)), this, SLOT(linkCardToChat(QString)));
|
||||
connect(card, &AbstractCardItem::cardShiftClicked, this, &TabGame::linkCardToChat);
|
||||
}
|
||||
|
||||
CardItem *TabGame::getCard(int playerId, const QString &zoneName, int cardId) const
|
||||
|
|
@ -1287,34 +1288,34 @@ void TabGame::updateCardMenu(AbstractCardItem *card)
|
|||
void TabGame::createMenuItems()
|
||||
{
|
||||
aNextPhase = new QAction(this);
|
||||
connect(aNextPhase, SIGNAL(triggered()), this, SLOT(actNextPhase()));
|
||||
connect(aNextPhase, &QAction::triggered, this, &TabGame::actNextPhase);
|
||||
aNextPhaseAction = new QAction(this);
|
||||
connect(aNextPhaseAction, SIGNAL(triggered()), this, SLOT(actNextPhaseAction()));
|
||||
connect(aNextPhaseAction, &QAction::triggered, this, &TabGame::actNextPhaseAction);
|
||||
aNextTurn = new QAction(this);
|
||||
connect(aNextTurn, SIGNAL(triggered()), this, SLOT(actNextTurn()));
|
||||
connect(aNextTurn, &QAction::triggered, this, &TabGame::actNextTurn);
|
||||
aReverseTurn = new QAction(this);
|
||||
connect(aReverseTurn, SIGNAL(triggered()), this, SLOT(actReverseTurn()));
|
||||
connect(aReverseTurn, &QAction::triggered, this, &TabGame::actReverseTurn);
|
||||
aRemoveLocalArrows = new QAction(this);
|
||||
connect(aRemoveLocalArrows, SIGNAL(triggered()), this, SLOT(actRemoveLocalArrows()));
|
||||
connect(aRemoveLocalArrows, &QAction::triggered, this, &TabGame::actRemoveLocalArrows);
|
||||
aRotateViewCW = new QAction(this);
|
||||
connect(aRotateViewCW, SIGNAL(triggered()), this, SLOT(actRotateViewCW()));
|
||||
connect(aRotateViewCW, &QAction::triggered, this, &TabGame::actRotateViewCW);
|
||||
aRotateViewCCW = new QAction(this);
|
||||
connect(aRotateViewCCW, SIGNAL(triggered()), this, SLOT(actRotateViewCCW()));
|
||||
connect(aRotateViewCCW, &QAction::triggered, this, &TabGame::actRotateViewCCW);
|
||||
aGameInfo = new QAction(this);
|
||||
connect(aGameInfo, SIGNAL(triggered()), this, SLOT(actGameInfo()));
|
||||
connect(aGameInfo, &QAction::triggered, this, &TabGame::actGameInfo);
|
||||
aConcede = new QAction(this);
|
||||
connect(aConcede, SIGNAL(triggered()), this, SLOT(actConcede()));
|
||||
connect(aConcede, &QAction::triggered, this, &TabGame::actConcede);
|
||||
aLeaveGame = new QAction(this);
|
||||
connect(aLeaveGame, &QAction::triggered, this, [this] { closeRequest(); });
|
||||
aFocusChat = new QAction(this);
|
||||
connect(aFocusChat, SIGNAL(triggered()), sayEdit, SLOT(setFocus()));
|
||||
connect(aFocusChat, &QAction::triggered, sayEdit, qOverload<>(&LineEditCompleter::setFocus));
|
||||
aCloseReplay = nullptr;
|
||||
|
||||
phasesMenu = new TearOffMenu(this);
|
||||
|
||||
for (int i = 0; i < phasesToolbar->phaseCount(); ++i) {
|
||||
QAction *temp = new QAction(QString(), this);
|
||||
connect(temp, SIGNAL(triggered()), this, SLOT(actPhaseAction()));
|
||||
connect(temp, &QAction::triggered, this, &TabGame::actPhaseAction);
|
||||
phasesMenu->addAction(temp);
|
||||
phaseActions.append(temp);
|
||||
}
|
||||
|
|
@ -1373,40 +1374,40 @@ void TabGame::createViewMenuItems()
|
|||
|
||||
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockVisible->setCheckable(true);
|
||||
connect(aCardInfoDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aCardInfoDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockFloating->setCheckable(true);
|
||||
connect(aCardInfoDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aCardInfoDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||
|
||||
aMessageLayoutDockVisible = messageLayoutDockMenu->addAction(QString());
|
||||
aMessageLayoutDockVisible->setCheckable(true);
|
||||
connect(aMessageLayoutDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aMessageLayoutDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||
aMessageLayoutDockFloating = messageLayoutDockMenu->addAction(QString());
|
||||
aMessageLayoutDockFloating->setCheckable(true);
|
||||
connect(aMessageLayoutDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aMessageLayoutDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||
|
||||
aPlayerListDockVisible = playerListDockMenu->addAction(QString());
|
||||
aPlayerListDockVisible->setCheckable(true);
|
||||
connect(aPlayerListDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aPlayerListDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||
aPlayerListDockFloating = playerListDockMenu->addAction(QString());
|
||||
aPlayerListDockFloating->setCheckable(true);
|
||||
connect(aPlayerListDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aPlayerListDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||
|
||||
if (replayDock) {
|
||||
replayDockMenu = viewMenu->addMenu(QString());
|
||||
|
||||
aReplayDockVisible = replayDockMenu->addAction(QString());
|
||||
aReplayDockVisible->setCheckable(true);
|
||||
connect(aReplayDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
connect(aReplayDockVisible, &QAction::triggered, this, &TabGame::dockVisibleTriggered);
|
||||
aReplayDockFloating = replayDockMenu->addAction(QString());
|
||||
aReplayDockFloating->setCheckable(true);
|
||||
connect(aReplayDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
connect(aReplayDockFloating, &QAction::triggered, this, &TabGame::dockFloatingTriggered);
|
||||
}
|
||||
|
||||
viewMenu->addSeparator();
|
||||
|
||||
aResetLayout = viewMenu->addAction(QString());
|
||||
connect(aResetLayout, SIGNAL(triggered()), this, SLOT(actResetLayout()));
|
||||
connect(aResetLayout, &QAction::triggered, this, &TabGame::actResetLayout);
|
||||
viewMenu->addAction(aResetLayout);
|
||||
|
||||
addTabMenu(viewMenu);
|
||||
|
|
@ -1457,7 +1458,7 @@ void TabGame::loadLayout()
|
|||
aReplayDockFloating->setChecked(replayDock->isFloating());
|
||||
}
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
||||
QTimer::singleShot(100, this, &TabGame::freeDocksSize);
|
||||
}
|
||||
|
||||
void TabGame::freeDocksSize()
|
||||
|
|
@ -1523,15 +1524,15 @@ void TabGame::actResetLayout()
|
|||
playerListDock->setMaximumSize(250, 50);
|
||||
}
|
||||
|
||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
||||
QTimer::singleShot(100, this, &TabGame::freeDocksSize);
|
||||
}
|
||||
|
||||
void TabGame::createPlayAreaWidget(bool bReplay)
|
||||
{
|
||||
phasesToolbar = new PhasesToolbar;
|
||||
if (!bReplay)
|
||||
connect(phasesToolbar, SIGNAL(sendGameCommand(const ::google::protobuf::Message &, int)), this,
|
||||
SLOT(sendGameCommand(const ::google::protobuf::Message &, int)));
|
||||
connect(phasesToolbar, &PhasesToolbar::sendGameCommand, this,
|
||||
qOverload<const ::google::protobuf::Message &, int>(&TabGame::sendGameCommand));
|
||||
scene = new GameScene(phasesToolbar, this);
|
||||
gameView = new GameView(scene);
|
||||
|
||||
|
|
@ -1549,9 +1550,8 @@ void TabGame::createReplayDock()
|
|||
// timeline widget
|
||||
timelineWidget = new ReplayTimelineWidget;
|
||||
timelineWidget->setTimeline(replayTimeline);
|
||||
connect(timelineWidget, SIGNAL(processNextEvent(Player::EventProcessingOptions)), this,
|
||||
SLOT(replayNextEvent(Player::EventProcessingOptions)));
|
||||
connect(timelineWidget, SIGNAL(replayFinished()), this, SLOT(replayFinished()));
|
||||
connect(timelineWidget, &ReplayTimelineWidget::processNextEvent, this, &TabGame::replayNextEvent);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::replayFinished, this, &TabGame::replayFinished);
|
||||
connect(timelineWidget, &ReplayTimelineWidget::rewound, this, &TabGame::replayRewind);
|
||||
|
||||
// timeline skip shortcuts
|
||||
|
|
@ -1583,13 +1583,13 @@ void TabGame::createReplayDock()
|
|||
playButtonIcon.addPixmap(QPixmap("theme:replay/pause"), QIcon::Normal, QIcon::On);
|
||||
replayPlayButton->setIcon(playButtonIcon);
|
||||
replayPlayButton->setCheckable(true);
|
||||
connect(replayPlayButton, SIGNAL(toggled(bool)), this, SLOT(replayPlayButtonToggled(bool)));
|
||||
connect(replayPlayButton, &QToolButton::toggled, this, &TabGame::replayPlayButtonToggled);
|
||||
|
||||
replayFastForwardButton = new QToolButton;
|
||||
replayFastForwardButton->setIconSize(QSize(32, 32));
|
||||
replayFastForwardButton->setIcon(QPixmap("theme:replay/fastforward"));
|
||||
replayFastForwardButton->setCheckable(true);
|
||||
connect(replayFastForwardButton, SIGNAL(toggled(bool)), this, SLOT(replayFastForwardButtonToggled(bool)));
|
||||
connect(replayFastForwardButton, &QToolButton::toggled, this, &TabGame::replayFastForwardButtonToggled);
|
||||
|
||||
// putting everything together
|
||||
replayControlLayout = new QHBoxLayout;
|
||||
|
|
@ -1609,7 +1609,7 @@ void TabGame::createReplayDock()
|
|||
replayDock->setFloating(false);
|
||||
|
||||
replayDock->installEventFilter(this);
|
||||
connect(replayDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
connect(replayDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||
}
|
||||
|
||||
void TabGame::createDeckViewContainerWidget(bool bReplay)
|
||||
|
|
@ -1650,7 +1650,7 @@ void TabGame::createCardInfoDock(bool bReplay)
|
|||
cardInfoDock->setFloating(false);
|
||||
|
||||
cardInfoDock->installEventFilter(this);
|
||||
connect(cardInfoDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
connect(cardInfoDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||
}
|
||||
|
||||
void TabGame::createPlayerListDock(bool bReplay)
|
||||
|
|
@ -1672,26 +1672,28 @@ void TabGame::createPlayerListDock(bool bReplay)
|
|||
playerListDock->setFloating(false);
|
||||
|
||||
playerListDock->installEventFilter(this);
|
||||
connect(playerListDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
connect(playerListDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||
}
|
||||
|
||||
void TabGame::createMessageDock(bool bReplay)
|
||||
{
|
||||
messageLog = new MessageLogWidget(tabSupervisor, this);
|
||||
connect(messageLog, SIGNAL(cardNameHovered(QString)), cardInfoFrameWidget, SLOT(setCard(QString)));
|
||||
connect(messageLog, &MessageLogWidget::cardNameHovered, cardInfoFrameWidget,
|
||||
qOverload<const QString &>(&CardInfoFrameWidget::setCard));
|
||||
connect(messageLog, &MessageLogWidget::showCardInfoPopup, this, &TabGame::showCardInfoPopup);
|
||||
connect(messageLog, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
connect(messageLog, &MessageLogWidget::deleteCardInfoPopup, this, &TabGame::deleteCardInfoPopup);
|
||||
|
||||
if (!bReplay) {
|
||||
connect(messageLog, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||
connect(messageLog, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||
connect(&SettingsCache::instance(), SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
||||
connect(messageLog, &MessageLogWidget::openMessageDialog, this, &TabGame::openMessageDialog);
|
||||
connect(messageLog, &MessageLogWidget::addMentionTag, this, &TabGame::addMentionTag);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::chatMentionCompleterChanged, this,
|
||||
&TabGame::actCompleterChanged);
|
||||
|
||||
timeElapsedLabel = new QLabel;
|
||||
timeElapsedLabel->setAlignment(Qt::AlignCenter);
|
||||
gameTimer = new QTimer(this);
|
||||
gameTimer->setInterval(1000);
|
||||
connect(gameTimer, SIGNAL(timeout()), this, SLOT(incrementGameTime()));
|
||||
connect(gameTimer, &QTimer::timeout, this, &TabGame::incrementGameTime);
|
||||
gameTimer->start();
|
||||
|
||||
sayLabel = new QLabel;
|
||||
|
|
@ -1719,8 +1721,8 @@ void TabGame::createMessageDock(bool bReplay)
|
|||
}
|
||||
}
|
||||
|
||||
connect(tabSupervisor, SIGNAL(adminLockChanged(bool)), this, SLOT(adminLockChanged(bool)));
|
||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(actSay()));
|
||||
connect(tabSupervisor, &TabSupervisor::adminLockChanged, this, &TabGame::adminLockChanged);
|
||||
connect(sayEdit, &LineEditCompleter::returnPressed, this, &TabGame::actSay);
|
||||
|
||||
sayHLayout = new QHBoxLayout;
|
||||
sayHLayout->addWidget(sayLabel);
|
||||
|
|
@ -1746,7 +1748,7 @@ void TabGame::createMessageDock(bool bReplay)
|
|||
messageLayoutDock->setFloating(false);
|
||||
|
||||
messageLayoutDock->installEventFilter(this);
|
||||
connect(messageLayoutDock, SIGNAL(topLevelChanged(bool)), this, SLOT(dockTopLevelChanged(bool)));
|
||||
connect(messageLayoutDock, &QDockWidget::topLevelChanged, this, &TabGame::dockTopLevelChanged);
|
||||
}
|
||||
|
||||
void TabGame::hideEvent(QHideEvent *event)
|
||||
|
|
|
|||
|
|
@ -116,8 +116,7 @@ void TabLog::getClicked()
|
|||
cmd.set_date_range(dateRange);
|
||||
cmd.set_maximum_results(maximumResults->value());
|
||||
PendingCommand *pend = client->prepareModeratorCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(viewLogHistory_processResponse(Response)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabLog::viewLogHistory_processResponse);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
|
||||
|
|
@ -186,11 +185,11 @@ void TabLog::createDock()
|
|||
|
||||
getButton = new QPushButton(tr("Get User Logs"));
|
||||
getButton->setAutoDefault(true);
|
||||
connect(getButton, SIGNAL(clicked()), this, SLOT(getClicked()));
|
||||
connect(getButton, &QPushButton::clicked, this, &TabLog::getClicked);
|
||||
|
||||
clearButton = new QPushButton(tr("Clear Filters"));
|
||||
clearButton->setAutoDefault(true);
|
||||
connect(clearButton, SIGNAL(clicked()), this, SLOT(clearClicked()));
|
||||
connect(clearButton, &QPushButton::clicked, this, &TabLog::clearClicked);
|
||||
|
||||
criteriaGrid = new QGridLayout;
|
||||
criteriaGrid->addWidget(labelFindUserName, 0, 0);
|
||||
|
|
|
|||
|
|
@ -28,11 +28,11 @@ TabMessage::TabMessage(TabSupervisor *_tabSupervisor,
|
|||
{
|
||||
chatView = new ChatView(tabSupervisor, 0, true);
|
||||
connect(chatView, &ChatView::showCardInfoPopup, this, &TabMessage::showCardInfoPopup);
|
||||
connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabMessage::deleteCardInfoPopup);
|
||||
connect(chatView, &ChatView::addMentionTag, this, &TabMessage::addMentionTag);
|
||||
sayEdit = new LineEditUnfocusable;
|
||||
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
||||
connect(sayEdit, &LineEditUnfocusable::returnPressed, this, &TabMessage::sendMessage);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(chatView);
|
||||
|
|
@ -102,7 +102,7 @@ void TabMessage::sendMessage()
|
|||
cmd.set_message(sayEdit->text().toStdString());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this, SLOT(messageSent(const Response &)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabMessage::messageSent);
|
||||
client->sendCommand(pend);
|
||||
|
||||
sayEdit->clear();
|
||||
|
|
@ -140,12 +140,12 @@ bool TabMessage::shouldShowSystemPopup(const Event_UserMessage &event)
|
|||
void TabMessage::showSystemPopup(const Event_UserMessage &event)
|
||||
{
|
||||
if (trayIcon) {
|
||||
disconnect(trayIcon, SIGNAL(messageClicked()), 0, 0);
|
||||
disconnect(trayIcon, &QSystemTrayIcon::messageClicked, 0, 0);
|
||||
trayIcon->showMessage(tr("Private message from") + " " + otherUserInfo->name().c_str(),
|
||||
event.message().c_str());
|
||||
connect(trayIcon, SIGNAL(messageClicked()), this, SLOT(messageClicked()));
|
||||
connect(trayIcon, &QSystemTrayIcon::messageClicked, this, &TabMessage::messageClicked);
|
||||
} else {
|
||||
qCDebug(TabMessageLog) << "Error: trayIcon is NULL. TabMessage::showSystemPopup failed";
|
||||
qCWarning(TabMessageLog) << "Error: trayIcon is NULL. TabMessage::showSystemPopup failed";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -96,8 +96,8 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
|||
// Left side actions
|
||||
aOpenLocalReplay = new QAction(this);
|
||||
aOpenLocalReplay->setIcon(QPixmap("theme:icons/view"));
|
||||
connect(aOpenLocalReplay, SIGNAL(triggered()), this, SLOT(actOpenLocalReplay()));
|
||||
connect(localDirView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(actOpenLocalReplay()));
|
||||
connect(aOpenLocalReplay, &QAction::triggered, this, &TabReplays::actOpenLocalReplay);
|
||||
connect(localDirView, &QTreeView::doubleClicked, this, &TabReplays::actOpenLocalReplay);
|
||||
aRenameLocal = new QAction(this);
|
||||
aRenameLocal->setIcon(QPixmap("theme:icons/rename"));
|
||||
connect(aRenameLocal, &QAction::triggered, this, &TabReplays::actRenameLocal);
|
||||
|
|
@ -106,7 +106,7 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
|||
connect(aNewLocalFolder, &QAction::triggered, this, &TabReplays::actNewLocalFolder);
|
||||
aDeleteLocalReplay = new QAction(this);
|
||||
aDeleteLocalReplay->setIcon(QPixmap("theme:icons/remove_row"));
|
||||
connect(aDeleteLocalReplay, SIGNAL(triggered()), this, SLOT(actDeleteLocalReplay()));
|
||||
connect(aDeleteLocalReplay, &QAction::triggered, this, &TabReplays::actDeleteLocalReplay);
|
||||
|
||||
aOpenReplaysFolder = new QAction(this);
|
||||
aOpenReplaysFolder->setIcon(qApp->style()->standardIcon(QStyle::SP_DirOpenIcon));
|
||||
|
|
@ -115,17 +115,17 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
|||
// Right side actions
|
||||
aOpenRemoteReplay = new QAction(this);
|
||||
aOpenRemoteReplay->setIcon(QPixmap("theme:icons/view"));
|
||||
connect(aOpenRemoteReplay, SIGNAL(triggered()), this, SLOT(actOpenRemoteReplay()));
|
||||
connect(serverDirView, SIGNAL(doubleClicked(const QModelIndex &)), this, SLOT(actOpenRemoteReplay()));
|
||||
connect(aOpenRemoteReplay, &QAction::triggered, this, &TabReplays::actOpenRemoteReplay);
|
||||
connect(serverDirView, &QTreeView::doubleClicked, this, &TabReplays::actOpenRemoteReplay);
|
||||
aDownload = new QAction(this);
|
||||
aDownload->setIcon(QPixmap("theme:icons/arrow_left_green"));
|
||||
connect(aDownload, SIGNAL(triggered()), this, SLOT(actDownload()));
|
||||
connect(aDownload, &QAction::triggered, this, &TabReplays::actDownload);
|
||||
aKeep = new QAction(this);
|
||||
aKeep->setIcon(QPixmap("theme:icons/lock"));
|
||||
connect(aKeep, SIGNAL(triggered()), this, SLOT(actKeepRemoteReplay()));
|
||||
connect(aKeep, &QAction::triggered, this, &TabReplays::actKeepRemoteReplay);
|
||||
aDeleteRemoteReplay = new QAction(this);
|
||||
aDeleteRemoteReplay->setIcon(QPixmap("theme:icons/remove_row"));
|
||||
connect(aDeleteRemoteReplay, SIGNAL(triggered()), this, SLOT(actDeleteRemoteReplay()));
|
||||
connect(aDeleteRemoteReplay, &QAction::triggered, this, &TabReplays::actDeleteRemoteReplay);
|
||||
|
||||
// Add actions to toolbars
|
||||
leftToolBar->addAction(aOpenLocalReplay);
|
||||
|
|
@ -146,8 +146,7 @@ TabReplays::TabReplays(TabSupervisor *_tabSupervisor, AbstractClient *_client, c
|
|||
mainWidget->setLayout(hbox);
|
||||
setCentralWidget(mainWidget);
|
||||
|
||||
connect(client, SIGNAL(replayAddedEventReceived(const Event_ReplayAdded &)), this,
|
||||
SLOT(replayAddedEventReceived(const Event_ReplayAdded &)));
|
||||
connect(client, &AbstractClient::replayAddedEventReceived, this, &TabReplays::replayAddedEventReceived);
|
||||
|
||||
connect(client, &AbstractClient::userInfoChanged, this, &TabReplays::handleConnected);
|
||||
connect(client, &AbstractClient::statusChanged, this, &TabReplays::handleConnectionChanged);
|
||||
|
|
@ -323,8 +322,7 @@ void TabReplays::actOpenRemoteReplay()
|
|||
cmd.set_replay_id(curRight->replay_id());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(openRemoteReplayFinished(const Response &)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabReplays::openRemoteReplayFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
}
|
||||
|
|
@ -378,8 +376,7 @@ void TabReplays::downloadNodeAtIndex(const QModelIndex &curLeft, const QModelInd
|
|||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
pend->setExtraData(filePath);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(downloadFinished(Response, CommandContainer, QVariant)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabReplays::downloadFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
// node at index was invalid
|
||||
|
|
@ -416,8 +413,7 @@ void TabReplays::actKeepRemoteReplay()
|
|||
cmd.set_do_not_hide(!curRight->do_not_hide());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(keepRemoteReplayFinished(Response, CommandContainer)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabReplays::keepRemoteReplayFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
}
|
||||
|
|
@ -455,8 +451,7 @@ void TabReplays::actDeleteRemoteReplay()
|
|||
cmd.set_game_id(curRight->game_id());
|
||||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(deleteRemoteReplayFinished(Response, CommandContainer)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabReplays::deleteRemoteReplayFinished);
|
||||
client->sendCommand(pend);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,28 +53,29 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor,
|
|||
SIGNAL(openMessageDialog(const QString &, bool)));
|
||||
|
||||
chatView = new ChatView(tabSupervisor, nullptr, true, this);
|
||||
connect(chatView, SIGNAL(showMentionPopup(const QString &)), this, SLOT(actShowMentionPopup(const QString &)));
|
||||
connect(chatView, SIGNAL(messageClickedSignal()), this, SLOT(focusTab()));
|
||||
connect(chatView, SIGNAL(openMessageDialog(QString, bool)), this, SIGNAL(openMessageDialog(QString, bool)));
|
||||
connect(chatView, &ChatView::showMentionPopup, this, &TabRoom::actShowMentionPopup);
|
||||
connect(chatView, &ChatView::messageClickedSignal, this, &TabRoom::focusTab);
|
||||
connect(chatView, &ChatView::openMessageDialog, this, &TabRoom::openMessageDialog);
|
||||
connect(chatView, &ChatView::showCardInfoPopup, this, &TabRoom::showCardInfoPopup);
|
||||
connect(chatView, SIGNAL(deleteCardInfoPopup(QString)), this, SLOT(deleteCardInfoPopup(QString)));
|
||||
connect(chatView, SIGNAL(addMentionTag(QString)), this, SLOT(addMentionTag(QString)));
|
||||
connect(&SettingsCache::instance(), SIGNAL(chatMentionCompleterChanged()), this, SLOT(actCompleterChanged()));
|
||||
connect(chatView, &ChatView::deleteCardInfoPopup, this, &TabRoom::deleteCardInfoPopup);
|
||||
connect(chatView, &ChatView::addMentionTag, this, &TabRoom::addMentionTag);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::chatMentionCompleterChanged, this,
|
||||
&TabRoom::actCompleterChanged);
|
||||
sayLabel = new QLabel;
|
||||
sayEdit = new LineEditCompleter;
|
||||
sayEdit->setMaxLength(MAX_TEXT_LENGTH);
|
||||
sayLabel->setBuddy(sayEdit);
|
||||
connect(sayEdit, SIGNAL(returnPressed()), this, SLOT(sendMessage()));
|
||||
connect(sayEdit, &LineEditCompleter::returnPressed, this, &TabRoom::sendMessage);
|
||||
|
||||
QMenu *chatSettingsMenu = new QMenu(this);
|
||||
|
||||
aClearChat = chatSettingsMenu->addAction(QString());
|
||||
connect(aClearChat, SIGNAL(triggered()), this, SLOT(actClearChat()));
|
||||
connect(aClearChat, &QAction::triggered, this, &TabRoom::actClearChat);
|
||||
|
||||
chatSettingsMenu->addSeparator();
|
||||
|
||||
aOpenChatSettings = chatSettingsMenu->addAction(QString());
|
||||
connect(aOpenChatSettings, SIGNAL(triggered()), this, SLOT(actOpenChatSettings()));
|
||||
connect(aOpenChatSettings, &QAction::triggered, this, &TabRoom::actOpenChatSettings);
|
||||
|
||||
QToolButton *chatSettingsButton = new QToolButton;
|
||||
chatSettingsButton->setIcon(QPixmap("theme:icons/settings"));
|
||||
|
|
@ -126,7 +127,8 @@ TabRoom::TabRoom(TabSupervisor *_tabSupervisor,
|
|||
|
||||
sayEdit->setCompleter(completer);
|
||||
actCompleterChanged();
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
connect(&SettingsCache::instance().shortcuts(), &ShortcutsSettings::shortCutChanged, this,
|
||||
&TabRoom::refreshShortcuts);
|
||||
refreshShortcuts();
|
||||
|
||||
retranslateUi();
|
||||
|
|
@ -165,9 +167,9 @@ void TabRoom::actShowPopup(const QString &message)
|
|||
{
|
||||
if (trayIcon && (tabSupervisor->currentIndex() != tabSupervisor->indexOf(this) ||
|
||||
QApplication::activeWindow() == nullptr || QApplication::focusWidget() == nullptr)) {
|
||||
disconnect(trayIcon, SIGNAL(messageClicked()), nullptr, nullptr);
|
||||
disconnect(trayIcon, &QSystemTrayIcon::messageClicked, nullptr, nullptr);
|
||||
trayIcon->showMessage(message, tr("Click to view"));
|
||||
connect(trayIcon, SIGNAL(messageClicked()), chatView, SLOT(actMessageClicked()));
|
||||
connect(trayIcon, &QSystemTrayIcon::messageClicked, chatView, &ChatView::messageClickedSignal);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -201,8 +203,7 @@ void TabRoom::sendMessage()
|
|||
cmd.set_message(sayEdit->text().toStdString());
|
||||
|
||||
PendingCommand *pend = prepareRoomCommand(cmd);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(sayFinished(const Response &)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabRoom::sayFinished);
|
||||
sendRoomCommand(pend);
|
||||
sayEdit->clear();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) : QGroupBox
|
|||
roomList->header()->setSectionResizeMode(3, QHeaderView::ResizeToContents);
|
||||
|
||||
joinButton = new QPushButton;
|
||||
connect(joinButton, SIGNAL(clicked()), this, SLOT(joinClicked()));
|
||||
connect(joinButton, &QPushButton::clicked, this, &RoomSelector::joinClicked);
|
||||
QHBoxLayout *buttonLayout = new QHBoxLayout;
|
||||
buttonLayout->addStretch();
|
||||
buttonLayout->addWidget(joinButton);
|
||||
|
|
@ -44,9 +44,8 @@ RoomSelector::RoomSelector(AbstractClient *_client, QWidget *parent) : QGroupBox
|
|||
retranslateUi();
|
||||
setLayout(vbox);
|
||||
|
||||
connect(client, SIGNAL(listRoomsEventReceived(const Event_ListRooms &)), this,
|
||||
SLOT(processListRoomsEvent(const Event_ListRooms &)));
|
||||
connect(roomList, SIGNAL(activated(const QModelIndex &)), this, SLOT(joinClicked()));
|
||||
connect(client, &AbstractClient::listRoomsEventReceived, this, &RoomSelector::processListRoomsEvent);
|
||||
connect(roomList, &QTreeWidget::activated, this, &RoomSelector::joinClicked);
|
||||
client->sendCommand(client->prepareSessionCommand(Command_ListRooms()));
|
||||
}
|
||||
|
||||
|
|
@ -144,10 +143,9 @@ TabServer::TabServer(TabSupervisor *_tabSupervisor, AbstractClient *_client) : T
|
|||
serverInfoBox = new QTextBrowser;
|
||||
serverInfoBox->setOpenExternalLinks(true);
|
||||
|
||||
connect(roomSelector, SIGNAL(joinRoomRequest(int, bool)), this, SLOT(joinRoom(int, bool)));
|
||||
connect(roomSelector, &RoomSelector::joinRoomRequest, this, &TabServer::joinRoom);
|
||||
|
||||
connect(client, SIGNAL(serverMessageEventReceived(const Event_ServerMessage &)), this,
|
||||
SLOT(processServerMessageEvent(const Event_ServerMessage &)));
|
||||
connect(client, &AbstractClient::serverMessageEventReceived, this, &TabServer::processServerMessageEvent);
|
||||
|
||||
QVBoxLayout *vbox = new QVBoxLayout;
|
||||
vbox->addWidget(roomSelector);
|
||||
|
|
@ -185,8 +183,7 @@ void TabServer::joinRoom(int id, bool setCurrent)
|
|||
|
||||
PendingCommand *pend = client->prepareSessionCommand(cmd);
|
||||
pend->setExtraData(setCurrent);
|
||||
connect(pend, SIGNAL(finished(Response, CommandContainer, QVariant)), this,
|
||||
SLOT(joinRoomFinished(Response, CommandContainer, QVariant)));
|
||||
connect(pend, &PendingCommand::finished, this, &TabServer::joinRoomFinished);
|
||||
|
||||
client->sendCommand(pend);
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "../../server/user/user_list_widget.h"
|
||||
#include "../../settings/cache_settings.h"
|
||||
#include "../ui/pixel_map_generator.h"
|
||||
#include "api/edhrec/tab_edhrec_main.h"
|
||||
#include "pb/event_game_joined.pb.h"
|
||||
#include "pb/event_notify_user.pb.h"
|
||||
#include "pb/event_user_message.pb.h"
|
||||
|
|
@ -25,6 +26,9 @@
|
|||
#include "tab_replays.h"
|
||||
#include "tab_room.h"
|
||||
#include "tab_server.h"
|
||||
#include "tab_visual_database_display.h"
|
||||
#include "visual_deck_editor/tab_deck_editor_visual.h"
|
||||
#include "visual_deck_editor/tab_deck_editor_visual_tab_widget.h"
|
||||
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
||||
|
||||
#include <QApplication>
|
||||
|
|
@ -130,10 +134,19 @@ TabSupervisor::TabSupervisor(AbstractClient *_client, QMenu *tabsMenu, QWidget *
|
|||
aTabDeckEditor = new QAction(this);
|
||||
connect(aTabDeckEditor, &QAction::triggered, this, [this] { addDeckEditorTab(nullptr); });
|
||||
|
||||
aTabVisualDeckEditor = new QAction(this);
|
||||
connect(aTabVisualDeckEditor, &QAction::triggered, this, [this] { addVisualDeckEditorTab(nullptr); });
|
||||
|
||||
aTabEdhRec = new QAction(this);
|
||||
connect(aTabEdhRec, &QAction::triggered, this, [this] { addEdhrecMainTab(); });
|
||||
|
||||
aTabVisualDeckStorage = new QAction(this);
|
||||
aTabVisualDeckStorage->setCheckable(true);
|
||||
connect(aTabVisualDeckStorage, &QAction::triggered, this, &TabSupervisor::actTabVisualDeckStorage);
|
||||
|
||||
aTabVisualDatabaseDisplay = new QAction(this);
|
||||
connect(aTabVisualDatabaseDisplay, &QAction::triggered, this, [this] { addVisualDatabaseDisplayTab(); });
|
||||
|
||||
aTabServer = new QAction(this);
|
||||
aTabServer->setCheckable(true);
|
||||
connect(aTabServer, &QAction::triggered, this, &TabSupervisor::actTabServer);
|
||||
|
|
@ -176,7 +189,10 @@ void TabSupervisor::retranslateUi()
|
|||
{
|
||||
// tab menu actions
|
||||
aTabDeckEditor->setText(tr("Deck Editor"));
|
||||
aTabVisualDeckEditor->setText(tr("Visual Deck Editor"));
|
||||
aTabEdhRec->setText(tr("EDHRec"));
|
||||
aTabVisualDeckStorage->setText(tr("&Visual Deck Storage"));
|
||||
aTabVisualDatabaseDisplay->setText(tr("Visual Database Display"));
|
||||
aTabServer->setText(tr("Server"));
|
||||
aTabAccount->setText(tr("Account"));
|
||||
aTabDeckStorage->setText(tr("Deck Storage"));
|
||||
|
|
@ -223,6 +239,7 @@ void TabSupervisor::refreshShortcuts()
|
|||
{
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
aTabDeckEditor->setShortcuts(shortcuts.getShortcut("Tabs/aTabDeckEditor"));
|
||||
aTabVisualDeckEditor->setShortcuts(shortcuts.getShortcut("Tabs/aTabVisualDeckEditor"));
|
||||
aTabVisualDeckStorage->setShortcuts(shortcuts.getShortcut("Tabs/aTabVisualDeckStorage"));
|
||||
aTabServer->setShortcuts(shortcuts.getShortcut("Tabs/aTabServer"));
|
||||
aTabAccount->setShortcuts(shortcuts.getShortcut("Tabs/aTabAccount"));
|
||||
|
|
@ -370,8 +387,11 @@ void TabSupervisor::resetTabsMenu()
|
|||
{
|
||||
tabsMenu->clear();
|
||||
tabsMenu->addAction(aTabDeckEditor);
|
||||
tabsMenu->addAction(aTabVisualDeckEditor);
|
||||
tabsMenu->addAction(aTabEdhRec);
|
||||
tabsMenu->addSeparator();
|
||||
tabsMenu->addAction(aTabVisualDeckStorage);
|
||||
tabsMenu->addAction(aTabVisualDatabaseDisplay);
|
||||
tabsMenu->addAction(aTabDeckStorage);
|
||||
tabsMenu->addAction(aTabReplays);
|
||||
}
|
||||
|
|
@ -804,6 +824,36 @@ TabDeckEditor *TabSupervisor::addDeckEditorTab(const DeckLoader *deckToOpen)
|
|||
return tab;
|
||||
}
|
||||
|
||||
TabDeckEditorVisual *TabSupervisor::addVisualDeckEditorTab(const DeckLoader *deckToOpen)
|
||||
{
|
||||
auto *tab = new TabDeckEditorVisual(this);
|
||||
if (deckToOpen)
|
||||
tab->openDeck(new DeckLoader(*deckToOpen));
|
||||
connect(tab, &AbstractTabDeckEditor::deckEditorClosing, this, &TabSupervisor::deckEditorClosed);
|
||||
connect(tab, &AbstractTabDeckEditor::openDeckEditor, this, &TabSupervisor::addVisualDeckEditorTab);
|
||||
myAddTab(tab);
|
||||
deckEditorTabs.append(tab);
|
||||
setCurrentWidget(tab);
|
||||
return tab;
|
||||
}
|
||||
|
||||
TabEdhRecMain *TabSupervisor::addEdhrecMainTab()
|
||||
{
|
||||
auto *tab = new TabEdhRecMain(this);
|
||||
|
||||
myAddTab(tab);
|
||||
setCurrentWidget(tab);
|
||||
return tab;
|
||||
}
|
||||
|
||||
TabVisualDatabaseDisplay *TabSupervisor::addVisualDatabaseDisplayTab()
|
||||
{
|
||||
auto *tab = new TabVisualDatabaseDisplay(this);
|
||||
myAddTab(tab);
|
||||
setCurrentWidget(tab);
|
||||
return tab;
|
||||
}
|
||||
|
||||
TabEdhRec *TabSupervisor::addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander)
|
||||
{
|
||||
auto *tab = new TabEdhRec(this);
|
||||
|
|
@ -856,7 +906,7 @@ void TabSupervisor::processGameEventContainer(const GameEventContainer &cont)
|
|||
if (tab)
|
||||
tab->processGameEventContainer(cont, qobject_cast<AbstractClient *>(sender()), {});
|
||||
else
|
||||
qCDebug(TabSupervisorLog) << "gameEvent: invalid gameId";
|
||||
qCInfo(TabSupervisorLog) << "gameEvent: invalid gameId" << cont.game_id();
|
||||
}
|
||||
|
||||
void TabSupervisor::processUserMessageEvent(const Event_UserMessage &event)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,10 @@
|
|||
#include "../../server/user/user_list_proxy.h"
|
||||
#include "abstract_tab_deck_editor.h"
|
||||
#include "api/edhrec/tab_edhrec.h"
|
||||
#include "api/edhrec/tab_edhrec_main.h"
|
||||
#include "tab_visual_database_display.h"
|
||||
#include "visual_deck_editor/tab_deck_editor_visual.h"
|
||||
#include "visual_deck_editor/tab_deck_editor_visual_tab_widget.h"
|
||||
#include "visual_deck_storage/tab_deck_storage_visual.h"
|
||||
|
||||
#include <QAbstractButton>
|
||||
|
|
@ -91,8 +95,8 @@ private:
|
|||
QList<AbstractTabDeckEditor *> deckEditorTabs;
|
||||
bool isLocalGame;
|
||||
|
||||
QAction *aTabDeckEditor, *aTabVisualDeckStorage, *aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays,
|
||||
*aTabAdmin, *aTabLog;
|
||||
QAction *aTabDeckEditor, *aTabVisualDeckEditor, *aTabEdhRec, *aTabVisualDeckStorage, *aTabVisualDatabaseDisplay,
|
||||
*aTabServer, *aTabAccount, *aTabDeckStorage, *aTabReplays, *aTabAdmin, *aTabLog;
|
||||
|
||||
int myAddTab(Tab *tab, QAction *manager = nullptr);
|
||||
void addCloseButtonToTab(Tab *tab, int tabIndex, QAction *manager);
|
||||
|
|
@ -149,6 +153,9 @@ signals:
|
|||
|
||||
public slots:
|
||||
TabDeckEditor *addDeckEditorTab(const DeckLoader *deckToOpen);
|
||||
TabDeckEditorVisual *addVisualDeckEditorTab(const DeckLoader *deckToOpen);
|
||||
TabVisualDatabaseDisplay *addVisualDatabaseDisplayTab();
|
||||
TabEdhRecMain *addEdhrecMainTab();
|
||||
TabEdhRec *addEdhrecTab(const CardInfoPtr &cardToQuery, bool isCommander = false);
|
||||
void openReplay(GameReplay *replay);
|
||||
void maximizeMainWindow();
|
||||
|
|
|
|||
20
cockatrice/src/client/tabs/tab_visual_database_display.cpp
Normal file
20
cockatrice/src/client/tabs/tab_visual_database_display.cpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
#include "tab_visual_database_display.h"
|
||||
|
||||
#include "tab_deck_editor.h"
|
||||
|
||||
TabVisualDatabaseDisplay::TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor) : Tab(_tabSupervisor)
|
||||
{
|
||||
deckEditor = new TabDeckEditor(_tabSupervisor);
|
||||
deckEditor->setHidden(true);
|
||||
visualDatabaseDisplayWidget =
|
||||
new VisualDatabaseDisplayWidget(this, deckEditor, deckEditor->databaseDisplayDockWidget->databaseModel,
|
||||
deckEditor->databaseDisplayDockWidget->databaseDisplayModel);
|
||||
|
||||
setCentralWidget(visualDatabaseDisplayWidget);
|
||||
|
||||
TabVisualDatabaseDisplay::retranslateUi();
|
||||
}
|
||||
|
||||
void TabVisualDatabaseDisplay::retranslateUi()
|
||||
{
|
||||
}
|
||||
26
cockatrice/src/client/tabs/tab_visual_database_display.h
Normal file
26
cockatrice/src/client/tabs/tab_visual_database_display.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
#ifndef TAB_VISUAL_DATABASE_DISPLAY_H
|
||||
#define TAB_VISUAL_DATABASE_DISPLAY_H
|
||||
|
||||
#include "../ui/widgets/visual_database_display/visual_database_display_widget.h"
|
||||
#include "tab.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
|
||||
class TabVisualDatabaseDisplay : public Tab
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
TabDeckEditor *deckEditor;
|
||||
VisualDatabaseDisplayWidget *visualDatabaseDisplayWidget;
|
||||
|
||||
public:
|
||||
TabVisualDatabaseDisplay(TabSupervisor *_tabSupervisor);
|
||||
void retranslateUi() override;
|
||||
QString getTabText() const override
|
||||
{
|
||||
return tr("Visual Database Display");
|
||||
}
|
||||
};
|
||||
|
||||
#endif // TAB_VISUAL_DATABASE_DISPLAY_H
|
||||
|
|
@ -0,0 +1,470 @@
|
|||
#include "tab_deck_editor_visual.h"
|
||||
|
||||
#include "../../../deck/deck_list_model.h"
|
||||
#include "../../../deck/deck_stats_interface.h"
|
||||
#include "../../../game/cards/card_database_model.h"
|
||||
#include "../../../game/filters/filter_builder.h"
|
||||
#include "../../../server/pending_command.h"
|
||||
#include "../../../settings/cache_settings.h"
|
||||
#include "../../ui/pixel_map_generator.h"
|
||||
#include "../../ui/widgets/cards/card_info_frame_widget.h"
|
||||
#include "../../ui/widgets/deck_analytics/deck_analytics_widget.h"
|
||||
#include "../../ui/widgets/visual_deck_editor/visual_deck_editor_widget.h"
|
||||
#include "../tab_deck_editor.h"
|
||||
#include "../tab_supervisor.h"
|
||||
#include "pb/command_deck_upload.pb.h"
|
||||
#include "tab_deck_editor_visual_tab_widget.h"
|
||||
#include "trice_limits.h"
|
||||
|
||||
#include <QAction>
|
||||
#include <QApplication>
|
||||
#include <QCloseEvent>
|
||||
#include <QCompleter>
|
||||
#include <QDir>
|
||||
#include <QDockWidget>
|
||||
#include <QFileDialog>
|
||||
#include <QHeaderView>
|
||||
#include <QLineEdit>
|
||||
#include <QMenu>
|
||||
#include <QPrintPreviewDialog>
|
||||
#include <QProcessEnvironment>
|
||||
#include <QSplitter>
|
||||
#include <QTextStream>
|
||||
#include <QTimer>
|
||||
#include <QTreeView>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
TabDeckEditorVisual::TabDeckEditorVisual(TabSupervisor *_tabSupervisor) : AbstractTabDeckEditor(_tabSupervisor)
|
||||
{
|
||||
setObjectName("TabDeckEditorVisual");
|
||||
|
||||
createCentralFrame();
|
||||
|
||||
TabDeckEditorVisual::createMenus();
|
||||
|
||||
installEventFilter(this);
|
||||
|
||||
TabDeckEditorVisual::retranslateUi();
|
||||
connect(&SettingsCache::instance().shortcuts(), SIGNAL(shortCutChanged()), this, SLOT(refreshShortcuts()));
|
||||
TabDeckEditorVisual::refreshShortcuts();
|
||||
|
||||
TabDeckEditorVisual::loadLayout();
|
||||
databaseDisplayDockWidget->setHidden(true);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::createCentralFrame()
|
||||
{
|
||||
centralWidget = new QWidget(this);
|
||||
centralWidget->setObjectName("centralWidget");
|
||||
|
||||
centralFrame = new QVBoxLayout;
|
||||
centralWidget->setLayout(centralFrame);
|
||||
|
||||
tabContainer = new TabDeckEditorVisualTabWidget(centralWidget, this, deckDockWidget->deckModel,
|
||||
databaseDisplayDockWidget->databaseModel,
|
||||
databaseDisplayDockWidget->databaseDisplayModel);
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardChanged, this,
|
||||
&TabDeckEditorVisual::changeModelIndexAndCardInfo);
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardChangedDatabaseDisplay, this,
|
||||
&AbstractTabDeckEditor::updateCard);
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardClicked, this,
|
||||
&TabDeckEditorVisual::processMainboardCardClick);
|
||||
|
||||
connect(tabContainer, &TabDeckEditorVisualTabWidget::cardClickedDatabaseDisplay, this,
|
||||
&TabDeckEditorVisual::processCardClickDatabaseDisplay);
|
||||
centralFrame->addWidget(tabContainer);
|
||||
|
||||
setCentralWidget(centralWidget);
|
||||
setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::onDeckChanged()
|
||||
{
|
||||
AbstractTabDeckEditor::onDeckChanged();
|
||||
tabContainer->visualDeckView->decklistDataChanged(QModelIndex(), QModelIndex());
|
||||
tabContainer->deckAnalytics->refreshDisplays(deckDockWidget->deckModel);
|
||||
tabContainer->sampleHandWidget->setDeckModel(deckDockWidget->deckModel);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::createMenus()
|
||||
{
|
||||
deckMenu = new DeckEditorMenu(this);
|
||||
addTabMenu(deckMenu);
|
||||
|
||||
viewMenu = new QMenu(this);
|
||||
|
||||
cardInfoDockMenu = viewMenu->addMenu(QString());
|
||||
deckDockMenu = viewMenu->addMenu(QString());
|
||||
deckAnalyticsMenu = viewMenu->addMenu(QString());
|
||||
filterDockMenu = viewMenu->addMenu(QString());
|
||||
printingSelectorDockMenu = viewMenu->addMenu(QString());
|
||||
|
||||
aCardInfoDockVisible = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockVisible->setCheckable(true);
|
||||
connect(aCardInfoDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
aCardInfoDockFloating = cardInfoDockMenu->addAction(QString());
|
||||
aCardInfoDockFloating->setCheckable(true);
|
||||
connect(aCardInfoDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
|
||||
aDeckDockVisible = deckDockMenu->addAction(QString());
|
||||
aDeckDockVisible->setCheckable(true);
|
||||
connect(aDeckDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
aDeckDockFloating = deckDockMenu->addAction(QString());
|
||||
aDeckDockFloating->setCheckable(true);
|
||||
connect(aDeckDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
|
||||
aDeckAnalyticsDockVisible = deckAnalyticsMenu->addAction(QString());
|
||||
aDeckAnalyticsDockVisible->setCheckable(true);
|
||||
connect(aDeckAnalyticsDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
aDeckAnalyticsDockFloating = deckAnalyticsMenu->addAction(QString());
|
||||
aDeckAnalyticsDockFloating->setCheckable(true);
|
||||
connect(aDeckAnalyticsDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
|
||||
aFilterDockVisible = filterDockMenu->addAction(QString());
|
||||
aFilterDockVisible->setCheckable(true);
|
||||
connect(aFilterDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
aFilterDockFloating = filterDockMenu->addAction(QString());
|
||||
aFilterDockFloating->setCheckable(true);
|
||||
connect(aFilterDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
|
||||
aPrintingSelectorDockVisible = printingSelectorDockMenu->addAction(QString());
|
||||
aPrintingSelectorDockVisible->setCheckable(true);
|
||||
connect(aPrintingSelectorDockVisible, SIGNAL(triggered()), this, SLOT(dockVisibleTriggered()));
|
||||
aPrintingSelectorDockFloating = printingSelectorDockMenu->addAction(QString());
|
||||
aPrintingSelectorDockFloating->setCheckable(true);
|
||||
connect(aPrintingSelectorDockFloating, SIGNAL(triggered()), this, SLOT(dockFloatingTriggered()));
|
||||
|
||||
viewMenu->addSeparator();
|
||||
|
||||
aResetLayout = viewMenu->addAction(QString());
|
||||
connect(aResetLayout, SIGNAL(triggered()), this, SLOT(restartLayout()));
|
||||
viewMenu->addAction(aResetLayout);
|
||||
|
||||
deckMenu->setSaveStatus(false);
|
||||
|
||||
addTabMenu(viewMenu);
|
||||
}
|
||||
|
||||
QString TabDeckEditorVisual::getTabText() const
|
||||
{
|
||||
QString result = tr("Visual Deck: %1").arg(deckDockWidget->getSimpleDeckName());
|
||||
if (modified)
|
||||
result.prepend("* ");
|
||||
return result;
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::changeModelIndexAndCardInfo(const CardInfoPtr &activeCard)
|
||||
{
|
||||
updateCard(activeCard);
|
||||
changeModelIndexToCard(activeCard);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::changeModelIndexToCard(const CardInfoPtr &activeCard)
|
||||
{
|
||||
QString cardName = activeCard->getName();
|
||||
QModelIndex index = deckDockWidget->deckModel->findCard(cardName, DECK_ZONE_MAIN);
|
||||
if (!index.isValid()) {
|
||||
index = deckDockWidget->deckModel->findCard(cardName, DECK_ZONE_SIDE);
|
||||
}
|
||||
deckDockWidget->deckView->setCurrentIndex(index);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::processMainboardCardClick(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance,
|
||||
QString zoneName)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
actSwapCard(instance->getInfo(), zoneName);
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
actDecrementCard(instance->getInfo());
|
||||
} else if (event->button() == Qt::MiddleButton) {
|
||||
deckDockWidget->actRemoveCard();
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::processCardClickDatabaseDisplay(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance)
|
||||
{
|
||||
if (event->button() == Qt::LeftButton) {
|
||||
actAddCard(instance->getInfo());
|
||||
} else if (event->button() == Qt::RightButton) {
|
||||
actDecrementCard(instance->getInfo());
|
||||
} else if (event->button() == Qt::MiddleButton) {
|
||||
deckDockWidget->actRemoveCard();
|
||||
}
|
||||
}
|
||||
|
||||
bool TabDeckEditorVisual::actSaveDeckAs()
|
||||
{
|
||||
// We have to disable the quick-add search bar or else it'll steal focus after dialog creation.
|
||||
tabContainer->visualDeckView->searchBar->setEnabled(false);
|
||||
auto result = AbstractTabDeckEditor::actSaveDeckAs();
|
||||
tabContainer->visualDeckView->searchBar->setEnabled(true);
|
||||
return result;
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::showPrintingSelector()
|
||||
{
|
||||
printingSelectorDockWidget->printingSelector->setCard(cardInfoDockWidget->cardInfo->getInfo(), DECK_ZONE_MAIN);
|
||||
printingSelectorDockWidget->printingSelector->updateDisplay();
|
||||
aPrintingSelectorDockVisible->setChecked(true);
|
||||
printingSelectorDockWidget->setVisible(true);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::restartLayout()
|
||||
{
|
||||
deckDockWidget->setVisible(true);
|
||||
cardInfoDockWidget->setVisible(true);
|
||||
filterDockWidget->setVisible(true);
|
||||
|
||||
deckDockWidget->setFloating(false);
|
||||
cardInfoDockWidget->setFloating(false);
|
||||
filterDockWidget->setFloating(false);
|
||||
|
||||
aCardInfoDockVisible->setChecked(true);
|
||||
aDeckDockVisible->setChecked(true);
|
||||
aFilterDockVisible->setChecked(true);
|
||||
|
||||
aCardInfoDockFloating->setChecked(false);
|
||||
aDeckDockFloating->setChecked(false);
|
||||
aFilterDockFloating->setChecked(false);
|
||||
|
||||
addDockWidget(static_cast<Qt::DockWidgetArea>(2), deckDockWidget);
|
||||
addDockWidget(static_cast<Qt::DockWidgetArea>(2), cardInfoDockWidget);
|
||||
addDockWidget(static_cast<Qt::DockWidgetArea>(1), deckAnalyticsDock);
|
||||
addDockWidget(static_cast<Qt::DockWidgetArea>(2), filterDockWidget);
|
||||
|
||||
splitDockWidget(cardInfoDockWidget, deckDockWidget, Qt::Horizontal);
|
||||
splitDockWidget(cardInfoDockWidget, filterDockWidget, Qt::Vertical);
|
||||
splitDockWidget(searchAndDatabaseDock, deckAnalyticsDock, Qt::Vertical);
|
||||
|
||||
deckDockWidget->setMinimumWidth(360);
|
||||
deckDockWidget->setMaximumWidth(360);
|
||||
|
||||
cardInfoDockWidget->setMinimumSize(250, 360);
|
||||
cardInfoDockWidget->setMaximumSize(250, 360);
|
||||
QTimer::singleShot(100, this, SLOT(freeDocksSize()));
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::freeDocksSize()
|
||||
{
|
||||
deckDockWidget->setMinimumSize(100, 100);
|
||||
deckDockWidget->setMaximumSize(5000, 5000);
|
||||
|
||||
cardInfoDockWidget->setMinimumSize(100, 100);
|
||||
cardInfoDockWidget->setMaximumSize(5000, 5000);
|
||||
|
||||
filterDockWidget->setMinimumSize(100, 100);
|
||||
filterDockWidget->setMaximumSize(5000, 5000);
|
||||
|
||||
databaseDisplayDockWidget->setMinimumSize(100, 100);
|
||||
databaseDisplayDockWidget->setMaximumSize(1400, 5000);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::refreshShortcuts()
|
||||
{
|
||||
ShortcutsSettings &shortcuts = SettingsCache::instance().shortcuts();
|
||||
aResetLayout->setShortcuts(shortcuts.getShortcut("TabDeckEditorVisual/aResetLayout"));
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::loadLayout()
|
||||
{
|
||||
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||
auto &layoutState = layouts.getDeckEditorLayoutState();
|
||||
if (layoutState.isNull()) {
|
||||
restartLayout();
|
||||
} else {
|
||||
restoreState(layoutState);
|
||||
restoreGeometry(layouts.getDeckEditorGeometry());
|
||||
}
|
||||
|
||||
aCardInfoDockVisible->setChecked(!cardInfoDockWidget->isHidden());
|
||||
aFilterDockVisible->setChecked(!filterDockWidget->isHidden());
|
||||
aDeckDockVisible->setChecked(!deckDockWidget->isHidden());
|
||||
aPrintingSelectorDockVisible->setChecked(!printingSelectorDockWidget->isHidden());
|
||||
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||
aFilterDockFloating->setEnabled(aFilterDockVisible->isChecked());
|
||||
aPrintingSelectorDockFloating->setEnabled(aPrintingSelectorDockVisible->isChecked());
|
||||
|
||||
aCardInfoDockFloating->setChecked(cardInfoDockWidget->isFloating());
|
||||
aFilterDockFloating->setChecked(filterDockWidget->isFloating());
|
||||
aDeckDockFloating->setChecked(deckDockWidget->isFloating());
|
||||
aPrintingSelectorDockFloating->setChecked(printingSelectorDockWidget->isFloating());
|
||||
|
||||
cardInfoDockWidget->setMinimumSize(layouts.getDeckEditorCardSize());
|
||||
cardInfoDockWidget->setMaximumSize(layouts.getDeckEditorCardSize());
|
||||
|
||||
filterDockWidget->setMinimumSize(layouts.getDeckEditorFilterSize());
|
||||
filterDockWidget->setMaximumSize(layouts.getDeckEditorFilterSize());
|
||||
|
||||
deckDockWidget->setMinimumSize(layouts.getDeckEditorDeckSize());
|
||||
deckDockWidget->setMaximumSize(layouts.getDeckEditorDeckSize());
|
||||
|
||||
printingSelectorDockWidget->setMinimumSize(layouts.getDeckEditorPrintingSelectorSize());
|
||||
printingSelectorDockWidget->setMaximumSize(layouts.getDeckEditorPrintingSelectorSize());
|
||||
|
||||
databaseDisplayDockWidget->setMinimumSize(100, 100);
|
||||
databaseDisplayDockWidget->setMaximumSize(1400, 5000);
|
||||
|
||||
QTimer::singleShot(100, this, &TabDeckEditorVisual::freeDocksSize);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::retranslateUi()
|
||||
{
|
||||
deckMenu->setTitle(tr("&Visual Deck Editor"));
|
||||
|
||||
cardInfoDockWidget->setWindowTitle(tr("Card Info"));
|
||||
deckDockWidget->setWindowTitle(tr("Deck"));
|
||||
filterDockWidget->setWindowTitle(tr("Filters"));
|
||||
|
||||
viewMenu->setTitle(tr("&View"));
|
||||
cardInfoDockMenu->setTitle(tr("Card Info"));
|
||||
deckDockMenu->setTitle(tr("Deck"));
|
||||
deckAnalyticsMenu->setTitle(tr("Deck Analytics"));
|
||||
filterDockMenu->setTitle(tr("Filters"));
|
||||
printingSelectorDockMenu->setTitle(tr("Printing"));
|
||||
|
||||
aCardInfoDockVisible->setText(tr("Visible"));
|
||||
aCardInfoDockFloating->setText(tr("Floating"));
|
||||
|
||||
aDeckDockVisible->setText(tr("Visible"));
|
||||
aDeckDockFloating->setText(tr("Floating"));
|
||||
|
||||
aDeckAnalyticsDockVisible->setText(tr("Visible"));
|
||||
aDeckAnalyticsDockFloating->setText(tr("Floating"));
|
||||
|
||||
aFilterDockVisible->setText(tr("Visible"));
|
||||
aFilterDockFloating->setText(tr("Floating"));
|
||||
|
||||
aPrintingSelectorDockVisible->setText(tr("Visible"));
|
||||
aPrintingSelectorDockFloating->setText(tr("Floating"));
|
||||
|
||||
aResetLayout->setText(tr("Reset layout"));
|
||||
}
|
||||
|
||||
// Method uses to sync docks state with menu items state
|
||||
bool TabDeckEditorVisual::eventFilter(QObject *o, QEvent *e)
|
||||
{
|
||||
if (e->type() == QEvent::Close) {
|
||||
if (o == cardInfoDockWidget) {
|
||||
aCardInfoDockVisible->setChecked(false);
|
||||
aCardInfoDockFloating->setEnabled(false);
|
||||
} else if (o == deckDockWidget) {
|
||||
aDeckDockVisible->setChecked(false);
|
||||
aDeckDockFloating->setEnabled(false);
|
||||
} else if (o == deckAnalyticsDock) {
|
||||
aDeckAnalyticsDockVisible->setChecked(false);
|
||||
aDeckAnalyticsDockFloating->setEnabled(false);
|
||||
} else if (o == filterDockWidget) {
|
||||
aFilterDockVisible->setChecked(false);
|
||||
aFilterDockFloating->setEnabled(false);
|
||||
} else if (o == printingSelectorDockWidget) {
|
||||
aPrintingSelectorDockVisible->setChecked(false);
|
||||
aPrintingSelectorDockFloating->setEnabled(false);
|
||||
}
|
||||
}
|
||||
if (o == this && e->type() == QEvent::Hide) {
|
||||
LayoutsSettings &layouts = SettingsCache::instance().layouts();
|
||||
layouts.setDeckEditorLayoutState(saveState());
|
||||
layouts.setDeckEditorGeometry(saveGeometry());
|
||||
layouts.setDeckEditorCardSize(cardInfoDockWidget->size());
|
||||
layouts.setDeckEditorFilterSize(filterDockWidget->size());
|
||||
layouts.setDeckEditorDeckSize(deckDockWidget->size());
|
||||
layouts.setDeckEditorPrintingSelectorSize(printingSelectorDockWidget->size());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::dockVisibleTriggered()
|
||||
{
|
||||
QObject *o = sender();
|
||||
if (o == aCardInfoDockVisible) {
|
||||
cardInfoDockWidget->setHidden(!aCardInfoDockVisible->isChecked());
|
||||
aCardInfoDockFloating->setEnabled(aCardInfoDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aDeckDockVisible) {
|
||||
deckDockWidget->setHidden(!aDeckDockVisible->isChecked());
|
||||
aDeckDockFloating->setEnabled(aDeckDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aDeckAnalyticsDockVisible) {
|
||||
deckAnalyticsDock->setHidden(!aDeckAnalyticsDockVisible->isChecked());
|
||||
aDeckAnalyticsDockFloating->setEnabled(aDeckAnalyticsDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aFilterDockVisible) {
|
||||
filterDockWidget->setHidden(!aFilterDockVisible->isChecked());
|
||||
aFilterDockFloating->setEnabled(aFilterDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aPrintingSelectorDockVisible) {
|
||||
printingSelectorDockWidget->setHidden(!aPrintingSelectorDockVisible->isChecked());
|
||||
aPrintingSelectorDockFloating->setEnabled(aPrintingSelectorDockVisible->isChecked());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::dockFloatingTriggered()
|
||||
{
|
||||
QObject *o = sender();
|
||||
if (o == aCardInfoDockFloating) {
|
||||
cardInfoDockWidget->setFloating(aCardInfoDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aDeckDockFloating) {
|
||||
deckDockWidget->setFloating(aDeckDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aDeckAnalyticsDockFloating) {
|
||||
deckAnalyticsDock->setFloating(aDeckAnalyticsDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aFilterDockFloating) {
|
||||
filterDockWidget->setFloating(aFilterDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == aPrintingSelectorDockFloating) {
|
||||
printingSelectorDockWidget->setFloating(aPrintingSelectorDockFloating->isChecked());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckEditorVisual::dockTopLevelChanged(bool topLevel)
|
||||
{
|
||||
QObject *o = sender();
|
||||
if (o == cardInfoDockWidget) {
|
||||
aCardInfoDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == deckDockWidget) {
|
||||
aDeckDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == filterDockWidget) {
|
||||
aFilterDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == deckAnalyticsDock) {
|
||||
aDeckAnalyticsDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
|
||||
if (o == printingSelectorDockWidget) {
|
||||
aPrintingSelectorDockFloating->setChecked(topLevel);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef WINDOW_DECKEDITORVISUAL_H
|
||||
#define WINDOW_DECKEDITORVISUAL_H
|
||||
|
||||
#include "../tab.h"
|
||||
#include "tab_deck_editor_visual_tab_widget.h"
|
||||
|
||||
class TabDeckEditorVisual : public AbstractTabDeckEditor
|
||||
{
|
||||
Q_OBJECT
|
||||
protected slots:
|
||||
void loadLayout() override;
|
||||
void restartLayout() override;
|
||||
void freeDocksSize() override;
|
||||
void refreshShortcuts() override;
|
||||
|
||||
bool eventFilter(QObject *o, QEvent *e) override;
|
||||
void dockVisibleTriggered() override;
|
||||
void dockFloatingTriggered() override;
|
||||
void dockTopLevelChanged(bool topLevel) override;
|
||||
|
||||
protected:
|
||||
TabDeckEditorVisualTabWidget *tabContainer;
|
||||
|
||||
QVBoxLayout *centralFrame;
|
||||
QVBoxLayout *searchAndDatabaseFrame;
|
||||
QHBoxLayout *searchLayout;
|
||||
QDockWidget *searchAndDatabaseDock;
|
||||
QDockWidget *deckAnalyticsDock;
|
||||
QWidget *centralWidget;
|
||||
QMenu *deckAnalyticsMenu;
|
||||
QAction *aDeckAnalyticsDockVisible, *aDeckAnalyticsDockFloating;
|
||||
|
||||
public:
|
||||
explicit TabDeckEditorVisual(TabSupervisor *_tabSupervisor);
|
||||
void retranslateUi() override;
|
||||
QString getTabText() const override;
|
||||
void changeModelIndexAndCardInfo(const CardInfoPtr &activeCard);
|
||||
void changeModelIndexToCard(const CardInfoPtr &activeCard);
|
||||
void createDeckAnalyticsDock();
|
||||
void createMenus() override;
|
||||
void createSearchAndDatabaseFrame();
|
||||
void createCentralFrame();
|
||||
|
||||
public slots:
|
||||
void onDeckChanged() override;
|
||||
void showPrintingSelector() override;
|
||||
void
|
||||
processMainboardCardClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
void processCardClickDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
bool actSaveDeckAs() override;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
#include "tab_deck_editor_visual_tab_widget.h"
|
||||
|
||||
#include "../../ui/widgets/visual_database_display/visual_database_display_widget.h"
|
||||
#include "../abstract_tab_deck_editor.h"
|
||||
|
||||
TabDeckEditorVisualTabWidget::TabDeckEditorVisualTabWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *_deckEditor,
|
||||
DeckListModel *_deckModel,
|
||||
CardDatabaseModel *_cardDatabaseModel,
|
||||
CardDatabaseDisplayModel *_cardDatabaseDisplayModel)
|
||||
: QTabWidget(parent), deckEditor(_deckEditor), deckModel(_deckModel), cardDatabaseModel(_cardDatabaseModel),
|
||||
cardDatabaseDisplayModel(_cardDatabaseDisplayModel)
|
||||
{
|
||||
this->setTabsClosable(true); // Enable tab closing
|
||||
connect(this, &QTabWidget::tabCloseRequested, this, &TabDeckEditorVisualTabWidget::handleTabClose);
|
||||
|
||||
// Set up the layout and add tab widget
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
visualDeckView = new VisualDeckEditorWidget(this, deckModel);
|
||||
visualDeckView->setObjectName("visualDeckView");
|
||||
connect(visualDeckView, &VisualDeckEditorWidget::activeCardChanged, this,
|
||||
&TabDeckEditorVisualTabWidget::onCardChanged);
|
||||
connect(visualDeckView, &VisualDeckEditorWidget::cardClicked, this,
|
||||
&TabDeckEditorVisualTabWidget::onCardClickedDeckEditor);
|
||||
connect(visualDeckView, &VisualDeckEditorWidget::cardAdditionRequested, deckEditor,
|
||||
&AbstractTabDeckEditor::actAddCard);
|
||||
|
||||
visualDatabaseDisplay =
|
||||
new VisualDatabaseDisplayWidget(this, deckEditor, _cardDatabaseModel, _cardDatabaseDisplayModel);
|
||||
visualDatabaseDisplay->setObjectName("visualDatabaseView");
|
||||
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardHoveredDatabaseDisplay, this,
|
||||
&TabDeckEditorVisualTabWidget::onCardChangedDatabaseDisplay);
|
||||
connect(visualDatabaseDisplay, &VisualDatabaseDisplayWidget::cardClickedDatabaseDisplay, this,
|
||||
&TabDeckEditorVisualTabWidget::onCardClickedDatabaseDisplay);
|
||||
|
||||
deckAnalytics = new DeckAnalyticsWidget(this, deckModel);
|
||||
deckAnalytics->setObjectName("deckAnalytics");
|
||||
|
||||
sampleHandWidget = new VisualDeckEditorSampleHandWidget(this, deckModel);
|
||||
|
||||
this->addNewTab(visualDeckView, tr("Visual Deck View"));
|
||||
this->addNewTab(visualDatabaseDisplay, tr("Visual Database Display"));
|
||||
this->addNewTab(deckAnalytics, tr("Deck Analytics"));
|
||||
this->addNewTab(sampleHandWidget, tr("Sample Hand"));
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::onCardChanged(CardInfoPtr activeCard)
|
||||
{
|
||||
emit cardChanged(activeCard);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::onCardChangedDatabaseDisplay(CardInfoPtr activeCard)
|
||||
{
|
||||
emit cardChangedDatabaseDisplay(activeCard);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::onCardClickedDeckEditor(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance,
|
||||
QString zoneName)
|
||||
{
|
||||
emit cardClicked(event, instance, zoneName);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::onCardClickedDatabaseDisplay(QMouseEvent *event,
|
||||
CardInfoPictureWithTextOverlayWidget *instance)
|
||||
{
|
||||
emit cardClickedDatabaseDisplay(event, instance);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::addNewTab(QWidget *widget, const QString &title)
|
||||
{
|
||||
// Add new tab to the tab widget
|
||||
this->addTab(widget, title);
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::removeCurrentTab()
|
||||
{
|
||||
// Remove the currently selected tab
|
||||
int currentIndex = this->currentIndex();
|
||||
if (currentIndex != -1) {
|
||||
this->removeTab(currentIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::setTabTitle(int index, const QString &title)
|
||||
{
|
||||
// Set the title of the tab at the given index
|
||||
if (index >= 0 && index < this->count()) {
|
||||
this->setTabText(index, title);
|
||||
}
|
||||
}
|
||||
|
||||
QWidget *TabDeckEditorVisualTabWidget::getCurrentTab() const
|
||||
{
|
||||
// Return the currently selected tab widget
|
||||
return this->currentWidget();
|
||||
}
|
||||
|
||||
int TabDeckEditorVisualTabWidget::getTabCount() const
|
||||
{
|
||||
// Return the number of tabs
|
||||
return this->count();
|
||||
}
|
||||
|
||||
void TabDeckEditorVisualTabWidget::handleTabClose(int index)
|
||||
{
|
||||
// Handle closing of the tab at the given index
|
||||
QWidget *tab = this->widget(index);
|
||||
this->removeTab(index);
|
||||
delete tab; // Delete the tab's widget to free memory
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#ifndef TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H
|
||||
#define TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H
|
||||
|
||||
#include "../../ui/widgets/deck_analytics/deck_analytics_widget.h"
|
||||
#include "../../ui/widgets/printing_selector/printing_selector.h"
|
||||
#include "../../ui/widgets/visual_database_display/visual_database_display_widget.h"
|
||||
#include "../../ui/widgets/visual_deck_editor/visual_deck_editor_sample_hand_widget.h"
|
||||
#include "../../ui/widgets/visual_deck_editor/visual_deck_editor_widget.h"
|
||||
#include "../abstract_tab_deck_editor.h"
|
||||
|
||||
#include <QTabWidget>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class TabDeckEditorVisualTabWidget : public QTabWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TabDeckEditorVisualTabWidget(QWidget *parent,
|
||||
AbstractTabDeckEditor *_deckEditor,
|
||||
DeckListModel *_deckModel,
|
||||
CardDatabaseModel *_cardDatabaseModel,
|
||||
CardDatabaseDisplayModel *_cardDatabaseDisplayModel);
|
||||
|
||||
// Utility functions
|
||||
void addNewTab(QWidget *widget, const QString &title);
|
||||
void removeCurrentTab();
|
||||
void setTabTitle(int index, const QString &title);
|
||||
QWidget *getCurrentTab() const;
|
||||
int getTabCount() const;
|
||||
|
||||
VisualDeckEditorWidget *visualDeckView;
|
||||
DeckAnalyticsWidget *deckAnalytics;
|
||||
VisualDatabaseDisplayWidget *visualDatabaseDisplay;
|
||||
PrintingSelector *printingSelector;
|
||||
VisualDeckEditorSampleHandWidget *sampleHandWidget;
|
||||
|
||||
public slots:
|
||||
void onCardChanged(CardInfoPtr activeCard);
|
||||
void onCardChangedDatabaseDisplay(CardInfoPtr activeCard);
|
||||
void onCardClickedDeckEditor(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
void onCardClickedDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
|
||||
signals:
|
||||
void cardChanged(CardInfoPtr activeCard);
|
||||
void cardChangedDatabaseDisplay(CardInfoPtr activeCard);
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance, QString zoneName);
|
||||
void cardClickedDatabaseDisplay(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *instance);
|
||||
|
||||
private:
|
||||
QVBoxLayout *layout; // Layout for the tab widget and other controls
|
||||
AbstractTabDeckEditor *deckEditor;
|
||||
DeckListModel *deckModel;
|
||||
CardDatabaseModel *cardDatabaseModel;
|
||||
CardDatabaseDisplayModel *cardDatabaseDisplayModel;
|
||||
|
||||
private slots:
|
||||
void handleTabClose(int index); // Slot for closing a tab
|
||||
};
|
||||
|
||||
#endif // TAB_DECK_EDITOR_VISUAL_TAB_WIDGET_H
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
TabDeckStorageVisual::TabDeckStorageVisual(TabSupervisor *_tabSupervisor)
|
||||
: Tab(_tabSupervisor), visualDeckStorageWidget(new VisualDeckStorageWidget(this))
|
||||
{
|
||||
connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::addDeckEditorTab);
|
||||
connect(this, &TabDeckStorageVisual::openDeckEditor, tabSupervisor, &TabSupervisor::addVisualDeckEditorTab);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::deckLoadRequested, this,
|
||||
&TabDeckStorageVisual::actOpenLocalDeck);
|
||||
connect(visualDeckStorageWidget, &VisualDeckStorageWidget::openDeckEditor, this,
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ void TappedOutInterface::queryFinished(QNetworkReply *reply)
|
|||
* can be extracted from the header. The http status is a 302 "redirect".
|
||||
*/
|
||||
QString deckUrl = reply->rawHeader("Location");
|
||||
qCDebug(TappedOutInterfaceLog) << "Tappedout: good reply, http status" << httpStatus << "location" << deckUrl;
|
||||
qCInfo(TappedOutInterfaceLog) << "Tappedout: good reply, http status" << httpStatus << "location" << deckUrl;
|
||||
QDesktopServices::openUrl("https://tappedout.net" + deckUrl);
|
||||
} else {
|
||||
/*
|
||||
|
|
@ -57,8 +57,8 @@ void TappedOutInterface::queryFinished(QNetworkReply *reply)
|
|||
}
|
||||
|
||||
QString errorMessage = errorMessageList.join("\n");
|
||||
qCDebug(TappedOutInterfaceLog) << "Tappedout: bad reply, http status" << httpStatus << "size" << data.size()
|
||||
<< "message" << errorMessage;
|
||||
qCWarning(TappedOutInterfaceLog) << "Tappedout: bad reply, http status" << httpStatus << "size" << data.size()
|
||||
<< "message" << errorMessage;
|
||||
|
||||
QMessageBox::critical(nullptr, tr("Error"), errorMessage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
#include <QWidget>
|
||||
#include <qstyle.h>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(FlowLayoutLog, "flow_layout");
|
||||
inline Q_LOGGING_CATEGORY(FlowLayoutLog, "flow_layout", QtInfoMsg);
|
||||
|
||||
class FlowLayout : public QLayout
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "overlap_layout.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QtMath>
|
||||
|
||||
/**
|
||||
|
|
@ -32,9 +33,10 @@ OverlapLayout::OverlapLayout(QWidget *parent,
|
|||
const int overlapPercentage,
|
||||
const int maxColumns,
|
||||
const int maxRows,
|
||||
const Qt::Orientation direction)
|
||||
const Qt::Orientation _overlapDirection,
|
||||
const Qt::Orientation _flowDirection)
|
||||
: QLayout(parent), overlapPercentage(overlapPercentage), maxColumns(maxColumns), maxRows(maxRows),
|
||||
direction(direction)
|
||||
overlapDirection(_overlapDirection), flowDirection(_flowDirection)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
@ -148,17 +150,21 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
|||
}
|
||||
|
||||
// Calculate the overlap offsets based on the layout direction and overlap percentage.
|
||||
const int overlapOffsetWidth = (direction == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
||||
const int overlapOffsetHeight = (direction == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
||||
const int overlapOffsetWidth = (overlapDirection == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
||||
const int overlapOffsetHeight = (overlapDirection == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
||||
|
||||
// Determine the number of columns based on layout constraints and available space.
|
||||
int columns;
|
||||
if (direction == Qt::Horizontal) {
|
||||
if (flowDirection == Qt::Horizontal) {
|
||||
if (maxColumns > 0) {
|
||||
// Calculate the maximum possible columns given the available width and overlap.
|
||||
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
||||
// Use the smaller of maxColumns and availableColumns.
|
||||
qCDebug(OverlapLayoutLog) << " Max Columns " << maxColumns << " available columns " << availableColumns;
|
||||
columns = qMin(maxColumns, availableColumns);
|
||||
if (columns < 1) {
|
||||
columns = 1;
|
||||
}
|
||||
} else {
|
||||
// If no maxColumns constraint, allow as many columns as possible.
|
||||
columns = INT_MAX;
|
||||
|
|
@ -170,12 +176,16 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
|||
|
||||
// Determine the number of rows based on layout constraints and available space.
|
||||
int rows;
|
||||
if (direction == Qt::Vertical) {
|
||||
if (flowDirection == Qt::Vertical) {
|
||||
if (maxRows > 0) {
|
||||
// Calculate the maximum possible rows given the available height and overlap.
|
||||
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
||||
// Use the smaller of maxRows and availableRows.
|
||||
qCDebug(OverlapLayoutLog) << " Max Rows " << maxRows << " available rows " << availableRows;
|
||||
rows = qMin(maxRows, availableRows);
|
||||
if (rows < 1) {
|
||||
rows = 1;
|
||||
}
|
||||
} else {
|
||||
// If no maxRows constraint, allow as many rows as possible.
|
||||
rows = INT_MAX;
|
||||
|
|
@ -200,16 +210,17 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
|||
const int yPos = rect.top() + currentRow * (maxItemHeight - overlapOffsetHeight);
|
||||
item->setGeometry(QRect(xPos, yPos, maxItemWidth, maxItemHeight));
|
||||
|
||||
// TODO: Figure this out properly or maybe adjust size hint to account for this?
|
||||
// Update row and column indices based on the layout direction.
|
||||
if (direction == Qt::Horizontal) {
|
||||
if (overlapDirection == Qt::Horizontal) {
|
||||
currentColumn++;
|
||||
if (currentColumn >= columns) {
|
||||
if (currentColumn > qCeil(itemList.size() / rows)) {
|
||||
currentColumn = 0;
|
||||
currentRow++;
|
||||
}
|
||||
} else {
|
||||
currentRow++;
|
||||
if (currentRow >= rows) {
|
||||
if (currentRow > qCeil(itemList.size() / columns)) {
|
||||
currentRow = 0;
|
||||
currentColumn++;
|
||||
}
|
||||
|
|
@ -223,88 +234,86 @@ void OverlapLayout::setGeometry(const QRect &rect)
|
|||
*/
|
||||
QSize OverlapLayout::calculatePreferredSize() const
|
||||
{
|
||||
// Get the parent widget for size and margin calculations.
|
||||
const QWidget *parentWidget = this->parentWidget();
|
||||
if (!parentWidget) {
|
||||
return QSize(0, 0);
|
||||
}
|
||||
|
||||
// Determine the maximum item dimensions.
|
||||
if (itemList.isEmpty()) {
|
||||
return QSize(0, 0);
|
||||
}
|
||||
|
||||
int availableWidth = parentWidget->width();
|
||||
int availableHeight = parentWidget->height();
|
||||
const QMargins margins = parentWidget->contentsMargins();
|
||||
availableWidth -= margins.left() + margins.right();
|
||||
availableHeight -= margins.top() + margins.bottom();
|
||||
|
||||
// Determine the maximum item width and height among all layout items.
|
||||
int maxItemWidth = 0;
|
||||
int maxItemHeight = 0;
|
||||
for (QLayoutItem *item : itemList) {
|
||||
if (item == nullptr) {
|
||||
continue;
|
||||
if (item != nullptr && item->widget()) {
|
||||
QSize itemSize = item->widget()->sizeHint();
|
||||
maxItemWidth = qMax(maxItemWidth, itemSize.width());
|
||||
maxItemHeight = qMax(maxItemHeight, itemSize.height());
|
||||
}
|
||||
if (!item->widget()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QSize itemSize = item->widget()->sizeHint();
|
||||
maxItemWidth = qMax(maxItemWidth, itemSize.width());
|
||||
maxItemHeight = qMax(maxItemHeight, itemSize.height());
|
||||
}
|
||||
|
||||
// Calculate the overlap offsets.
|
||||
const int extra_for_overlap = (100 - overlapPercentage);
|
||||
const int overlapOffsetWidth =
|
||||
(direction == Qt::Horizontal) ? qRound((maxItemWidth / 100.0) * extra_for_overlap) : 0;
|
||||
const int overlapOffsetHeight =
|
||||
(direction == Qt::Vertical) ? qRound((maxItemHeight / 100.0) * extra_for_overlap) : 0;
|
||||
// Calculate the overlap offsets based on the layout direction and overlap percentage.
|
||||
const int overlapOffsetWidth = (overlapDirection == Qt::Horizontal) ? (maxItemWidth * overlapPercentage / 100) : 0;
|
||||
const int overlapOffsetHeight = (overlapDirection == Qt::Vertical) ? (maxItemHeight * overlapPercentage / 100) : 0;
|
||||
|
||||
// Variables to hold the total dimensions based on layout orientation.
|
||||
int totalWidth = 0;
|
||||
int totalHeight = 0;
|
||||
|
||||
// Calculate the total size based on the layout direction and constraints.
|
||||
if (direction == Qt::Horizontal) {
|
||||
// Determine the number of columns:
|
||||
// - Use maxColumns if it is greater than 0 (constraint set by the user).
|
||||
// - Otherwise, set the number of columns to the total number of items in the layout.
|
||||
const int numColumns = (maxColumns > 0) ? static_cast<int>(maxColumns) : static_cast<int>(itemList.size());
|
||||
|
||||
// Calculate the extra space required for overlaps between columns:
|
||||
// - Each overlap reduces the effective width of subsequent items.
|
||||
const int extra_space_for_overlaps = overlapOffsetWidth * (numColumns - 1);
|
||||
|
||||
// Total width:
|
||||
// - The first item's width is fully included (maxItemWidth).
|
||||
// - Add the space for all overlaps between adjacent items.
|
||||
totalWidth = maxItemWidth + extra_space_for_overlaps;
|
||||
|
||||
// Determine the number of rows:
|
||||
// - Use maxRows if maxColumns is set (to constrain the number of rows).
|
||||
// - Otherwise, assume a single row.
|
||||
const int numRows =
|
||||
(maxColumns > 0) ? qCeil(static_cast<double>(itemList.size()) / static_cast<double>(numColumns)) : 1;
|
||||
|
||||
// Total height:
|
||||
// - Multiply the number of rows by the item height (maxItemHeight).
|
||||
// - Subtract the height overlap between rows to avoid double-counting.
|
||||
totalHeight = maxItemHeight * numRows - (numRows - 1) * overlapOffsetHeight;
|
||||
} else if (direction == Qt::Vertical) {
|
||||
// Determine the number of columns:
|
||||
// - Use maxRows to calculate how many columns are needed if a row constraint exists.
|
||||
// - Otherwise, assume a single column.
|
||||
const int numColumns =
|
||||
(maxRows != 0) ? qCeil(static_cast<double>(itemList.size()) / static_cast<double>(maxRows)) : 1;
|
||||
|
||||
// Total width:
|
||||
// - Multiply the number of columns by the item width (maxItemWidth).
|
||||
// - Subtract the width overlap between columns to avoid double-counting.
|
||||
totalWidth = maxItemWidth * numColumns - (numColumns - 1) * overlapOffsetWidth;
|
||||
|
||||
// Determine the number of rows:
|
||||
// - Use maxRows if it is greater than 0 (constraint set by the user).
|
||||
// - Otherwise, set the number of rows to the total number of items in the layout.
|
||||
const int numRows = (maxRows > 0) ? static_cast<int>(maxRows) : static_cast<int>(itemList.size());
|
||||
|
||||
// Calculate the extra space required for overlaps between rows:
|
||||
// - Each overlap reduces the effective height of subsequent items.
|
||||
const int extraSpaceForOverlaps = overlapOffsetHeight * (numRows - 1);
|
||||
|
||||
// Total height:
|
||||
// - The first item's height is fully included (maxItemHeight).
|
||||
// - Add the space for all overlaps between adjacent items.
|
||||
totalHeight = maxItemHeight + extraSpaceForOverlaps;
|
||||
// Determine the number of columns based on layout constraints and available space.
|
||||
int columns;
|
||||
if (flowDirection == Qt::Horizontal) {
|
||||
if (maxColumns > 0) {
|
||||
// Calculate the maximum possible columns given the available width and overlap.
|
||||
const int availableColumns = (availableWidth + overlapOffsetWidth) / (maxItemWidth - overlapOffsetWidth);
|
||||
// Use the smaller of maxColumns and availableColumns.
|
||||
qCDebug(OverlapLayoutLog) << " Max Columns " << maxColumns << " available columns " << availableColumns;
|
||||
columns = qMin(maxColumns, availableColumns);
|
||||
if (columns < 1) {
|
||||
columns = 1;
|
||||
}
|
||||
} else {
|
||||
// If no maxColumns constraint, allow as many columns as possible.
|
||||
columns = INT_MAX;
|
||||
}
|
||||
} else {
|
||||
// If not a horizontal layout, column count is irrelevant.
|
||||
columns = INT_MAX;
|
||||
}
|
||||
|
||||
return {totalWidth, totalHeight};
|
||||
// Determine the number of rows based on layout constraints and available space.
|
||||
int rows;
|
||||
if (flowDirection == Qt::Vertical) {
|
||||
if (maxRows > 0) {
|
||||
// Calculate the maximum possible rows given the available height and overlap.
|
||||
const int availableRows = (availableHeight + overlapOffsetHeight) / (maxItemHeight - overlapOffsetHeight);
|
||||
// Use the smaller of maxRows and availableRows.
|
||||
qCDebug(OverlapLayoutLog) << " Max Rows " << maxRows << " available rows " << availableRows;
|
||||
rows = qMin(maxRows, availableRows);
|
||||
if (rows < 1) {
|
||||
rows = 1;
|
||||
}
|
||||
} else {
|
||||
// If no maxRows constraint, allow as many rows as possible.
|
||||
rows = INT_MAX;
|
||||
}
|
||||
} else {
|
||||
// If not a vertical layout, row count is irrelevant.
|
||||
rows = INT_MAX;
|
||||
}
|
||||
|
||||
if (overlapDirection == Qt::Horizontal) {
|
||||
return QSize(maxItemWidth + ((qCeil(itemList.size() / rows)) * (maxItemWidth - overlapOffsetWidth)),
|
||||
rows * maxItemHeight);
|
||||
} else {
|
||||
return QSize(columns * maxItemWidth,
|
||||
maxItemHeight + ((qCeil(itemList.size() / columns)) * (maxItemHeight - overlapOffsetHeight)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -341,7 +350,7 @@ QSize OverlapLayout::minimumSize() const
|
|||
*/
|
||||
void OverlapLayout::setDirection(const Qt::Orientation _direction)
|
||||
{
|
||||
direction = _direction;
|
||||
overlapDirection = _direction;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -378,7 +387,7 @@ void OverlapLayout::setMaxRows(const int _maxRows)
|
|||
*/
|
||||
int OverlapLayout::calculateMaxColumns() const
|
||||
{
|
||||
if (direction != Qt::Vertical || itemList.isEmpty()) {
|
||||
if (overlapDirection != Qt::Vertical || itemList.isEmpty()) {
|
||||
return 1; // Only relevant if the layout direction is vertical
|
||||
}
|
||||
|
||||
|
|
@ -410,7 +419,7 @@ int OverlapLayout::calculateMaxColumns() const
|
|||
*/
|
||||
int OverlapLayout::calculateRowsForColumns(const int columns) const
|
||||
{
|
||||
if (direction != Qt::Vertical || itemList.isEmpty() || columns <= 0) {
|
||||
if (overlapDirection != Qt::Vertical || itemList.isEmpty() || columns <= 0) {
|
||||
return 1; // Only relevant if the layout direction is vertical and there are items
|
||||
}
|
||||
|
||||
|
|
@ -429,7 +438,7 @@ int OverlapLayout::calculateRowsForColumns(const int columns) const
|
|||
*/
|
||||
int OverlapLayout::calculateMaxRows() const
|
||||
{
|
||||
if (direction != Qt::Horizontal || itemList.isEmpty()) {
|
||||
if (overlapDirection != Qt::Horizontal || itemList.isEmpty()) {
|
||||
return 1; // Only relevant if the layout direction is horizontal
|
||||
}
|
||||
|
||||
|
|
@ -464,7 +473,7 @@ int OverlapLayout::calculateMaxRows() const
|
|||
*/
|
||||
int OverlapLayout::calculateColumnsForRows(const int rows) const
|
||||
{
|
||||
if (direction != Qt::Horizontal || itemList.isEmpty() || rows <= 0) {
|
||||
if (overlapDirection != Qt::Horizontal || itemList.isEmpty() || rows <= 0) {
|
||||
return 1; // Only relevant if the layout direction is horizontal and there are items
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,11 @@
|
|||
|
||||
#include <QLayout>
|
||||
#include <QList>
|
||||
#include <QLoggingCategory>
|
||||
#include <QWidget>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(OverlapLayoutLog, "overlap_layout");
|
||||
|
||||
class OverlapLayout : public QLayout
|
||||
{
|
||||
public:
|
||||
|
|
@ -12,7 +15,8 @@ public:
|
|||
int overlapPercentage = 10,
|
||||
int maxColumns = 2,
|
||||
int maxRows = 2,
|
||||
Qt::Orientation direction = Qt::Horizontal);
|
||||
Qt::Orientation overlapDirection = Qt::Vertical,
|
||||
Qt::Orientation flowDirection = Qt::Horizontal);
|
||||
~OverlapLayout();
|
||||
|
||||
void addItem(QLayoutItem *item) override;
|
||||
|
|
@ -35,7 +39,8 @@ private:
|
|||
int overlapPercentage;
|
||||
int maxColumns;
|
||||
int maxRows;
|
||||
Qt::Orientation direction;
|
||||
Qt::Orientation overlapDirection;
|
||||
Qt::Orientation flowDirection;
|
||||
|
||||
// Calculate the preferred size of the layout
|
||||
QSize calculatePreferredSize() const;
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@ void LineEditCompleter::setCompleter(QCompleter *completer)
|
|||
{
|
||||
c = completer;
|
||||
c->setWidget(this);
|
||||
connect(c, SIGNAL(activated(QString)), this, SLOT(insertCompletion(QString)));
|
||||
connect(c, qOverload<const QString &>(&QCompleter::activated), this, &LineEditCompleter::insertCompletion);
|
||||
}
|
||||
|
||||
void LineEditCompleter::setCompletionList(QStringList completionList)
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ PhaseButton::PhaseButton(const QString &_name, QGraphicsItem *parent, QAction *_
|
|||
{
|
||||
if (highlightable) {
|
||||
activeAnimationTimer = new QTimer(this);
|
||||
connect(activeAnimationTimer, SIGNAL(timeout()), this, SLOT(updateAnimation()));
|
||||
connect(activeAnimationTimer, &QTimer::timeout, this, &PhaseButton::updateAnimation);
|
||||
activeAnimationTimer->setSingleShot(false);
|
||||
} else
|
||||
activeAnimationCounter = 9;
|
||||
|
|
@ -106,9 +106,9 @@ PhasesToolbar::PhasesToolbar(QGraphicsItem *parent)
|
|||
: QGraphicsItem(parent), width(100), height(100), ySpacing(1), symbolSize(8)
|
||||
{
|
||||
auto *aUntapAll = new QAction(this);
|
||||
connect(aUntapAll, SIGNAL(triggered()), this, SLOT(actUntapAll()));
|
||||
connect(aUntapAll, &QAction::triggered, this, &PhasesToolbar::actUntapAll);
|
||||
auto *aDrawCard = new QAction(this);
|
||||
connect(aDrawCard, SIGNAL(triggered()), this, SLOT(actDrawCard()));
|
||||
connect(aDrawCard, &QAction::triggered, this, &PhasesToolbar::actDrawCard);
|
||||
|
||||
PhaseButton *untapButton = new PhaseButton("untap", this, aUntapAll);
|
||||
PhaseButton *upkeepButton = new PhaseButton("upkeep", this);
|
||||
|
|
@ -126,10 +126,10 @@ PhasesToolbar::PhasesToolbar(QGraphicsItem *parent)
|
|||
<< combatBlockersButton << combatDamageButton << combatEndButton << main2Button << cleanupButton;
|
||||
|
||||
for (auto &i : buttonList)
|
||||
connect(i, SIGNAL(clicked()), this, SLOT(phaseButtonClicked()));
|
||||
connect(i, &PhaseButton::clicked, this, &PhasesToolbar::phaseButtonClicked);
|
||||
|
||||
nextTurnButton = new PhaseButton("nextturn", this, nullptr, false);
|
||||
connect(nextTurnButton, SIGNAL(clicked()), this, SLOT(actNextTurn()));
|
||||
connect(nextTurnButton, &PhaseButton::clicked, this, &PhasesToolbar::actNextTurn);
|
||||
|
||||
rearrangeButtons();
|
||||
|
||||
|
|
|
|||
|
|
@ -23,11 +23,10 @@
|
|||
PictureLoader::PictureLoader() : QObject(nullptr)
|
||||
{
|
||||
worker = new PictureLoaderWorker;
|
||||
connect(&SettingsCache::instance(), SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged()));
|
||||
connect(&SettingsCache::instance(), SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged()));
|
||||
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this, &PictureLoader::picsPathChanged);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::picDownloadChanged, this, &PictureLoader::picDownloadChanged);
|
||||
|
||||
connect(worker, SIGNAL(imageLoaded(CardInfoPtr, const QImage &)), this,
|
||||
SLOT(imageLoaded(CardInfoPtr, const QImage &)));
|
||||
connect(worker, &PictureLoaderWorker::imageLoaded, this, &PictureLoader::imageLoaded);
|
||||
}
|
||||
|
||||
PictureLoader::~PictureLoader()
|
||||
|
|
@ -115,7 +114,7 @@ void PictureLoader::getPixmap(QPixmap &pixmap, CardInfoPtr card, QSize size)
|
|||
QPixmap bigPixmap;
|
||||
if (QPixmapCache::find(key, &bigPixmap)) {
|
||||
if (bigPixmap.isNull()) {
|
||||
qCWarning(PictureLoaderLog) << "Cached pixmap for key" << key << "is NULL!";
|
||||
qCDebug(PictureLoaderLog) << "Cached pixmap for key" << key << "is NULL!";
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -140,7 +139,11 @@ void PictureLoader::imageLoaded(CardInfoPtr card, const QImage &image)
|
|||
QPixmapCache::insert(card->getPixmapCacheKey(), QPixmap());
|
||||
} else {
|
||||
if (card->getUpsideDownArt()) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 9, 0))
|
||||
QImage mirrorImage = image.flipped(Qt::Horizontal | Qt::Vertical);
|
||||
#else
|
||||
QImage mirrorImage = image.mirrored(true, true);
|
||||
#endif
|
||||
QPixmapCache::insert(card->getPixmapCacheKey(), QPixmap::fromImage(mirrorImage));
|
||||
} else {
|
||||
QPixmapCache::insert(card->getPixmapCacheKey(), QPixmap::fromImage(image));
|
||||
|
|
@ -195,3 +198,31 @@ void PictureLoader::picsPathChanged()
|
|||
{
|
||||
QPixmapCache::clear();
|
||||
}
|
||||
|
||||
bool PictureLoader::hasCustomArt()
|
||||
{
|
||||
auto picsPath = SettingsCache::instance().getPicsPath();
|
||||
QDirIterator it(picsPath, QDir::Dirs | QDir::NoDotAndDotDot);
|
||||
|
||||
// Check if there is at least one non-directory file in the pics path, other
|
||||
// than in the "downloadedPics" subdirectory.
|
||||
while (it.hasNext()) {
|
||||
#if (QT_VERSION >= QT_VERSION_CHECK(6, 3, 0))
|
||||
QFileInfo dir(it.nextFileInfo());
|
||||
#else
|
||||
// nextFileInfo() is only available in Qt 6.3+, for previous versions, we build
|
||||
// the QFileInfo from a QString which requires more system calls.
|
||||
QFileInfo dir(it.next());
|
||||
#endif
|
||||
|
||||
if (it.fileName() == "downloadedPics")
|
||||
continue;
|
||||
|
||||
QDirIterator subIt(it.filePath(), QDir::Files, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
||||
if (subIt.hasNext()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PICTURELOADER_H
|
||||
#define PICTURELOADER_H
|
||||
|
||||
#include "../../../game/cards/card_database.h"
|
||||
#include "../../../game/cards/card_info.h"
|
||||
#include "picture_loader_worker.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
|
@ -36,6 +36,7 @@ public:
|
|||
static void clearPixmapCache(CardInfoPtr card);
|
||||
static void clearPixmapCache();
|
||||
static void cacheCardPixmaps(QList<CardInfoPtr> cards);
|
||||
static bool hasCustomArt();
|
||||
|
||||
public slots:
|
||||
static void clearNetworkCache();
|
||||
|
|
|
|||
|
|
@ -16,11 +16,16 @@ QStringList PictureLoaderWorker::md5Blacklist = QStringList() << "db0c48db407a90
|
|||
PictureLoaderWorker::PictureLoaderWorker()
|
||||
: QObject(nullptr), picsPath(SettingsCache::instance().getPicsPath()),
|
||||
customPicsPath(SettingsCache::instance().getCustomPicsPath()),
|
||||
picDownload(SettingsCache::instance().getPicDownload()), downloadRunning(false), loadQueueRunning(false)
|
||||
picDownload(SettingsCache::instance().getPicDownload()), downloadRunning(false), loadQueueRunning(false),
|
||||
overrideAllCardArtWithPersonalPreference(SettingsCache::instance().getOverrideAllCardArtWithPersonalPreference())
|
||||
{
|
||||
connect(this, SIGNAL(startLoadQueue()), this, SLOT(processLoadQueue()), Qt::QueuedConnection);
|
||||
connect(&SettingsCache::instance(), SIGNAL(picsPathChanged()), this, SLOT(picsPathChanged()));
|
||||
connect(&SettingsCache::instance(), SIGNAL(picDownloadChanged()), this, SLOT(picDownloadChanged()));
|
||||
connect(this, &PictureLoaderWorker::startLoadQueue, this, &PictureLoaderWorker::processLoadQueue,
|
||||
Qt::QueuedConnection);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::picsPathChanged, this, &PictureLoaderWorker::picsPathChanged);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::picDownloadChanged, this,
|
||||
&PictureLoaderWorker::picDownloadChanged);
|
||||
connect(&SettingsCache::instance(), &SettingsCache::overrideAllCardArtWithPersonalPreferenceChanged, this,
|
||||
&PictureLoaderWorker::setOverrideAllCardArtWithPersonalPreference);
|
||||
|
||||
networkManager = new QNetworkAccessManager(this);
|
||||
// We need a timeout to ensure requests don't hang indefinitely in case of
|
||||
|
|
@ -40,7 +45,7 @@ PictureLoaderWorker::PictureLoaderWorker()
|
|||
// Use a ManualRedirectPolicy since we keep track of redirects in picDownloadFinished
|
||||
// We can't use NoLessSafeRedirectPolicy because it is not applied with AlwaysCache
|
||||
networkManager->setRedirectPolicy(QNetworkRequest::ManualRedirectPolicy);
|
||||
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(picDownloadFinished(QNetworkReply *)));
|
||||
connect(networkManager, &QNetworkAccessManager::finished, this, &PictureLoaderWorker::picDownloadFinished);
|
||||
|
||||
cacheFilePath = SettingsCache::instance().getRedirectCachePath() + REDIRECT_CACHE_FILENAME;
|
||||
loadRedirectCache();
|
||||
|
|
@ -83,11 +88,24 @@ void PictureLoaderWorker::processLoadQueue()
|
|||
qCDebug(PictureLoaderWorkerLog).nospace()
|
||||
<< "[card: " << cardName << " set: " << setName << "]: Trying to load picture";
|
||||
|
||||
if (CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting(
|
||||
cardName, cardBeingLoaded.getCard()->getPixmapCacheKey())) {
|
||||
if (cardImageExistsOnDisk(setName, correctedCardName)) {
|
||||
continue;
|
||||
}
|
||||
// FIXME: This is a hack so that to keep old Cockatrice behavior
|
||||
// (ignoring provider ID) when the "override all card art with personal
|
||||
// preference" is set.
|
||||
//
|
||||
// Figure out a proper way to integrate the two systems at some point.
|
||||
//
|
||||
// Note: need to go through a member for
|
||||
// overrideAllCardArtWithPersonalPreference as reading from the
|
||||
// SettingsCache instance from the PictureLoaderWorker thread could
|
||||
// cause race conditions.
|
||||
//
|
||||
// XXX: Reading from the CardDatabaseManager instance from the
|
||||
// PictureLoaderWorker thread might not be safe either
|
||||
bool searchCustomPics = overrideAllCardArtWithPersonalPreference ||
|
||||
CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting(
|
||||
cardName, cardBeingLoaded.getCard()->getPixmapCacheKey());
|
||||
if (searchCustomPics && cardImageExistsOnDisk(setName, correctedCardName, searchCustomPics)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
qCDebug(PictureLoaderWorkerLog).nospace()
|
||||
|
|
@ -100,23 +118,26 @@ void PictureLoaderWorker::processLoadQueue()
|
|||
}
|
||||
}
|
||||
|
||||
bool PictureLoaderWorker::cardImageExistsOnDisk(QString &setName, QString &correctedCardname)
|
||||
bool PictureLoaderWorker::cardImageExistsOnDisk(QString &setName, QString &correctedCardname, bool searchCustomPics)
|
||||
{
|
||||
QImage image;
|
||||
QImageReader imgReader;
|
||||
imgReader.setDecideFormatFromContent(true);
|
||||
QList<QString> picsPaths = QList<QString>();
|
||||
QDirIterator it(customPicsPath, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
||||
|
||||
// Recursively check all subdirectories of the CUSTOM folder
|
||||
while (it.hasNext()) {
|
||||
QString thisPath(it.next());
|
||||
QFileInfo thisFileInfo(thisPath);
|
||||
if (searchCustomPics) {
|
||||
QDirIterator it(customPicsPath, QDirIterator::Subdirectories | QDirIterator::FollowSymlinks);
|
||||
|
||||
if (thisFileInfo.isFile() &&
|
||||
(thisFileInfo.fileName() == correctedCardname || thisFileInfo.completeBaseName() == correctedCardname ||
|
||||
thisFileInfo.baseName() == correctedCardname)) {
|
||||
picsPaths << thisPath; // Card found in the CUSTOM directory, somewhere
|
||||
// Recursively check all subdirectories of the CUSTOM folder
|
||||
while (it.hasNext()) {
|
||||
QString thisPath(it.next());
|
||||
QFileInfo thisFileInfo(thisPath);
|
||||
|
||||
if (thisFileInfo.isFile() &&
|
||||
(thisFileInfo.fileName() == correctedCardname || thisFileInfo.completeBaseName() == correctedCardname ||
|
||||
thisFileInfo.baseName() == correctedCardname)) {
|
||||
picsPaths << thisPath; // Card found in the CUSTOM directory, somewhere
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -194,7 +215,7 @@ void PictureLoaderWorker::picDownloadFailed()
|
|||
loadQueue.prepend(cardBeingDownloaded);
|
||||
mutex.unlock();
|
||||
} else {
|
||||
qCDebug(PictureLoaderWorkerLog).nospace()
|
||||
qCWarning(PictureLoaderWorkerLog).nospace()
|
||||
<< "[card: " << cardBeingDownloaded.getCard()->getCorrectedName()
|
||||
<< " set: " << cardBeingDownloaded.getSetName() << "]: Picture NOT found, "
|
||||
<< (picDownload ? "download failed" : "downloads disabled")
|
||||
|
|
@ -225,6 +246,23 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url)
|
|||
|
||||
QNetworkRequest req(url);
|
||||
|
||||
// QNetworkDiskCache leaks file descriptors when downloading compressed
|
||||
// files, see https://bugreports.qt.io/browse/QTBUG-135641
|
||||
//
|
||||
// We can set the Accept-Encoding header manually to disable Qt's automatic
|
||||
// response decompression, but then we would have to deal with decompression
|
||||
// ourselves.
|
||||
//
|
||||
// Since we are dowloading images that are usually stored in a
|
||||
// compressed format (e.g. jpeg or webp), it's not clear compression at the
|
||||
// HTTP level helps; in fact, images are typically returned without
|
||||
// compression. Redirects, on the other hand, are compressed and cause file
|
||||
// descriptor leaks -- but since redirects have no payload, we don't really
|
||||
// care either.
|
||||
//
|
||||
// In the end, just do the simple thing and disable HTTP compression.
|
||||
req.setRawHeader("accept-encoding", "identity");
|
||||
|
||||
if (!picDownload) {
|
||||
req.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache);
|
||||
}
|
||||
|
|
@ -405,7 +443,7 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
|
|||
}
|
||||
|
||||
if (logSuccessMessage) {
|
||||
qCDebug(PictureLoaderWorkerLog).nospace()
|
||||
qCInfo(PictureLoaderWorkerLog).nospace()
|
||||
<< "[card: " << cardBeingDownloaded.getCard()->getName() << " set: " << cardBeingDownloaded.getSetName()
|
||||
<< "]: Image successfully " << (isFromCache ? "loaded from cached" : "downloaded from") << " url "
|
||||
<< reply->url().toDisplayString();
|
||||
|
|
@ -451,7 +489,12 @@ void PictureLoaderWorker::picsPathChanged()
|
|||
customPicsPath = SettingsCache::instance().getCustomPicsPath();
|
||||
}
|
||||
|
||||
void PictureLoaderWorker::setOverrideAllCardArtWithPersonalPreference(bool _overrideAllCardArtWithPersonalPreference)
|
||||
{
|
||||
overrideAllCardArtWithPersonalPreference = _overrideAllCardArtWithPersonalPreference;
|
||||
}
|
||||
|
||||
void PictureLoaderWorker::clearNetworkCache()
|
||||
{
|
||||
networkManager->cache()->clear();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PICTURE_LOADER_WORKER_H
|
||||
#define PICTURE_LOADER_WORKER_H
|
||||
|
||||
#include "../../../game/cards/card_database.h"
|
||||
#include "../../../game/cards/card_info.h"
|
||||
#include "picture_to_load.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
|
@ -42,8 +42,16 @@ private:
|
|||
PictureToLoad cardBeingLoaded;
|
||||
PictureToLoad cardBeingDownloaded;
|
||||
bool picDownload, downloadRunning, loadQueueRunning;
|
||||
bool overrideAllCardArtWithPersonalPreference;
|
||||
void startNextPicDownload();
|
||||
bool cardImageExistsOnDisk(QString &setName, QString &correctedCardName);
|
||||
|
||||
/** Emit the `imageLoaded` signal and return `true` if a picture is found on
|
||||
disk, return `false` otherwise.
|
||||
|
||||
If `searchCustomPics` is `true`, the CUSTOM folder is searched for a
|
||||
matching image first; otherwise, only the set-based folders are used. */
|
||||
bool cardImageExistsOnDisk(QString &setName, QString &correctedCardName, bool searchCustomPics);
|
||||
|
||||
bool imageIsBlackListed(const QByteArray &);
|
||||
QNetworkReply *makeRequest(const QUrl &url);
|
||||
void cacheRedirect(const QUrl &originalUrl, const QUrl &redirectUrl);
|
||||
|
|
@ -58,6 +66,7 @@ private slots:
|
|||
|
||||
void picDownloadChanged();
|
||||
void picsPathChanged();
|
||||
void setOverrideAllCardArtWithPersonalPreference(bool _overrideAllCardArtWithPersonalPreference);
|
||||
public slots:
|
||||
void processLoadQueue();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef PICTURE_TO_LOAD_H
|
||||
#define PICTURE_TO_LOAD_H
|
||||
|
||||
#include "../../../game/cards/card_database.h"
|
||||
#include "../../../game/cards/card_info.h"
|
||||
|
||||
#include <QLoggingCategory>
|
||||
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ static const QStringList DEFAULT_RESOURCE_PATHS = {":/resources"};
|
|||
ThemeManager::ThemeManager(QObject *parent) : QObject(parent)
|
||||
{
|
||||
ensureThemeDirectoryExists();
|
||||
connect(&SettingsCache::instance(), SIGNAL(themeChanged()), this, SLOT(themeChangedSlot()));
|
||||
connect(&SettingsCache::instance(), &SettingsCache::themeChanged, this, &ThemeManager::themeChangedSlot);
|
||||
themeChangedSlot();
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ void ThemeManager::ensureThemeDirectoryExists()
|
|||
{
|
||||
if (SettingsCache::instance().getThemeName().isEmpty() ||
|
||||
!getAvailableThemes().contains(SettingsCache::instance().getThemeName())) {
|
||||
qCDebug(ThemeManagerLog) << "Theme name not set, setting default value";
|
||||
qCInfo(ThemeManagerLog) << "Theme name not set, setting default value";
|
||||
SettingsCache::instance().setThemeName(NONE_THEME_NAME);
|
||||
}
|
||||
}
|
||||
|
|
@ -105,7 +105,7 @@ QBrush ThemeManager::loadExtraBrush(QString fileName, QBrush &fallbackBrush)
|
|||
void ThemeManager::themeChangedSlot()
|
||||
{
|
||||
QString themeName = SettingsCache::instance().getThemeName();
|
||||
qCDebug(ThemeManagerLog) << "Theme changed:" << themeName;
|
||||
qCInfo(ThemeManagerLog) << "Theme changed:" << themeName;
|
||||
|
||||
QString dirPath = getAvailableThemes().value(themeName);
|
||||
QDir dir = dirPath;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef COLOR_IDENTITY_WIDGET_H
|
||||
#define COLOR_IDENTITY_WIDGET_H
|
||||
|
||||
#include "../../../../../game/cards/card_database.h"
|
||||
#include "../../../../../game/cards/card_info.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QWidget>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef MANA_COST_WIDGET_H
|
||||
#define MANA_COST_WIDGET_H
|
||||
|
||||
#include "../../../../../game/cards/card_database.h"
|
||||
#include "../../../../../game/cards/card_info.h"
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QWidget>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
#include "card_group_display_widget.h"
|
||||
|
||||
#include "../../../../../deck/deck_list_model.h"
|
||||
#include "../../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../../../utility/card_info_comparator.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
CardGroupDisplayWidget::CardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *_deckListModel,
|
||||
QString _zoneName,
|
||||
QString _cardGroupCategory,
|
||||
QString _activeGroupCriteria,
|
||||
QStringList _activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
CardSizeWidget *_cardSizeWidget)
|
||||
: QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), cardGroupCategory(_cardGroupCategory),
|
||||
activeGroupCriteria(_activeGroupCriteria), activeSortCriteria(_activeSortCriteria),
|
||||
cardSizeWidget(_cardSizeWidget)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
setMinimumSize(QSize(0, 0));
|
||||
|
||||
banner = new BannerWidget(this, cardGroupCategory, Qt::Orientation::Vertical, bannerOpacity);
|
||||
|
||||
layout->addWidget(banner);
|
||||
updateCardDisplays();
|
||||
}
|
||||
|
||||
void CardGroupDisplayWidget::updateCardDisplays()
|
||||
{
|
||||
}
|
||||
|
||||
QList<CardInfoPtr> CardGroupDisplayWidget::getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort)
|
||||
{
|
||||
cardsToSort = sortCardList(cardsToSort, activeSortCriteria, Qt::SortOrder::AscendingOrder);
|
||||
|
||||
QList<CardInfoPtr> activeList;
|
||||
for (const CardInfoPtr &info : cardsToSort) {
|
||||
if (info && info->getProperty(activeGroupCriteria) == cardGroupCategory) {
|
||||
activeList.append(info);
|
||||
}
|
||||
}
|
||||
|
||||
return activeList;
|
||||
}
|
||||
|
||||
QList<CardInfoPtr> CardGroupDisplayWidget::sortCardList(QList<CardInfoPtr> cardsToSort,
|
||||
const QStringList properties,
|
||||
Qt::SortOrder order = Qt::AscendingOrder)
|
||||
{
|
||||
CardInfoComparator comparator(properties, order);
|
||||
std::sort(cardsToSort.begin(), cardsToSort.end(), comparator);
|
||||
|
||||
return cardsToSort;
|
||||
}
|
||||
|
||||
void CardGroupDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria)
|
||||
{
|
||||
if (activeSortCriteria != _activeSortCriteria) {
|
||||
activeSortCriteria = _activeSortCriteria;
|
||||
updateCardDisplays(); // Refresh display with new sorting
|
||||
}
|
||||
}
|
||||
|
||||
void CardGroupDisplayWidget::onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card)
|
||||
{
|
||||
emit cardClicked(event, card);
|
||||
}
|
||||
|
||||
void CardGroupDisplayWidget::onHover(CardInfoPtr card)
|
||||
{
|
||||
emit cardHovered(card);
|
||||
}
|
||||
|
||||
void CardGroupDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
#ifndef CARD_GROUP_DISPLAY_WIDGET_H
|
||||
#define CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../../../deck/deck_list_model.h"
|
||||
#include "../../../../../game/cards/card_info.h"
|
||||
#include "../../general/display/banner_widget.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
#include "../card_size_widget.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class CardGroupDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
CardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *deckListModel,
|
||||
QString zoneName,
|
||||
QString cardGroupCategory,
|
||||
QString activeGroupCriteria,
|
||||
QStringList activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
CardSizeWidget *cardSizeWidget);
|
||||
|
||||
QList<CardInfoPtr> getCardsMatchingGroup(QList<CardInfoPtr> cardsToSort);
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
DeckListModel *deckListModel;
|
||||
QString zoneName;
|
||||
QString cardGroupCategory;
|
||||
QString activeGroupCriteria;
|
||||
QStringList activeSortCriteria;
|
||||
CardSizeWidget *cardSizeWidget;
|
||||
|
||||
public slots:
|
||||
QList<CardInfoPtr> sortCardList(QList<CardInfoPtr> cardsToSort, QStringList properties, Qt::SortOrder order);
|
||||
void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||
void onHover(CardInfoPtr card);
|
||||
virtual void updateCardDisplays();
|
||||
void onActiveSortCriteriaChanged(QStringList activeSortCriteria);
|
||||
|
||||
signals:
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||
void cardHovered(CardInfoPtr card);
|
||||
|
||||
protected:
|
||||
QVBoxLayout *layout;
|
||||
BannerWidget *banner;
|
||||
};
|
||||
#endif // CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
#include "flat_card_group_display_widget.h"
|
||||
|
||||
#include "../../../../../deck/deck_list_model.h"
|
||||
#include "../../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../../../utility/card_info_comparator.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
FlatCardGroupDisplayWidget::FlatCardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *_deckListModel,
|
||||
QString _zoneName,
|
||||
QString _cardGroupCategory,
|
||||
QString _activeGroupCriteria,
|
||||
QStringList _activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
CardSizeWidget *_cardSizeWidget)
|
||||
: CardGroupDisplayWidget(parent,
|
||||
_deckListModel,
|
||||
_zoneName,
|
||||
_cardGroupCategory,
|
||||
_activeGroupCriteria,
|
||||
_activeSortCriteria,
|
||||
bannerOpacity,
|
||||
_cardSizeWidget)
|
||||
{
|
||||
flowWidget = new FlowWidget(this, Qt::Horizontal, Qt::ScrollBarAlwaysOff, Qt::ScrollBarAlwaysOff);
|
||||
banner->setBuddy(flowWidget);
|
||||
|
||||
layout->addWidget(flowWidget);
|
||||
FlatCardGroupDisplayWidget::updateCardDisplays();
|
||||
connect(deckListModel, &DeckListModel::dataChanged, this, &FlatCardGroupDisplayWidget::updateCardDisplays);
|
||||
}
|
||||
|
||||
void FlatCardGroupDisplayWidget::updateCardDisplays()
|
||||
{
|
||||
// Retrieve and sort cards
|
||||
QList<CardInfoPtr> cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName));
|
||||
|
||||
// Show or hide widget
|
||||
bool shouldBeVisible = !cardsInZone.isEmpty();
|
||||
if (shouldBeVisible != isVisible()) {
|
||||
setVisible(shouldBeVisible);
|
||||
}
|
||||
|
||||
// Retrieve existing widgets
|
||||
QList<CardInfoPictureWithTextOverlayWidget *> existingWidgets =
|
||||
flowWidget->findChildren<CardInfoPictureWithTextOverlayWidget *>();
|
||||
|
||||
QHash<QString, QList<CardInfoPictureWithTextOverlayWidget *>> widgetMap;
|
||||
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||
widgetMap[widget->getInfo()->getName()].append(widget);
|
||||
}
|
||||
|
||||
QList<CardInfoPictureWithTextOverlayWidget *> sortedWidgets;
|
||||
QSet<CardInfoPictureWithTextOverlayWidget *> usedWidgets;
|
||||
|
||||
// Ensure widgets are ordered to match the sorted cards
|
||||
for (const CardInfoPtr &card : cardsInZone) {
|
||||
QString name = card->getName();
|
||||
CardInfoPictureWithTextOverlayWidget *widget = nullptr;
|
||||
|
||||
if (!widgetMap[name].isEmpty()) {
|
||||
// Reuse an existing widget
|
||||
widget = widgetMap[name].takeFirst();
|
||||
} else {
|
||||
// Create a new widget if needed
|
||||
widget = new CardInfoPictureWithTextOverlayWidget(flowWidget, true);
|
||||
widget->setScaleFactor(cardSizeWidget->getSlider()->value());
|
||||
widget->setCard(card);
|
||||
|
||||
connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this,
|
||||
&FlatCardGroupDisplayWidget::onClick);
|
||||
connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this,
|
||||
&FlatCardGroupDisplayWidget::onHover);
|
||||
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget,
|
||||
&CardInfoPictureWidget::setScaleFactor);
|
||||
|
||||
flowWidget->addWidget(widget);
|
||||
}
|
||||
|
||||
// Store in sorted order
|
||||
sortedWidgets.append(widget);
|
||||
usedWidgets.insert(widget);
|
||||
}
|
||||
|
||||
// Remove extra widgets
|
||||
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||
if (!usedWidgets.contains(widget)) {
|
||||
flowWidget->layout()->removeWidget(widget);
|
||||
widget->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
// **Reorder widgets in place**
|
||||
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||
sortedWidgets[i]->setParent(nullptr); // Temporarily detach
|
||||
}
|
||||
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||
flowWidget->addWidget(sortedWidgets[i]); // Reattach in correct order
|
||||
}
|
||||
}
|
||||
|
||||
void FlatCardGroupDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef FLAT_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
#define FLAT_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../general/layout_containers/flow_widget.h"
|
||||
#include "card_group_display_widget.h"
|
||||
|
||||
class FlatCardGroupDisplayWidget : public CardGroupDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FlatCardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *deckListModel,
|
||||
QString zoneName,
|
||||
QString cardGroupCategory,
|
||||
QString activeGroupCriteria,
|
||||
QStringList activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
CardSizeWidget *cardSizeWidget);
|
||||
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void updateCardDisplays() override;
|
||||
|
||||
private:
|
||||
FlowWidget *flowWidget;
|
||||
};
|
||||
|
||||
#endif // FLAT_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
|
@ -0,0 +1,122 @@
|
|||
#include "overlapped_card_group_display_widget.h"
|
||||
|
||||
#include "../../../../../deck/deck_list_model.h"
|
||||
#include "../../../../../game/cards/card_database_manager.h"
|
||||
#include "../../../../../utility/card_info_comparator.h"
|
||||
#include "../card_info_picture_with_text_overlay_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
OverlappedCardGroupDisplayWidget::OverlappedCardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *_deckListModel,
|
||||
QString _zoneName,
|
||||
QString _cardGroupCategory,
|
||||
QString _activeGroupCriteria,
|
||||
QStringList _activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
CardSizeWidget *_cardSizeWidget)
|
||||
: CardGroupDisplayWidget(parent,
|
||||
_deckListModel,
|
||||
_zoneName,
|
||||
_cardGroupCategory,
|
||||
_activeGroupCriteria,
|
||||
_activeSortCriteria,
|
||||
bannerOpacity,
|
||||
_cardSizeWidget)
|
||||
{
|
||||
overlapWidget = new OverlapWidget(this, 80, 1, 1, Qt::Vertical, true);
|
||||
banner->setBuddy(overlapWidget);
|
||||
|
||||
layout->addWidget(overlapWidget);
|
||||
OverlappedCardGroupDisplayWidget::updateCardDisplays();
|
||||
connect(deckListModel, &DeckListModel::dataChanged, this, &OverlappedCardGroupDisplayWidget::updateCardDisplays);
|
||||
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, this,
|
||||
[this]() { overlapWidget->adjustMaxColumnsAndRows(); });
|
||||
}
|
||||
|
||||
void OverlappedCardGroupDisplayWidget::updateCardDisplays()
|
||||
{
|
||||
overlapWidget->setUpdatesEnabled(false);
|
||||
// Retrieve and sort cards
|
||||
QList<CardInfoPtr> cardsInZone = getCardsMatchingGroup(deckListModel->getCardsAsCardInfoPtrsForZone(zoneName));
|
||||
|
||||
// Show or hide widget
|
||||
bool shouldBeVisible = !cardsInZone.isEmpty();
|
||||
if (shouldBeVisible != isVisible()) {
|
||||
setVisible(shouldBeVisible);
|
||||
}
|
||||
|
||||
// Retrieve existing widgets
|
||||
QList<CardInfoPictureWithTextOverlayWidget *> existingWidgets =
|
||||
overlapWidget->findChildren<CardInfoPictureWithTextOverlayWidget *>();
|
||||
|
||||
QHash<QString, QList<CardInfoPictureWithTextOverlayWidget *>> widgetMap;
|
||||
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||
widgetMap[widget->getInfo()->getName()].append(widget);
|
||||
}
|
||||
|
||||
QList<CardInfoPictureWithTextOverlayWidget *> sortedWidgets;
|
||||
QSet<CardInfoPictureWithTextOverlayWidget *> usedWidgets;
|
||||
|
||||
// Ensure widgets are ordered to match the sorted cards
|
||||
for (const CardInfoPtr &card : cardsInZone) {
|
||||
QString name = card->getName();
|
||||
CardInfoPictureWithTextOverlayWidget *widget = nullptr;
|
||||
|
||||
if (!widgetMap[name].isEmpty()) {
|
||||
// Reuse an existing widget
|
||||
widget = widgetMap[name].takeFirst();
|
||||
} else {
|
||||
// Create a new widget if needed
|
||||
widget = new CardInfoPictureWithTextOverlayWidget(overlapWidget, true);
|
||||
widget->setScaleFactor(cardSizeWidget->getSlider()->value());
|
||||
widget->setCard(card);
|
||||
|
||||
connect(widget, &CardInfoPictureWithTextOverlayWidget::imageClicked, this,
|
||||
&OverlappedCardGroupDisplayWidget::onClick);
|
||||
connect(widget, &CardInfoPictureWithTextOverlayWidget::hoveredOnCard, this,
|
||||
&OverlappedCardGroupDisplayWidget::onHover);
|
||||
connect(cardSizeWidget->getSlider(), &QSlider::valueChanged, widget,
|
||||
&CardInfoPictureWidget::setScaleFactor);
|
||||
|
||||
overlapWidget->addWidget(widget);
|
||||
}
|
||||
|
||||
// Store in sorted order
|
||||
sortedWidgets.append(widget);
|
||||
usedWidgets.insert(widget);
|
||||
}
|
||||
|
||||
// Remove extra widgets
|
||||
for (CardInfoPictureWithTextOverlayWidget *widget : existingWidgets) {
|
||||
if (!usedWidgets.contains(widget)) {
|
||||
overlapWidget->layout()->removeWidget(widget);
|
||||
delete widget;
|
||||
}
|
||||
}
|
||||
|
||||
// **Reorder widgets in place**
|
||||
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||
sortedWidgets[i]->setParent(nullptr); // Temporarily detach
|
||||
}
|
||||
for (int i = 0; i < sortedWidgets.size(); ++i) {
|
||||
overlapWidget->addWidget(sortedWidgets[i]); // Reattach in correct order
|
||||
}
|
||||
|
||||
// Ensure proper layering
|
||||
for (CardInfoPictureWithTextOverlayWidget *widget : sortedWidgets) {
|
||||
widget->raise();
|
||||
}
|
||||
|
||||
overlapWidget->adjustMaxColumnsAndRows();
|
||||
overlapWidget->setUpdatesEnabled(true);
|
||||
overlapWidget->update();
|
||||
}
|
||||
|
||||
void OverlappedCardGroupDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
|
||||
overlapWidget->resize(event->size());
|
||||
overlapWidget->adjustMaxColumnsAndRows();
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
#ifndef OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
#define OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../general/layout_containers/overlap_widget.h"
|
||||
#include "card_group_display_widget.h"
|
||||
|
||||
class OverlappedCardGroupDisplayWidget : public CardGroupDisplayWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
OverlappedCardGroupDisplayWidget(QWidget *parent,
|
||||
DeckListModel *deckListModel,
|
||||
QString zoneName,
|
||||
QString cardGroupCategory,
|
||||
QString activeGroupCriteria,
|
||||
QStringList activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
CardSizeWidget *cardSizeWidget);
|
||||
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void updateCardDisplays() override;
|
||||
|
||||
private:
|
||||
OverlapWidget *overlapWidget;
|
||||
};
|
||||
|
||||
#endif // OVERLAPPED_CARD_GROUP_DISPLAY_WIDGET_H
|
||||
|
|
@ -22,7 +22,7 @@ CardInfoDisplayWidget::CardInfoDisplayWidget(const QString &cardName,
|
|||
pic->setObjectName("pic");
|
||||
text = new CardInfoTextWidget();
|
||||
text->setObjectName("text");
|
||||
connect(text, SIGNAL(linkActivated(const QString &)), this, SLOT(setCard(const QString &)));
|
||||
connect(text, &CardInfoTextWidget::linkActivated, this, [this](const QString &card) { setCard(card); });
|
||||
|
||||
auto *layout = new QVBoxLayout();
|
||||
layout->setObjectName("layout");
|
||||
|
|
@ -52,7 +52,7 @@ void CardInfoDisplayWidget::setCard(CardInfoPtr card)
|
|||
disconnect(info.data(), nullptr, this, nullptr);
|
||||
info = std::move(card);
|
||||
if (info)
|
||||
connect(info.data(), SIGNAL(destroyed()), this, SLOT(clear()));
|
||||
connect(info.data(), &QObject::destroyed, this, &CardInfoDisplayWidget::clear);
|
||||
|
||||
text->setCard(info);
|
||||
pic->setCard(info);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef CARDINFOWIDGET_H
|
||||
#define CARDINFOWIDGET_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../../game/cards/card_info.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QFrame>
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ CardInfoFrameWidget::CardInfoFrameWidget(const QString &cardName, QWidget *paren
|
|||
|
||||
text = new CardInfoTextWidget();
|
||||
text->setObjectName("text");
|
||||
connect(text, SIGNAL(linkActivated(const QString &)), this, SLOT(setCard(const QString &)));
|
||||
connect(text, &CardInfoTextWidget::linkActivated, this, qOverload<const QString &>(&CardInfoFrameWidget::setCard));
|
||||
|
||||
tab1 = new QWidget(this);
|
||||
tab2 = new QWidget(this);
|
||||
|
|
@ -34,7 +34,7 @@ CardInfoFrameWidget::CardInfoFrameWidget(const QString &cardName, QWidget *paren
|
|||
insertTab(ImageOnlyView, tab1, QString());
|
||||
insertTab(TextOnlyView, tab2, QString());
|
||||
insertTab(ImageAndTextView, tab3, QString());
|
||||
connect(this, SIGNAL(currentChanged(int)), this, SLOT(setViewMode(int)));
|
||||
connect(this, &CardInfoFrameWidget::currentChanged, this, &CardInfoFrameWidget::setViewMode);
|
||||
|
||||
tab1Layout = new QVBoxLayout();
|
||||
tab1Layout->setObjectName("tab1Layout");
|
||||
|
|
@ -61,6 +61,7 @@ CardInfoFrameWidget::CardInfoFrameWidget(const QString &cardName, QWidget *paren
|
|||
|
||||
setViewMode(SettingsCache::instance().getCardInfoViewMode());
|
||||
|
||||
// TODO: Change this to be by UUID
|
||||
setCard(CardDatabaseManager::getInstance()->getCard(cardName));
|
||||
}
|
||||
|
||||
|
|
@ -154,7 +155,7 @@ void CardInfoFrameWidget::setCard(CardInfoPtr card)
|
|||
info = std::move(card);
|
||||
|
||||
if (info) {
|
||||
connect(info.data(), SIGNAL(destroyed()), this, SLOT(clearCard()));
|
||||
connect(info.data(), &QObject::destroyed, this, &CardInfoFrameWidget::clearCard);
|
||||
}
|
||||
|
||||
setViewTransformationButtonVisibility(hasTransformation(info));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef CARDFRAME_H
|
||||
#define CARDFRAME_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../../game/cards/card_info.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QTabWidget>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef CARD_PICTURE_ENLARGED_WIDGET_H
|
||||
#define CARD_PICTURE_ENLARGED_WIDGET_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../../game/cards/card_info.h"
|
||||
|
||||
#include <QPixmap>
|
||||
#include <QWidget>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include <QMenu>
|
||||
#include <QMouseEvent>
|
||||
#include <QScreen>
|
||||
#include <QStylePainter>
|
||||
#include <QWidget>
|
||||
#include <utility>
|
||||
|
|
@ -37,7 +38,7 @@ CardInfoPictureWidget::CardInfoPictureWidget(QWidget *parent, const bool hoverTo
|
|||
setMouseTracking(true);
|
||||
}
|
||||
|
||||
enlargedPixmapWidget = new CardInfoPictureEnlargedWidget(this);
|
||||
enlargedPixmapWidget = new CardInfoPictureEnlargedWidget(this->window());
|
||||
enlargedPixmapWidget->hide();
|
||||
|
||||
hoverTimer = new QTimer(this);
|
||||
|
|
@ -67,7 +68,7 @@ void CardInfoPictureWidget::setCard(CardInfoPtr card)
|
|||
info = std::move(card);
|
||||
|
||||
if (info) {
|
||||
connect(info.data(), SIGNAL(pixmapUpdated()), this, SLOT(updatePixmap()));
|
||||
connect(info.data(), &CardInfo::pixmapUpdated, this, &CardInfoPictureWidget::updatePixmap);
|
||||
}
|
||||
|
||||
updatePixmap();
|
||||
|
|
@ -210,7 +211,8 @@ void CardInfoPictureWidget::paintEvent(QPaintEvent *event)
|
|||
*/
|
||||
QSize CardInfoPictureWidget::sizeHint() const
|
||||
{
|
||||
return {static_cast<int>(baseWidth * scaleFactor), static_cast<int>(baseHeight * scaleFactor)};
|
||||
return {static_cast<int>(baseWidth * scaleFactor / 100.0),
|
||||
static_cast<int>(baseWidth * scaleFactor / 100.0 * aspectRatio)};
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -254,10 +256,24 @@ void CardInfoPictureWidget::leaveEvent(QEvent *event)
|
|||
void CardInfoPictureWidget::mouseMoveEvent(QMouseEvent *event)
|
||||
{
|
||||
QWidget::mouseMoveEvent(event);
|
||||
|
||||
if (hoverToZoomEnabled && enlargedPixmapWidget->isVisible()) {
|
||||
const QPointF cursorPos = QCursor::pos();
|
||||
enlargedPixmapWidget->move(QPoint(static_cast<int>(cursorPos.x()) + enlargedPixmapOffset,
|
||||
static_cast<int>(cursorPos.y()) + enlargedPixmapOffset));
|
||||
const QPoint cursorPos = QCursor::pos();
|
||||
const QRect screenGeometry = QGuiApplication::screenAt(cursorPos)->geometry();
|
||||
const QSize widgetSize = enlargedPixmapWidget->size();
|
||||
|
||||
int newX = cursorPos.x() + enlargedPixmapOffset;
|
||||
int newY = cursorPos.y() + enlargedPixmapOffset;
|
||||
|
||||
// Adjust if out of bounds
|
||||
if (newX + widgetSize.width() > screenGeometry.right()) {
|
||||
newX = cursorPos.x() - widgetSize.width() - enlargedPixmapOffset;
|
||||
}
|
||||
if (newY + widgetSize.height() > screenGeometry.bottom()) {
|
||||
newY = cursorPos.y() - widgetSize.height() - enlargedPixmapOffset;
|
||||
}
|
||||
|
||||
enlargedPixmapWidget->move(newX, newY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -267,6 +283,8 @@ void CardInfoPictureWidget::mousePressEvent(QMouseEvent *event)
|
|||
if (event->button() == Qt::RightButton) {
|
||||
createRightClickMenu()->popup(QCursor::pos());
|
||||
}
|
||||
|
||||
emit cardClicked();
|
||||
}
|
||||
|
||||
QMenu *CardInfoPictureWidget::createRightClickMenu()
|
||||
|
|
@ -312,11 +330,26 @@ QMenu *CardInfoPictureWidget::createViewRelatedCardsMenu()
|
|||
return viewRelatedCards;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the single instance of the MainWindow in this application.
|
||||
*/
|
||||
static MainWindow *findMainWindow()
|
||||
{
|
||||
for (auto widget : QApplication::topLevelWidgets()) {
|
||||
if (auto mainWindow = qobject_cast<MainWindow *>(widget)) {
|
||||
return mainWindow;
|
||||
}
|
||||
}
|
||||
// This code should be unreachable
|
||||
qCritical() << "Could not find MainWindow in QApplication::topLevelWidgets";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QMenu *CardInfoPictureWidget::createAddToOpenDeckMenu()
|
||||
{
|
||||
auto addToOpenDeckMenu = new QMenu(tr("Add card to deck"));
|
||||
|
||||
auto *mainWindow = qobject_cast<MainWindow *>(window());
|
||||
auto mainWindow = findMainWindow();
|
||||
QList<AbstractTabDeckEditor *> deckEditorTabs = mainWindow->getTabSupervisor()->getDeckEditorTabs();
|
||||
|
||||
if (deckEditorTabs.isEmpty()) {
|
||||
|
|
@ -355,13 +388,25 @@ void CardInfoPictureWidget::showEnlargedPixmap() const
|
|||
return;
|
||||
}
|
||||
|
||||
const QSize enlargedSize(static_cast<int>(size().width() * scaleFactor),
|
||||
static_cast<int>(size().width() * aspectRatio * scaleFactor));
|
||||
const QSize enlargedSize(static_cast<int>(size().width() * 2), static_cast<int>(size().width() * aspectRatio * 2));
|
||||
enlargedPixmapWidget->setCardPixmap(info, enlargedSize);
|
||||
|
||||
const QPointF cursorPos = QCursor::pos();
|
||||
enlargedPixmapWidget->move(static_cast<int>(cursorPos.x()) + enlargedPixmapOffset,
|
||||
static_cast<int>(cursorPos.y()) + enlargedPixmapOffset);
|
||||
const QPoint cursorPos = QCursor::pos();
|
||||
const QRect screenGeometry = QGuiApplication::screenAt(cursorPos)->geometry();
|
||||
const QSize widgetSize = enlargedPixmapWidget->size();
|
||||
|
||||
int newX = cursorPos.x() + enlargedPixmapOffset;
|
||||
int newY = cursorPos.y() + enlargedPixmapOffset;
|
||||
|
||||
// Adjust if out of bounds
|
||||
if (newX + widgetSize.width() > screenGeometry.right()) {
|
||||
newX = cursorPos.x() - widgetSize.width() - enlargedPixmapOffset;
|
||||
}
|
||||
if (newY + widgetSize.height() > screenGeometry.bottom()) {
|
||||
newY = cursorPos.y() - widgetSize.height() - enlargedPixmapOffset;
|
||||
}
|
||||
|
||||
enlargedPixmapWidget->move(newX, newY);
|
||||
|
||||
enlargedPixmapWidget->show();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,14 @@
|
|||
#ifndef CARD_INFO_PICTURE_H
|
||||
#define CARD_INFO_PICTURE_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../../game/cards/card_info.h"
|
||||
#include "card_info_picture_enlarged_widget.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
inline Q_LOGGING_CATEGORY(CardInfoPictureWidgetLog, "card_info_picture_widget");
|
||||
|
||||
class AbstractCardItem;
|
||||
class QMenu;
|
||||
|
||||
|
|
@ -32,6 +34,7 @@ signals:
|
|||
void hoveredOnCard(CardInfoPtr hoveredCard);
|
||||
void cardScaleFactorChanged(int _scale);
|
||||
void cardChanged(CardInfoPtr card);
|
||||
void cardClicked();
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
|
@ -58,7 +61,7 @@ private:
|
|||
qreal aspectRatio = magicTheGatheringCardAspectRatio;
|
||||
int baseWidth = 200;
|
||||
int baseHeight = 200;
|
||||
double scaleFactor = 1.5;
|
||||
double scaleFactor = 100;
|
||||
QPixmap resizedPixmap;
|
||||
bool pixmapDirty;
|
||||
bool hoverToZoomEnabled;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef CARDINFOTEXT_H
|
||||
#define CARDINFOTEXT_H
|
||||
|
||||
#include "../../../../game/cards/card_database.h"
|
||||
#include "../../../../game/cards/card_info.h"
|
||||
|
||||
#include <QFrame>
|
||||
class QLabel;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,168 @@
|
|||
#include "deck_card_zone_display_widget.h"
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../../utility/card_info_comparator.h"
|
||||
#include "card_group_display_widgets/flat_card_group_display_widget.h"
|
||||
#include "card_group_display_widgets/overlapped_card_group_display_widget.h"
|
||||
|
||||
#include <QResizeEvent>
|
||||
|
||||
DeckCardZoneDisplayWidget::DeckCardZoneDisplayWidget(QWidget *parent,
|
||||
DeckListModel *_deckListModel,
|
||||
QString _zoneName,
|
||||
QString _activeGroupCriteria,
|
||||
QStringList _activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
int subBannerOpacity,
|
||||
CardSizeWidget *_cardSizeWidget)
|
||||
: QWidget(parent), deckListModel(_deckListModel), zoneName(_zoneName), activeGroupCriteria(_activeGroupCriteria),
|
||||
activeSortCriteria(_activeSortCriteria), bannerOpacity(bannerOpacity), subBannerOpacity(subBannerOpacity),
|
||||
cardSizeWidget(_cardSizeWidget)
|
||||
{
|
||||
layout = new QVBoxLayout(this);
|
||||
setLayout(layout);
|
||||
|
||||
banner = new BannerWidget(this, zoneName, Qt::Orientation::Vertical, bannerOpacity);
|
||||
layout->addWidget(banner);
|
||||
|
||||
cardGroupContainer = new QWidget(this);
|
||||
cardGroupLayout = new QVBoxLayout(cardGroupContainer);
|
||||
cardGroupContainer->setLayout(cardGroupLayout);
|
||||
layout->addWidget(cardGroupContainer);
|
||||
|
||||
banner->setBuddy(cardGroupContainer);
|
||||
|
||||
displayCards();
|
||||
connect(deckListModel, &DeckListModel::dataChanged, this, &DeckCardZoneDisplayWidget::displayCards);
|
||||
}
|
||||
void DeckCardZoneDisplayWidget::resizeEvent(QResizeEvent *event)
|
||||
{
|
||||
QWidget::resizeEvent(event);
|
||||
for (QObject *child : layout->children()) {
|
||||
QWidget *widget = qobject_cast<QWidget *>(child);
|
||||
if (widget) {
|
||||
widget->setMaximumWidth(width());
|
||||
}
|
||||
}
|
||||
}
|
||||
void DeckCardZoneDisplayWidget::onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card)
|
||||
{
|
||||
emit cardClicked(event, card, zoneName);
|
||||
}
|
||||
void DeckCardZoneDisplayWidget::onHover(CardInfoPtr card)
|
||||
{
|
||||
emit cardHovered(card);
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::displayCards()
|
||||
{
|
||||
addCardGroupIfItDoesNotExist();
|
||||
deleteCardGroupIfItDoesNotExist();
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::refreshDisplayType(const QString &_displayType)
|
||||
{
|
||||
displayType = _displayType;
|
||||
QLayoutItem *item;
|
||||
while ((item = cardGroupLayout->takeAt(0)) != nullptr) {
|
||||
if (item->widget()) {
|
||||
item->widget()->deleteLater();
|
||||
} else if (item->layout()) {
|
||||
delete item->layout();
|
||||
}
|
||||
delete item;
|
||||
}
|
||||
|
||||
// We gotta wait for all the deleteLater's to finish so we fire after the next event cycle
|
||||
|
||||
auto timer = new QTimer(this);
|
||||
timer->setSingleShot(true);
|
||||
connect(timer, &QTimer::timeout, this, [this]() { displayCards(); });
|
||||
timer->start();
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::addCardGroupIfItDoesNotExist()
|
||||
{
|
||||
QList<CardGroupDisplayWidget *> cardGroupsDisplayWidgets =
|
||||
cardGroupContainer->findChildren<CardGroupDisplayWidget *>();
|
||||
|
||||
QList<QString> cardGroups = getGroupCriteriaValueList();
|
||||
|
||||
for (QString cardGroup : cardGroups) {
|
||||
bool found = false;
|
||||
for (CardGroupDisplayWidget *cardGroupDisplayWidget : cardGroupsDisplayWidgets) {
|
||||
if (cardGroupDisplayWidget->cardGroupCategory == cardGroup) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (displayType == "overlap") {
|
||||
auto *display_widget = new OverlappedCardGroupDisplayWidget(
|
||||
cardGroupContainer, deckListModel, zoneName, cardGroup, activeGroupCriteria, activeSortCriteria,
|
||||
subBannerOpacity, cardSizeWidget);
|
||||
connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr)));
|
||||
connect(this, &DeckCardZoneDisplayWidget::activeSortCriteriaChanged, display_widget,
|
||||
&CardGroupDisplayWidget::onActiveSortCriteriaChanged);
|
||||
cardGroupLayout->addWidget(display_widget);
|
||||
} else if (displayType == "flat") {
|
||||
auto *display_widget = new FlatCardGroupDisplayWidget(cardGroupContainer, deckListModel, zoneName,
|
||||
cardGroup, activeGroupCriteria, activeSortCriteria,
|
||||
subBannerOpacity, cardSizeWidget);
|
||||
connect(display_widget, SIGNAL(cardClicked(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)), this,
|
||||
SLOT(onClick(QMouseEvent *, CardInfoPictureWithTextOverlayWidget *)));
|
||||
connect(display_widget, SIGNAL(cardHovered(CardInfoPtr)), this, SLOT(onHover(CardInfoPtr)));
|
||||
connect(this, &DeckCardZoneDisplayWidget::activeSortCriteriaChanged, display_widget,
|
||||
&CardGroupDisplayWidget::onActiveSortCriteriaChanged);
|
||||
cardGroupLayout->addWidget(display_widget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::deleteCardGroupIfItDoesNotExist()
|
||||
{
|
||||
QList<CardGroupDisplayWidget *> cardGroupsDisplayWidgets =
|
||||
cardGroupContainer->findChildren<CardGroupDisplayWidget *>();
|
||||
|
||||
QList<QString> validGroups = getGroupCriteriaValueList();
|
||||
|
||||
for (CardGroupDisplayWidget *cardGroupDisplayWidget : cardGroupsDisplayWidgets) {
|
||||
if (!validGroups.contains(cardGroupDisplayWidget->cardGroupCategory)) {
|
||||
cardGroupLayout->removeWidget(cardGroupDisplayWidget);
|
||||
cardGroupDisplayWidget->deleteLater(); // Properly delete the widget after the event loop cycles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::onActiveGroupCriteriaChanged(QString _activeGroupCriteria)
|
||||
{
|
||||
activeGroupCriteria = _activeGroupCriteria;
|
||||
displayCards();
|
||||
}
|
||||
|
||||
void DeckCardZoneDisplayWidget::onActiveSortCriteriaChanged(QStringList _activeSortCriteria)
|
||||
{
|
||||
activeSortCriteria = _activeSortCriteria;
|
||||
emit activeSortCriteriaChanged(activeSortCriteria);
|
||||
}
|
||||
|
||||
QList<QString> DeckCardZoneDisplayWidget::getGroupCriteriaValueList()
|
||||
{
|
||||
QList<QString> groupCriteriaValues;
|
||||
|
||||
QList<CardInfoPtr> cardsInZone = deckListModel->getCardsAsCardInfoPtrsForZone(zoneName);
|
||||
|
||||
for (CardInfoPtr cardInZone : cardsInZone) {
|
||||
groupCriteriaValues.append(cardInZone->getProperty(activeGroupCriteria));
|
||||
}
|
||||
|
||||
groupCriteriaValues.removeDuplicates();
|
||||
groupCriteriaValues.sort();
|
||||
|
||||
return groupCriteriaValues;
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
#ifndef DECK_CARD_ZONE_DISPLAY_WIDGET_H
|
||||
#define DECK_CARD_ZONE_DISPLAY_WIDGET_H
|
||||
|
||||
#include "../../../../deck/deck_list_model.h"
|
||||
#include "../../../../game/cards/card_info.h"
|
||||
#include "../general/display/banner_widget.h"
|
||||
#include "../general/layout_containers/overlap_widget.h"
|
||||
#include "card_info_picture_with_text_overlay_widget.h"
|
||||
#include "card_size_widget.h"
|
||||
|
||||
#include <QVBoxLayout>
|
||||
#include <QWidget>
|
||||
|
||||
class DeckCardZoneDisplayWidget : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DeckCardZoneDisplayWidget(QWidget *parent,
|
||||
DeckListModel *deckListModel,
|
||||
QString zoneName,
|
||||
QString activeGroupCriteria,
|
||||
QStringList activeSortCriteria,
|
||||
int bannerOpacity,
|
||||
int subBannerOpacity,
|
||||
CardSizeWidget *_cardSizeWidget);
|
||||
DeckListModel *deckListModel;
|
||||
QString zoneName;
|
||||
void addCardsToOverlapWidget();
|
||||
void resizeEvent(QResizeEvent *event) override;
|
||||
|
||||
public slots:
|
||||
void onClick(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card);
|
||||
void onHover(CardInfoPtr card);
|
||||
void displayCards();
|
||||
void refreshDisplayType(const QString &displayType);
|
||||
void addCardGroupIfItDoesNotExist();
|
||||
void deleteCardGroupIfItDoesNotExist();
|
||||
void onActiveGroupCriteriaChanged(QString activeGroupCriteria);
|
||||
void onActiveSortCriteriaChanged(QStringList activeSortCriteria);
|
||||
QList<QString> getGroupCriteriaValueList();
|
||||
|
||||
signals:
|
||||
void cardClicked(QMouseEvent *event, CardInfoPictureWithTextOverlayWidget *card, QString zoneName);
|
||||
void cardHovered(CardInfoPtr card);
|
||||
void activeSortCriteriaChanged(QStringList activeSortCriteria);
|
||||
|
||||
private:
|
||||
QString activeGroupCriteria;
|
||||
QStringList activeSortCriteria;
|
||||
int bannerOpacity = 20;
|
||||
int subBannerOpacity = 10;
|
||||
CardSizeWidget *cardSizeWidget;
|
||||
QVBoxLayout *layout;
|
||||
BannerWidget *banner;
|
||||
QWidget *cardGroupContainer;
|
||||
QVBoxLayout *cardGroupLayout;
|
||||
QString displayType = "flat";
|
||||
OverlapWidget *overlapWidget;
|
||||
};
|
||||
|
||||
#endif // DECK_CARD_ZONE_DISPLAY_WIDGET_H
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue