Merge branch 'master' into new_visual_deck_storage

This commit is contained in:
Zach H 2025-01-05 17:56:22 -05:00 committed by GitHub
commit a659ec0bc1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 205 additions and 74 deletions

1
.gitignore vendored
View file

@ -13,3 +13,4 @@ compile_commands.json
.vscode/ .vscode/
.cache .cache
.gdb_history .gdb_history
cockatrice/resources/config/qtlogging.ini

View file

@ -56,6 +56,7 @@ set(cockatrice_SOURCES
src/dialogs/dlg_tip_of_the_day.cpp src/dialogs/dlg_tip_of_the_day.cpp
src/dialogs/dlg_update.cpp src/dialogs/dlg_update.cpp
src/dialogs/dlg_view_log.cpp src/dialogs/dlg_view_log.cpp
src/dialogs/dlg_load_deck.cpp
src/game/filters/filter_string.cpp src/game/filters/filter_string.cpp
src/game/filters/filter_builder.cpp src/game/filters/filter_builder.cpp
src/game/filters/filter_tree.cpp src/game/filters/filter_tree.cpp
@ -168,6 +169,9 @@ set(cockatrice_SOURCES
add_subdirectory(sounds) add_subdirectory(sounds)
add_subdirectory(themes) add_subdirectory(themes)
configure_file(
${CMAKE_SOURCE_DIR}/cockatrice/resources/config/qtlogging.ini ${CMAKE_BINARY_DIR}/cockatrice/qtlogging.ini COPYONLY
)
set(cockatrice_RESOURCES cockatrice.qrc) set(cockatrice_RESOURCES cockatrice.qrc)

View file

@ -41,6 +41,8 @@
<file>resources/config/deckeditor.svg</file> <file>resources/config/deckeditor.svg</file>
<file>resources/config/shorcuts.svg</file> <file>resources/config/shorcuts.svg</file>
<file>resources/config/sound.svg</file> <file>resources/config/sound.svg</file>
<file>resources/config/debug.ini</file>
<file>resources/config/qtlogging.ini</file>
<file>resources/counters/w.svg</file> <file>resources/counters/w.svg</file>
<file>resources/counters/w_highlight.svg</file> <file>resources/counters/w_highlight.svg</file>

View file

@ -0,0 +1,11 @@
[debug]
showCardId=false
[localgame]
onStartup=false
playerCount=1
;deck\Player 1=path/to/deck
;deck\Player 2=path/to/deck
; Fun Fact: You can assign a deck to your username and it will auto load and ready when you join a server game
;deck\Your Username Here=path/to/deck

View file

@ -0,0 +1,2 @@
[Rules]
picture_loader.debug = true

View file

@ -5,6 +5,7 @@
#include "../../client/ui/widgets/cards/card_info_frame_widget.h" #include "../../client/ui/widgets/cards/card_info_frame_widget.h"
#include "../../deck/deck_list_model.h" #include "../../deck/deck_list_model.h"
#include "../../deck/deck_stats_interface.h" #include "../../deck/deck_stats_interface.h"
#include "../../dialogs/dlg_load_deck.h"
#include "../../dialogs/dlg_load_deck_from_clipboard.h" #include "../../dialogs/dlg_load_deck_from_clipboard.h"
#include "../../game/cards/card_database_manager.h" #include "../../game/cards/card_database_manager.h"
#include "../../game/cards/card_database_model.h" #include "../../game/cards/card_database_model.h"
@ -1007,9 +1008,7 @@ void TabDeckEditor::actLoadDeck()
return; return;
} }
QFileDialog dialog(this, tr("Load deck")); DlgLoadDeck dialog(this);
dialog.setDirectory(SettingsCache::instance().getDeckPath());
dialog.setNameFilters(DeckLoader::fileNameFilters);
if (!dialog.exec()) if (!dialog.exec())
return; return;

View file

@ -4,6 +4,7 @@
#include "../../deck/deck_loader.h" #include "../../deck/deck_loader.h"
#include "../../deck/deck_view.h" #include "../../deck/deck_view.h"
#include "../../dialogs/dlg_create_game.h" #include "../../dialogs/dlg_create_game.h"
#include "../../dialogs/dlg_load_deck.h"
#include "../../dialogs/dlg_load_remote_deck.h" #include "../../dialogs/dlg_load_remote_deck.h"
#include "../../dialogs/dlg_manage_sets.h" #include "../../dialogs/dlg_manage_sets.h"
#include "../../game/board/arrow_item.h" #include "../../game/board/arrow_item.h"
@ -338,9 +339,7 @@ void DeckViewContainer::unloadDeck()
void DeckViewContainer::loadLocalDeck() void DeckViewContainer::loadLocalDeck()
{ {
QFileDialog dialog(this, tr("Load deck")); DlgLoadDeck dialog(this);
dialog.setDirectory(SettingsCache::instance().getDeckPath());
dialog.setNameFilters(DeckLoader::fileNameFilters);
if (!dialog.exec()) if (!dialog.exec())
return; return;
@ -815,6 +814,12 @@ void TabGame::actSay()
if (completer->popup()->isVisible()) if (completer->popup()->isVisible())
return; return;
if (sayEdit->text().startsWith("/card ")) {
cardInfoFrameWidget->setCard(sayEdit->text().mid(6));
sayEdit->clear();
return;
}
if (!sayEdit->text().isEmpty()) { if (!sayEdit->text().isEmpty()) {
Command_GameSay cmd; Command_GameSay cmd;
cmd.set_message(sayEdit->text().toStdString()); cmd.set_message(sayEdit->text().toStdString());

View file

@ -23,8 +23,11 @@
#include <QThread> #include <QThread>
#include <QUrl> #include <QUrl>
#include <algorithm> #include <algorithm>
#include <qloggingcategory.h>
#include <utility> #include <utility>
Q_LOGGING_CATEGORY(PictureLoaderLog, "picture_loader")
// never cache more than 300 cards at once for a single deck // never cache more than 300 cards at once for a single deck
#define CACHED_CARD_PER_DECK_MAX 300 #define CACHED_CARD_PER_DECK_MAX 300
@ -189,8 +192,8 @@ void PictureLoaderWorker::processLoadQueue()
QString cardName = cardBeingLoaded.getCard()->getName(); QString cardName = cardBeingLoaded.getCard()->getName();
QString correctedCardName = cardBeingLoaded.getCard()->getCorrectedName(); QString correctedCardName = cardBeingLoaded.getCard()->getCorrectedName();
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName qCDebug(PictureLoaderLog).nospace()
<< "]: Trying to load picture"; << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Trying to load picture";
if (CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting( if (CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting(
cardName, cardBeingLoaded.getCard()->getPixmapCacheKey())) { cardName, cardBeingLoaded.getCard()->getPixmapCacheKey())) {
@ -199,7 +202,7 @@ void PictureLoaderWorker::processLoadQueue()
} }
} }
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << cardName << " set: " << setName
<< "]: No custom picture, trying to download"; << "]: No custom picture, trying to download";
cardsToDownload.append(cardBeingLoaded); cardsToDownload.append(cardBeingLoaded);
cardBeingLoaded.clear(); cardBeingLoaded.clear();
@ -242,21 +245,21 @@ bool PictureLoaderWorker::cardImageExistsOnDisk(QString &setName, QString &corre
for (const auto &_picsPath : picsPaths) { for (const auto &_picsPath : picsPaths) {
imgReader.setFileName(_picsPath); imgReader.setFileName(_picsPath);
if (imgReader.read(&image)) { if (imgReader.read(&image)) {
qDebug().nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName qCDebug(PictureLoaderLog).nospace()
<< "]: Picture found on disk."; << "PictureLoader: [card: " << correctedCardname << " set: " << setName << "]: Picture found on disk.";
imageLoaded(cardBeingLoaded.getCard(), image); imageLoaded(cardBeingLoaded.getCard(), image);
return true; return true;
} }
imgReader.setFileName(_picsPath + ".full"); imgReader.setFileName(_picsPath + ".full");
if (imgReader.read(&image)) { if (imgReader.read(&image)) {
qDebug().nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName
<< "]: Picture.full found on disk."; << "]: Picture.full found on disk.";
imageLoaded(cardBeingLoaded.getCard(), image); imageLoaded(cardBeingLoaded.getCard(), image);
return true; return true;
} }
imgReader.setFileName(_picsPath + ".xlhq"); imgReader.setFileName(_picsPath + ".xlhq");
if (imgReader.read(&image)) { if (imgReader.read(&image)) {
qDebug().nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName
<< "]: Picture.xlhq found on disk."; << "]: Picture.xlhq found on disk.";
imageLoaded(cardBeingLoaded.getCard(), image); imageLoaded(cardBeingLoaded.getCard(), image);
return true; return true;
@ -303,18 +306,19 @@ static int parse(const QString &urlTemplate,
} }
QString propertyValue = getProperty(cardPropertyName); QString propertyValue = getProperty(cardPropertyName);
if (propertyValue.isEmpty()) { if (propertyValue.isEmpty()) {
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " qCDebug(PictureLoaderLog).nospace()
<< propType << "property (" << cardPropertyName << ") for Url template (" << urlTemplate << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " << propType
<< ") is not available"; << "property (" << cardPropertyName << ") for Url template (" << urlTemplate << ") is not available";
return 1; return 1;
} else { } else {
int propLength = propertyValue.length(); int propLength = propertyValue.length();
if (subStrLen > 0) { if (subStrLen > 0) {
if (subStrPos + subStrLen > propLength) { if (subStrPos + subStrLen > propLength) {
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " qCDebug(PictureLoaderLog).nospace()
<< propType << " property (" << cardPropertyName << ") for Url template (" << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " << propType
<< urlTemplate << ") is smaller than substr specification (" << subStrPos << " property (" << cardPropertyName << ") for Url template (" << urlTemplate
<< " + " << subStrLen << " > " << propLength << ")"; << ") is smaller than substr specification (" << subStrPos << " + " << subStrLen << " > "
<< propLength << ")";
return 1; return 1;
} else { } else {
propertyValue = propertyValue.mid(subStrPos, subStrLen); propertyValue = propertyValue.mid(subStrPos, subStrLen);
@ -325,9 +329,10 @@ static int parse(const QString &urlTemplate,
if (!fillWith.isEmpty()) { if (!fillWith.isEmpty()) {
int fillLength = fillWith.length(); int fillLength = fillWith.length();
if (fillLength < propLength) { if (fillLength < propLength) {
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " qCDebug(PictureLoaderLog).nospace()
<< propType << " property (" << cardPropertyName << ") for Url template (" << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " << propType
<< urlTemplate << ") is longer than fill specification (" << fillWith << ")"; << " property (" << cardPropertyName << ") for Url template (" << urlTemplate
<< ") is longer than fill specification (" << fillWith << ")";
return 1; return 1;
} else { } else {
@ -394,9 +399,9 @@ QString PictureToLoad::transformUrl(const QString &urlTemplate) const
* populated in this card, so it should return an empty string, * populated in this card, so it should return an empty string,
* indicating an invalid Url. * indicating an invalid Url.
*/ */
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName qCDebug(PictureLoaderLog).nospace()
<< "]: Requested information (" << prop << ") for Url template (" << urlTemplate << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested information ("
<< ") is not available"; << prop << ") for Url template (" << urlTemplate << ") is not available";
return QString(); return QString();
} }
} }
@ -424,7 +429,8 @@ void PictureLoaderWorker::startNextPicDownload()
picDownloadFailed(); picDownloadFailed();
} else { } else {
QUrl url(picUrl); QUrl url(picUrl);
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName() qCDebug(PictureLoaderLog).nospace()
<< "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
<< " set: " << cardBeingDownloaded.getSetName() << "]: Trying to fetch picture from url " << " set: " << cardBeingDownloaded.getSetName() << "]: Trying to fetch picture from url "
<< url.toDisplayString(); << url.toDisplayString();
makeRequest(url); makeRequest(url);
@ -442,7 +448,8 @@ void PictureLoaderWorker::picDownloadFailed()
loadQueue.prepend(cardBeingDownloaded); loadQueue.prepend(cardBeingDownloaded);
mutex.unlock(); mutex.unlock();
} else { } else {
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName() qCDebug(PictureLoaderLog).nospace()
<< "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
<< " set: " << cardBeingDownloaded.getSetName() << "]: Picture NOT found, " << " set: " << cardBeingDownloaded.getSetName() << "]: Picture NOT found, "
<< (picDownload ? "download failed" : "downloads disabled") << (picDownload ? "download failed" : "downloads disabled")
<< ", no more url combinations to try: BAILING OUT"; << ", no more url combinations to try: BAILING OUT";
@ -463,9 +470,10 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url)
// Check if the redirect is cached // Check if the redirect is cached
QUrl cachedRedirect = getCachedRedirect(url); QUrl cachedRedirect = getCachedRedirect(url);
if (!cachedRedirect.isEmpty()) { if (!cachedRedirect.isEmpty()) {
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName() qCDebug(PictureLoaderLog).nospace()
<< " set: " << cardBeingDownloaded.getSetName() << "]: Using cached redirect for " << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
<< url.toDisplayString() << " to " << cachedRedirect.toDisplayString(); << " set: " << cardBeingDownloaded.getSetName() << "]: Using cached redirect for " << url.toDisplayString()
<< " to " << cachedRedirect.toDisplayString();
return makeRequest(cachedRedirect); // Use the cached redirect return makeRequest(cachedRedirect); // Use the cached redirect
} }
@ -487,9 +495,10 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url)
} }
cacheRedirect(url, redirectUrl); cacheRedirect(url, redirectUrl);
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName() qCDebug(PictureLoaderLog).nospace()
<< " set: " << cardBeingDownloaded.getSetName() << "]: Caching redirect from " << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
<< url.toDisplayString() << " to " << redirectUrl.toDisplayString(); << " set: " << cardBeingDownloaded.getSetName() << "]: Caching redirect from " << url.toDisplayString()
<< " to " << redirectUrl.toDisplayString();
} }
reply->deleteLater(); reply->deleteLater();
@ -566,19 +575,19 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
if (reply->error()) { if (reply->error()) {
if (isFromCache) { if (isFromCache) {
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName() qCDebug(PictureLoaderLog).nospace()
<< " set: " << cardBeingDownloaded.getSetName() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
<< "]: Removing corrupted cache file for url " << reply->url().toDisplayString() << " set: " << cardBeingDownloaded.getSetName() << "]: Removing corrupted cache file for url "
<< " and retrying (" << reply->errorString() << ")"; << reply->url().toDisplayString() << " and retrying (" << reply->errorString() << ")";
networkManager->cache()->remove(reply->url()); networkManager->cache()->remove(reply->url());
makeRequest(reply->url()); makeRequest(reply->url());
} else { } else {
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName() qCDebug(PictureLoaderLog).nospace()
<< " set: " << cardBeingDownloaded.getSetName() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
<< "]: " << (picDownload ? "Download" : "Cache search") << " failed for url " << " set: " << cardBeingDownloaded.getSetName() << "]: " << (picDownload ? "Download" : "Cache search")
<< reply->url().toDisplayString() << " (" << reply->errorString() << ")"; << " failed for url " << reply->url().toDisplayString() << " (" << reply->errorString() << ")";
picDownloadFailed(); picDownloadFailed();
startNextPicDownload(); startNextPicDownload();
@ -593,7 +602,8 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
if (statusCode == 301 || statusCode == 302 || statusCode == 303 || statusCode == 305 || statusCode == 307 || if (statusCode == 301 || statusCode == 302 || statusCode == 303 || statusCode == 305 || statusCode == 307 ||
statusCode == 308) { statusCode == 308) {
QUrl redirectUrl = reply->header(QNetworkRequest::LocationHeader).toUrl(); QUrl redirectUrl = reply->header(QNetworkRequest::LocationHeader).toUrl();
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName() qCDebug(PictureLoaderLog).nospace()
<< "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
<< " set: " << cardBeingDownloaded.getSetName() << "]: following " << " set: " << cardBeingDownloaded.getSetName() << "]: following "
<< (isFromCache ? "cached redirect" : "redirect") << " to " << redirectUrl.toDisplayString(); << (isFromCache ? "cached redirect" : "redirect") << " to " << redirectUrl.toDisplayString();
makeRequest(redirectUrl); makeRequest(redirectUrl);
@ -605,7 +615,7 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
const QByteArray &picData = reply->peek(reply->size()); const QByteArray &picData = reply->peek(reply->size());
if (imageIsBlackListed(picData)) { if (imageIsBlackListed(picData)) {
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName() qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
<< " set: " << cardBeingDownloaded.getSetName() << " set: " << cardBeingDownloaded.getSetName()
<< "]: Picture found, but blacklisted, will consider it as not found"; << "]: Picture found, but blacklisted, will consider it as not found";
@ -640,19 +650,19 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
imageLoaded(cardBeingDownloaded.getCard(), testImage); imageLoaded(cardBeingDownloaded.getCard(), testImage);
logSuccessMessage = true; logSuccessMessage = true;
} else { } else {
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName() qCDebug(PictureLoaderLog).nospace()
<< " set: " << cardBeingDownloaded.getSetName() << "]: Possible " << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
<< (isFromCache ? "cached" : "downloaded") << " picture at " << " set: " << cardBeingDownloaded.getSetName() << "]: Possible " << (isFromCache ? "cached" : "downloaded")
<< reply->url().toDisplayString() << " could not be loaded: " << reply->errorString(); << " picture at " << reply->url().toDisplayString() << " could not be loaded: " << reply->errorString();
picDownloadFailed(); picDownloadFailed();
} }
if (logSuccessMessage) { if (logSuccessMessage) {
qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName() qCDebug(PictureLoaderLog).nospace()
<< "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
<< " set: " << cardBeingDownloaded.getSetName() << "]: Image successfully " << " set: " << cardBeingDownloaded.getSetName() << "]: Image successfully "
<< (isFromCache ? "loaded from cached" : "downloaded from") << " url " << (isFromCache ? "loaded from cached" : "downloaded from") << " url " << reply->url().toDisplayString();
<< reply->url().toDisplayString();
} }
reply->deleteLater(); reply->deleteLater();
@ -719,7 +729,7 @@ void PictureLoader::getCardBackPixmap(QPixmap &pixmap, QSize size)
{ {
QString backCacheKey = "_trice_card_back_" + QString::number(size.width()) + QString::number(size.height()); QString backCacheKey = "_trice_card_back_" + QString::number(size.width()) + QString::number(size.height());
if (!QPixmapCache::find(backCacheKey, &pixmap)) { if (!QPixmapCache::find(backCacheKey, &pixmap)) {
qDebug() << "PictureLoader: cache fail for" << backCacheKey; qCDebug(PictureLoaderLog) << "PictureLoader: cache fail for" << backCacheKey;
pixmap = QPixmap("theme:cardback").scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); pixmap = QPixmap("theme:cardback").scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmapCache::insert(backCacheKey, pixmap); QPixmapCache::insert(backCacheKey, pixmap);
} }
@ -729,7 +739,7 @@ void PictureLoader::getCardBackLoadingInProgressPixmap(QPixmap &pixmap, QSize si
{ {
QString backCacheKey = "_trice_card_back_" + QString::number(size.width()) + QString::number(size.height()); QString backCacheKey = "_trice_card_back_" + QString::number(size.width()) + QString::number(size.height());
if (!QPixmapCache::find(backCacheKey, &pixmap)) { if (!QPixmapCache::find(backCacheKey, &pixmap)) {
qDebug() << "PictureLoader: cache fail for" << backCacheKey; qCDebug(PictureLoaderLog) << "PictureLoader: cache fail for" << backCacheKey;
pixmap = QPixmap("theme:cardback").scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); pixmap = QPixmap("theme:cardback").scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmapCache::insert(backCacheKey, pixmap); QPixmapCache::insert(backCacheKey, pixmap);
} }
@ -739,7 +749,7 @@ void PictureLoader::getCardBackLoadingFailedPixmap(QPixmap &pixmap, QSize size)
{ {
QString backCacheKey = "_trice_card_back_" + QString::number(size.width()) + QString::number(size.height()); QString backCacheKey = "_trice_card_back_" + QString::number(size.width()) + QString::number(size.height());
if (!QPixmapCache::find(backCacheKey, &pixmap)) { if (!QPixmapCache::find(backCacheKey, &pixmap)) {
qDebug() << "PictureLoader: cache fail for" << backCacheKey; qCDebug(PictureLoaderLog) << "PictureLoader: cache fail for" << backCacheKey;
pixmap = QPixmap("theme:cardback").scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); pixmap = QPixmap("theme:cardback").scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QPixmapCache::insert(backCacheKey, pixmap); QPixmapCache::insert(backCacheKey, pixmap);
} }

View file

@ -57,10 +57,14 @@ PrintingSelector::PrintingSelector(QWidget *parent,
layout->addWidget(cardSelectionBar); layout->addWidget(cardSelectionBar);
// Connect deck model data change signal to update display // Connect deck model data change signal to update display
connect(deckModel, &DeckListModel::dataChanged, this, [this]() { connect(deckModel, &DeckListModel::rowsInserted, this, &PrintingSelector::printingsInDeckChanged);
connect(deckModel, &DeckListModel::rowsRemoved, this, &PrintingSelector::printingsInDeckChanged);
}
void PrintingSelector::printingsInDeckChanged()
{
// Delay the update to avoid race conditions // Delay the update to avoid race conditions
QTimer::singleShot(100, this, &PrintingSelector::updateDisplay); QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
});
} }
/** /**
@ -89,6 +93,12 @@ void PrintingSelector::setCard(const CardInfoPtr &newCard, const QString &_curre
if (newCard.isNull()) { if (newCard.isNull()) {
return; return;
} }
// we don't need to redraw the widget if the card is the same
if (!selectedCard.isNull() && selectedCard->getName() == newCard->getName()) {
return;
}
selectedCard = newCard; selectedCard = newCard;
currentZone = _currentZone; currentZone = _currentZone;
if (isVisible()) { if (isVisible()) {

View file

@ -37,6 +37,9 @@ public slots:
void toggleVisibilityCardSizeSlider(bool _state); void toggleVisibilityCardSizeSlider(bool _state);
void toggleVisibilityNavigationButtons(bool _state); void toggleVisibilityNavigationButtons(bool _state);
private slots:
void printingsInDeckChanged();
private: private:
QVBoxLayout *layout; QVBoxLayout *layout;
PrintingSelectorViewOptionsToolbarWidget *viewOptionsToolbar; PrintingSelectorViewOptionsToolbarWidget *viewOptionsToolbar;

View file

@ -366,6 +366,12 @@ void MainWindow::actViewLog()
logviewDialog->activateWindow(); logviewDialog->activateWindow();
} }
void MainWindow::actOpenSettingsFolder()
{
QString dir = SettingsCache::instance().getSettingsPath();
QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
}
void MainWindow::serverTimeout() void MainWindow::serverTimeout()
{ {
QMessageBox::critical(this, tr("Error"), tr("Server timeout")); QMessageBox::critical(this, tr("Error"), tr("Server timeout"));
@ -687,6 +693,7 @@ void MainWindow::retranslateUi()
aUpdate->setText(tr("Check for Client Updates")); aUpdate->setText(tr("Check for Client Updates"));
aCheckCardUpdates->setText(tr("Check for Card Updates...")); aCheckCardUpdates->setText(tr("Check for Card Updates..."));
aViewLog->setText(tr("View &Debug Log")); aViewLog->setText(tr("View &Debug Log"));
aOpenSettingsFolder->setText(tr("Open Settings Folder"));
aShow->setText(tr("Show/Hide")); aShow->setText(tr("Show/Hide"));
@ -743,6 +750,8 @@ void MainWindow::createActions()
connect(aCheckCardUpdates, SIGNAL(triggered()), this, SLOT(actCheckCardUpdates())); connect(aCheckCardUpdates, SIGNAL(triggered()), this, SLOT(actCheckCardUpdates()));
aViewLog = new QAction(this); aViewLog = new QAction(this);
connect(aViewLog, SIGNAL(triggered()), this, SLOT(actViewLog())); connect(aViewLog, SIGNAL(triggered()), this, SLOT(actViewLog()));
aOpenSettingsFolder = new QAction(this);
connect(aOpenSettingsFolder, &QAction::triggered, this, &MainWindow::actOpenSettingsFolder);
aShow = new QAction(this); aShow = new QAction(this);
connect(aShow, SIGNAL(triggered()), this, SLOT(actShow())); connect(aShow, SIGNAL(triggered()), this, SLOT(actShow()));
@ -818,6 +827,7 @@ void MainWindow::createMenus()
helpMenu->addAction(aCheckCardUpdates); helpMenu->addAction(aCheckCardUpdates);
helpMenu->addSeparator(); helpMenu->addSeparator();
helpMenu->addAction(aViewLog); helpMenu->addAction(aViewLog);
helpMenu->addAction(aOpenSettingsFolder);
} }
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)

View file

@ -84,6 +84,7 @@ private slots:
void actTips(); void actTips();
void actUpdate(); void actUpdate();
void actViewLog(); void actViewLog();
void actOpenSettingsFolder();
void forgotPasswordSuccess(); void forgotPasswordSuccess();
void forgotPasswordError(); void forgotPasswordError();
void promptForgotPasswordReset(); void promptForgotPasswordReset();
@ -134,7 +135,8 @@ private:
QAction *aConnect, *aDisconnect, *aSinglePlayer, *aWatchReplay, *aDeckEditor, *aVisualDeckStorage, *aFullScreen, QAction *aConnect, *aDisconnect, *aSinglePlayer, *aWatchReplay, *aDeckEditor, *aVisualDeckStorage, *aFullScreen,
*aSettings, *aExit, *aAbout, *aTips, *aCheckCardUpdates, *aRegister, *aForgotPassword, *aUpdate, *aViewLog, *aSettings, *aExit, *aAbout, *aTips, *aCheckCardUpdates, *aRegister, *aForgotPassword, *aUpdate, *aViewLog,
*aManageSets, *aEditTokens, *aOpenCustomFolder, *aOpenCustomsetsFolder, *aAddCustomSet, *aReloadCardDatabase, *aManageSets, *aEditTokens, *aOpenCustomFolder, *aOpenCustomsetsFolder, *aAddCustomSet, *aReloadCardDatabase,
*aShow; *aShow, *aOpenSettingsFolder;
TabSupervisor *tabSupervisor; TabSupervisor *tabSupervisor;
WndSets *wndSets; WndSets *wndSets;
RemoteClient *client; RemoteClient *client;

View file

@ -0,0 +1,22 @@
#include "dlg_load_deck.h"
#include "../deck/deck_loader.h"
#include "../settings/cache_settings.h"
DlgLoadDeck::DlgLoadDeck(QWidget *parent) : QFileDialog(parent, tr("Load Deck"))
{
QString startingDir = SettingsCache::instance().recents().getLatestDeckDirPath();
if (startingDir.isEmpty()) {
startingDir = SettingsCache::instance().getDeckPath();
}
setDirectory(startingDir);
setNameFilters(DeckLoader::fileNameFilters);
connect(this, &DlgLoadDeck::accepted, this, &DlgLoadDeck::actAccepted);
}
void DlgLoadDeck::actAccepted()
{
SettingsCache::instance().recents().setLatestDeckDirPath(directory().absolutePath());
}

View file

@ -0,0 +1,21 @@
#ifndef DLG_LOAD_DECK_H
#define DLG_LOAD_DECK_H
#include <QFileDialog>
/**
* The file dialog for "Load Deck" operations.
* Handles remembering the most recently used deck loading directory.
*/
class DlgLoadDeck : public QFileDialog
{
Q_OBJECT
void actAccepted();
public:
explicit DlgLoadDeck(QWidget *parent = nullptr);
};
#endif // DLG_LOAD_DECK_H

View file

@ -71,3 +71,13 @@ void DlgLoadDeckFromClipboard::actOK()
delete deckLoader; delete deckLoader;
} }
} }
void DlgLoadDeckFromClipboard::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Return && event->modifiers() & Qt::ControlModifier) {
event->accept();
actOK();
return;
}
QDialog::keyPressEvent(event);
}

View file

@ -26,6 +26,9 @@ public:
{ {
return deckList; return deckList;
} }
protected:
void keyPressEvent(QKeyEvent *event) override;
}; };
#endif #endif

View file

@ -136,6 +136,9 @@ int main(int argc, char *argv[])
SetUnhandledExceptionFilter(CockatriceUnhandledExceptionFilter); SetUnhandledExceptionFilter(CockatriceUnhandledExceptionFilter);
#endif #endif
// Set the QT_LOGGING_CONF environment variable
qputenv("QT_LOGGING_CONF", "./qtlogging.ini");
QApplication app(argc, argv); QApplication app(argc, argv);
QObject::connect(&app, &QApplication::lastWindowClosed, &app, &QApplication::quit); QObject::connect(&app, &QApplication::lastWindowClosed, &app, &QApplication::quit);

View file

@ -5,9 +5,9 @@
DebugSettings::DebugSettings(const QString &settingPath, QObject *parent) DebugSettings::DebugSettings(const QString &settingPath, QObject *parent)
: SettingsManager(settingPath + "debug.ini", parent) : SettingsManager(settingPath + "debug.ini", parent)
{ {
// force debug.ini to be created if it doesn't exist yet // Create the default debug.ini if it doesn't exist yet
if (!QFile(settingPath + "debug.ini").exists()) { if (!QFile(settingPath + "debug.ini").exists()) {
setValue(false, "showCardId", "debug"); QFile::copy(":/resources/config/debug.ini", settingPath + "debug.ini");
} }
} }

View file

@ -30,3 +30,13 @@ void RecentsSettings::updateRecentlyOpenedDeckPaths(const QString &deckPath)
setValue(deckPaths, "deckpaths", "deckbuilder"); setValue(deckPaths, "deckpaths", "deckbuilder");
emit recentlyOpenedDeckPathsChanged(); emit recentlyOpenedDeckPathsChanged();
} }
QString RecentsSettings::getLatestDeckDirPath()
{
return getValue("latestDeckDir", "dirs").toString();
}
void RecentsSettings::setLatestDeckDirPath(const QString &dirPath)
{
setValue(dirPath, "latestDeckDir", "dirs");
}

View file

@ -16,6 +16,9 @@ public:
void clearRecentlyOpenedDeckPaths(); void clearRecentlyOpenedDeckPaths();
void updateRecentlyOpenedDeckPaths(const QString &deckPath); void updateRecentlyOpenedDeckPaths(const QString &deckPath);
QString getLatestDeckDirPath();
void setLatestDeckDirPath(const QString &dirPath);
signals: signals:
void recentlyOpenedDeckPathsChanged(); void recentlyOpenedDeckPathsChanged();
}; };