diff --git a/.gitignore b/.gitignore
index b0ccf34e0..f147c1458 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@ compile_commands.json
.vscode/
.cache
.gdb_history
+cockatrice/resources/config/qtlogging.ini
diff --git a/cockatrice/CMakeLists.txt b/cockatrice/CMakeLists.txt
index 2122edbc6..c88aca46b 100644
--- a/cockatrice/CMakeLists.txt
+++ b/cockatrice/CMakeLists.txt
@@ -56,6 +56,7 @@ set(cockatrice_SOURCES
src/dialogs/dlg_tip_of_the_day.cpp
src/dialogs/dlg_update.cpp
src/dialogs/dlg_view_log.cpp
+ src/dialogs/dlg_load_deck.cpp
src/game/filters/filter_string.cpp
src/game/filters/filter_builder.cpp
src/game/filters/filter_tree.cpp
@@ -168,6 +169,9 @@ set(cockatrice_SOURCES
add_subdirectory(sounds)
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)
diff --git a/cockatrice/cockatrice.qrc b/cockatrice/cockatrice.qrc
index 2d147bcf6..c93499cf3 100644
--- a/cockatrice/cockatrice.qrc
+++ b/cockatrice/cockatrice.qrc
@@ -41,6 +41,8 @@
resources/config/deckeditor.svg
resources/config/shorcuts.svg
resources/config/sound.svg
+ resources/config/debug.ini
+ resources/config/qtlogging.ini
resources/counters/w.svg
resources/counters/w_highlight.svg
diff --git a/cockatrice/resources/config/debug.ini b/cockatrice/resources/config/debug.ini
new file mode 100644
index 000000000..a1d203c7a
--- /dev/null
+++ b/cockatrice/resources/config/debug.ini
@@ -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
diff --git a/cockatrice/resources/config/qtlogging.ini b/cockatrice/resources/config/qtlogging.ini
new file mode 100644
index 000000000..325ac6536
--- /dev/null
+++ b/cockatrice/resources/config/qtlogging.ini
@@ -0,0 +1,2 @@
+[Rules]
+picture_loader.debug = true
\ No newline at end of file
diff --git a/cockatrice/src/client/tabs/tab_deck_editor.cpp b/cockatrice/src/client/tabs/tab_deck_editor.cpp
index 79982129b..8de574798 100644
--- a/cockatrice/src/client/tabs/tab_deck_editor.cpp
+++ b/cockatrice/src/client/tabs/tab_deck_editor.cpp
@@ -5,6 +5,7 @@
#include "../../client/ui/widgets/cards/card_info_frame_widget.h"
#include "../../deck/deck_list_model.h"
#include "../../deck/deck_stats_interface.h"
+#include "../../dialogs/dlg_load_deck.h"
#include "../../dialogs/dlg_load_deck_from_clipboard.h"
#include "../../game/cards/card_database_manager.h"
#include "../../game/cards/card_database_model.h"
@@ -1007,9 +1008,7 @@ void TabDeckEditor::actLoadDeck()
return;
}
- QFileDialog dialog(this, tr("Load deck"));
- dialog.setDirectory(SettingsCache::instance().getDeckPath());
- dialog.setNameFilters(DeckLoader::fileNameFilters);
+ DlgLoadDeck dialog(this);
if (!dialog.exec())
return;
diff --git a/cockatrice/src/client/tabs/tab_game.cpp b/cockatrice/src/client/tabs/tab_game.cpp
index 043112173..9897b3865 100644
--- a/cockatrice/src/client/tabs/tab_game.cpp
+++ b/cockatrice/src/client/tabs/tab_game.cpp
@@ -4,6 +4,7 @@
#include "../../deck/deck_loader.h"
#include "../../deck/deck_view.h"
#include "../../dialogs/dlg_create_game.h"
+#include "../../dialogs/dlg_load_deck.h"
#include "../../dialogs/dlg_load_remote_deck.h"
#include "../../dialogs/dlg_manage_sets.h"
#include "../../game/board/arrow_item.h"
@@ -338,9 +339,7 @@ void DeckViewContainer::unloadDeck()
void DeckViewContainer::loadLocalDeck()
{
- QFileDialog dialog(this, tr("Load deck"));
- dialog.setDirectory(SettingsCache::instance().getDeckPath());
- dialog.setNameFilters(DeckLoader::fileNameFilters);
+ DlgLoadDeck dialog(this);
if (!dialog.exec())
return;
@@ -815,6 +814,12 @@ void TabGame::actSay()
if (completer->popup()->isVisible())
return;
+ if (sayEdit->text().startsWith("/card ")) {
+ cardInfoFrameWidget->setCard(sayEdit->text().mid(6));
+ sayEdit->clear();
+ return;
+ }
+
if (!sayEdit->text().isEmpty()) {
Command_GameSay cmd;
cmd.set_message(sayEdit->text().toStdString());
diff --git a/cockatrice/src/client/ui/picture_loader.cpp b/cockatrice/src/client/ui/picture_loader.cpp
index 8eb4a7fb9..a2eed3f28 100644
--- a/cockatrice/src/client/ui/picture_loader.cpp
+++ b/cockatrice/src/client/ui/picture_loader.cpp
@@ -23,8 +23,11 @@
#include
#include
#include
+#include
#include
+Q_LOGGING_CATEGORY(PictureLoaderLog, "picture_loader")
+
// never cache more than 300 cards at once for a single deck
#define CACHED_CARD_PER_DECK_MAX 300
@@ -189,8 +192,8 @@ void PictureLoaderWorker::processLoadQueue()
QString cardName = cardBeingLoaded.getCard()->getName();
QString correctedCardName = cardBeingLoaded.getCard()->getCorrectedName();
- qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName
- << "]: Trying to load picture";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Trying to load picture";
if (CardDatabaseManager::getInstance()->isProviderIdForPreferredPrinting(
cardName, cardBeingLoaded.getCard()->getPixmapCacheKey())) {
@@ -199,8 +202,8 @@ void PictureLoaderWorker::processLoadQueue()
}
}
- qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName
- << "]: No custom picture, trying to download";
+ qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << cardName << " set: " << setName
+ << "]: No custom picture, trying to download";
cardsToDownload.append(cardBeingLoaded);
cardBeingLoaded.clear();
if (!downloadRunning) {
@@ -242,22 +245,22 @@ bool PictureLoaderWorker::cardImageExistsOnDisk(QString &setName, QString &corre
for (const auto &_picsPath : picsPaths) {
imgReader.setFileName(_picsPath);
if (imgReader.read(&image)) {
- qDebug().nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName
- << "]: Picture found on disk.";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << correctedCardname << " set: " << setName << "]: Picture found on disk.";
imageLoaded(cardBeingLoaded.getCard(), image);
return true;
}
imgReader.setFileName(_picsPath + ".full");
if (imgReader.read(&image)) {
- qDebug().nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName
- << "]: Picture.full found on disk.";
+ qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName
+ << "]: Picture.full found on disk.";
imageLoaded(cardBeingLoaded.getCard(), image);
return true;
}
imgReader.setFileName(_picsPath + ".xlhq");
if (imgReader.read(&image)) {
- qDebug().nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName
- << "]: Picture.xlhq found on disk.";
+ qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << correctedCardname << " set: " << setName
+ << "]: Picture.xlhq found on disk.";
imageLoaded(cardBeingLoaded.getCard(), image);
return true;
}
@@ -303,18 +306,19 @@ static int parse(const QString &urlTemplate,
}
QString propertyValue = getProperty(cardPropertyName);
if (propertyValue.isEmpty()) {
- qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested "
- << propType << "property (" << cardPropertyName << ") for Url template (" << urlTemplate
- << ") is not available";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " << propType
+ << "property (" << cardPropertyName << ") for Url template (" << urlTemplate << ") is not available";
return 1;
} else {
int propLength = propertyValue.length();
if (subStrLen > 0) {
if (subStrPos + subStrLen > propLength) {
- qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested "
- << propType << " property (" << cardPropertyName << ") for Url template ("
- << urlTemplate << ") is smaller than substr specification (" << subStrPos
- << " + " << subStrLen << " > " << propLength << ")";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " << propType
+ << " property (" << cardPropertyName << ") for Url template (" << urlTemplate
+ << ") is smaller than substr specification (" << subStrPos << " + " << subStrLen << " > "
+ << propLength << ")";
return 1;
} else {
propertyValue = propertyValue.mid(subStrPos, subStrLen);
@@ -325,9 +329,10 @@ static int parse(const QString &urlTemplate,
if (!fillWith.isEmpty()) {
int fillLength = fillWith.length();
if (fillLength < propLength) {
- qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested "
- << propType << " property (" << cardPropertyName << ") for Url template ("
- << urlTemplate << ") is longer than fill specification (" << fillWith << ")";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested " << propType
+ << " property (" << cardPropertyName << ") for Url template (" << urlTemplate
+ << ") is longer than fill specification (" << fillWith << ")";
return 1;
} else {
@@ -394,9 +399,9 @@ QString PictureToLoad::transformUrl(const QString &urlTemplate) const
* populated in this card, so it should return an empty string,
* indicating an invalid Url.
*/
- qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName
- << "]: Requested information (" << prop << ") for Url template (" << urlTemplate
- << ") is not available";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested information ("
+ << prop << ") for Url template (" << urlTemplate << ") is not available";
return QString();
}
}
@@ -424,9 +429,10 @@ void PictureLoaderWorker::startNextPicDownload()
picDownloadFailed();
} else {
QUrl url(picUrl);
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
- << " set: " << cardBeingDownloaded.getSetName() << "]: Trying to fetch picture from url "
- << url.toDisplayString();
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: Trying to fetch picture from url "
+ << url.toDisplayString();
makeRequest(url);
}
}
@@ -442,10 +448,11 @@ void PictureLoaderWorker::picDownloadFailed()
loadQueue.prepend(cardBeingDownloaded);
mutex.unlock();
} else {
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
- << " set: " << cardBeingDownloaded.getSetName() << "]: Picture NOT found, "
- << (picDownload ? "download failed" : "downloads disabled")
- << ", no more url combinations to try: BAILING OUT";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: Picture NOT found, "
+ << (picDownload ? "download failed" : "downloads disabled")
+ << ", no more url combinations to try: BAILING OUT";
imageLoaded(cardBeingDownloaded.getCard(), QImage());
cardBeingDownloaded.clear();
}
@@ -463,9 +470,10 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url)
// Check if the redirect is cached
QUrl cachedRedirect = getCachedRedirect(url);
if (!cachedRedirect.isEmpty()) {
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
- << " set: " << cardBeingDownloaded.getSetName() << "]: Using cached redirect for "
- << url.toDisplayString() << " to " << cachedRedirect.toDisplayString();
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: Using cached redirect for " << url.toDisplayString()
+ << " to " << cachedRedirect.toDisplayString();
return makeRequest(cachedRedirect); // Use the cached redirect
}
@@ -487,9 +495,10 @@ QNetworkReply *PictureLoaderWorker::makeRequest(const QUrl &url)
}
cacheRedirect(url, redirectUrl);
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
- << " set: " << cardBeingDownloaded.getSetName() << "]: Caching redirect from "
- << url.toDisplayString() << " to " << redirectUrl.toDisplayString();
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getCorrectedName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: Caching redirect from " << url.toDisplayString()
+ << " to " << redirectUrl.toDisplayString();
}
reply->deleteLater();
@@ -566,19 +575,19 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
if (reply->error()) {
if (isFromCache) {
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
- << " set: " << cardBeingDownloaded.getSetName()
- << "]: Removing corrupted cache file for url " << reply->url().toDisplayString()
- << " and retrying (" << reply->errorString() << ")";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: Removing corrupted cache file for url "
+ << reply->url().toDisplayString() << " and retrying (" << reply->errorString() << ")";
networkManager->cache()->remove(reply->url());
makeRequest(reply->url());
} else {
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
- << " set: " << cardBeingDownloaded.getSetName()
- << "]: " << (picDownload ? "Download" : "Cache search") << " failed for url "
- << reply->url().toDisplayString() << " (" << reply->errorString() << ")";
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: " << (picDownload ? "Download" : "Cache search")
+ << " failed for url " << reply->url().toDisplayString() << " (" << reply->errorString() << ")";
picDownloadFailed();
startNextPicDownload();
@@ -593,9 +602,10 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
if (statusCode == 301 || statusCode == 302 || statusCode == 303 || statusCode == 305 || statusCode == 307 ||
statusCode == 308) {
QUrl redirectUrl = reply->header(QNetworkRequest::LocationHeader).toUrl();
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
- << " set: " << cardBeingDownloaded.getSetName() << "]: following "
- << (isFromCache ? "cached redirect" : "redirect") << " to " << redirectUrl.toDisplayString();
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: following "
+ << (isFromCache ? "cached redirect" : "redirect") << " to " << redirectUrl.toDisplayString();
makeRequest(redirectUrl);
reply->deleteLater();
return;
@@ -605,9 +615,9 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
const QByteArray &picData = reply->peek(reply->size());
if (imageIsBlackListed(picData)) {
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
- << " set: " << cardBeingDownloaded.getSetName()
- << "]: Picture found, but blacklisted, will consider it as not found";
+ qCDebug(PictureLoaderLog).nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
+ << " set: " << cardBeingDownloaded.getSetName()
+ << "]: Picture found, but blacklisted, will consider it as not found";
picDownloadFailed();
reply->deleteLater();
@@ -640,19 +650,19 @@ void PictureLoaderWorker::picDownloadFinished(QNetworkReply *reply)
imageLoaded(cardBeingDownloaded.getCard(), testImage);
logSuccessMessage = true;
} else {
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
- << " set: " << cardBeingDownloaded.getSetName() << "]: Possible "
- << (isFromCache ? "cached" : "downloaded") << " picture at "
- << reply->url().toDisplayString() << " could not be loaded: " << reply->errorString();
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: Possible " << (isFromCache ? "cached" : "downloaded")
+ << " picture at " << reply->url().toDisplayString() << " could not be loaded: " << reply->errorString();
picDownloadFailed();
}
if (logSuccessMessage) {
- qDebug().nospace() << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
- << " set: " << cardBeingDownloaded.getSetName() << "]: Image successfully "
- << (isFromCache ? "loaded from cached" : "downloaded from") << " url "
- << reply->url().toDisplayString();
+ qCDebug(PictureLoaderLog).nospace()
+ << "PictureLoader: [card: " << cardBeingDownloaded.getCard()->getName()
+ << " set: " << cardBeingDownloaded.getSetName() << "]: Image successfully "
+ << (isFromCache ? "loaded from cached" : "downloaded from") << " url " << reply->url().toDisplayString();
}
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());
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);
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());
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);
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());
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);
QPixmapCache::insert(backCacheKey, pixmap);
}
diff --git a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp
index 33f76ada7..9943b9403 100644
--- a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp
+++ b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.cpp
@@ -57,10 +57,14 @@ PrintingSelector::PrintingSelector(QWidget *parent,
layout->addWidget(cardSelectionBar);
// Connect deck model data change signal to update display
- connect(deckModel, &DeckListModel::dataChanged, this, [this]() {
- // Delay the update to avoid race conditions
- QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
- });
+ connect(deckModel, &DeckListModel::rowsInserted, this, &PrintingSelector::printingsInDeckChanged);
+ connect(deckModel, &DeckListModel::rowsRemoved, this, &PrintingSelector::printingsInDeckChanged);
+}
+
+void PrintingSelector::printingsInDeckChanged()
+{
+ // Delay the update to avoid race conditions
+ QTimer::singleShot(100, this, &PrintingSelector::updateDisplay);
}
/**
@@ -89,6 +93,12 @@ void PrintingSelector::setCard(const CardInfoPtr &newCard, const QString &_curre
if (newCard.isNull()) {
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;
currentZone = _currentZone;
if (isVisible()) {
diff --git a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h
index 1e9b01b29..547d4dbef 100644
--- a/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h
+++ b/cockatrice/src/client/ui/widgets/printing_selector/printing_selector.h
@@ -37,6 +37,9 @@ public slots:
void toggleVisibilityCardSizeSlider(bool _state);
void toggleVisibilityNavigationButtons(bool _state);
+private slots:
+ void printingsInDeckChanged();
+
private:
QVBoxLayout *layout;
PrintingSelectorViewOptionsToolbarWidget *viewOptionsToolbar;
diff --git a/cockatrice/src/client/ui/window_main.cpp b/cockatrice/src/client/ui/window_main.cpp
index b0cf4165e..ff25471a1 100644
--- a/cockatrice/src/client/ui/window_main.cpp
+++ b/cockatrice/src/client/ui/window_main.cpp
@@ -366,6 +366,12 @@ void MainWindow::actViewLog()
logviewDialog->activateWindow();
}
+void MainWindow::actOpenSettingsFolder()
+{
+ QString dir = SettingsCache::instance().getSettingsPath();
+ QDesktopServices::openUrl(QUrl::fromLocalFile(dir));
+}
+
void MainWindow::serverTimeout()
{
QMessageBox::critical(this, tr("Error"), tr("Server timeout"));
@@ -687,6 +693,7 @@ void MainWindow::retranslateUi()
aUpdate->setText(tr("Check for Client Updates"));
aCheckCardUpdates->setText(tr("Check for Card Updates..."));
aViewLog->setText(tr("View &Debug Log"));
+ aOpenSettingsFolder->setText(tr("Open Settings Folder"));
aShow->setText(tr("Show/Hide"));
@@ -743,6 +750,8 @@ void MainWindow::createActions()
connect(aCheckCardUpdates, SIGNAL(triggered()), this, SLOT(actCheckCardUpdates()));
aViewLog = new QAction(this);
connect(aViewLog, SIGNAL(triggered()), this, SLOT(actViewLog()));
+ aOpenSettingsFolder = new QAction(this);
+ connect(aOpenSettingsFolder, &QAction::triggered, this, &MainWindow::actOpenSettingsFolder);
aShow = new QAction(this);
connect(aShow, SIGNAL(triggered()), this, SLOT(actShow()));
@@ -818,6 +827,7 @@ void MainWindow::createMenus()
helpMenu->addAction(aCheckCardUpdates);
helpMenu->addSeparator();
helpMenu->addAction(aViewLog);
+ helpMenu->addAction(aOpenSettingsFolder);
}
MainWindow::MainWindow(QWidget *parent)
diff --git a/cockatrice/src/client/ui/window_main.h b/cockatrice/src/client/ui/window_main.h
index 356b6f529..4efed7fd5 100644
--- a/cockatrice/src/client/ui/window_main.h
+++ b/cockatrice/src/client/ui/window_main.h
@@ -84,6 +84,7 @@ private slots:
void actTips();
void actUpdate();
void actViewLog();
+ void actOpenSettingsFolder();
void forgotPasswordSuccess();
void forgotPasswordError();
void promptForgotPasswordReset();
@@ -134,7 +135,8 @@ private:
QAction *aConnect, *aDisconnect, *aSinglePlayer, *aWatchReplay, *aDeckEditor, *aVisualDeckStorage, *aFullScreen,
*aSettings, *aExit, *aAbout, *aTips, *aCheckCardUpdates, *aRegister, *aForgotPassword, *aUpdate, *aViewLog,
*aManageSets, *aEditTokens, *aOpenCustomFolder, *aOpenCustomsetsFolder, *aAddCustomSet, *aReloadCardDatabase,
- *aShow;
+ *aShow, *aOpenSettingsFolder;
+
TabSupervisor *tabSupervisor;
WndSets *wndSets;
RemoteClient *client;
diff --git a/cockatrice/src/dialogs/dlg_load_deck.cpp b/cockatrice/src/dialogs/dlg_load_deck.cpp
new file mode 100644
index 000000000..0fabdaaa3
--- /dev/null
+++ b/cockatrice/src/dialogs/dlg_load_deck.cpp
@@ -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());
+}
\ No newline at end of file
diff --git a/cockatrice/src/dialogs/dlg_load_deck.h b/cockatrice/src/dialogs/dlg_load_deck.h
new file mode 100644
index 000000000..13df97995
--- /dev/null
+++ b/cockatrice/src/dialogs/dlg_load_deck.h
@@ -0,0 +1,21 @@
+
+#ifndef DLG_LOAD_DECK_H
+#define DLG_LOAD_DECK_H
+
+#include
+
+/**
+ * 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
diff --git a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp
index e3673d1a3..dd06b45c8 100644
--- a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp
+++ b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.cpp
@@ -71,3 +71,13 @@ void DlgLoadDeckFromClipboard::actOK()
delete deckLoader;
}
}
+
+void DlgLoadDeckFromClipboard::keyPressEvent(QKeyEvent *event)
+{
+ if (event->key() == Qt::Key_Return && event->modifiers() & Qt::ControlModifier) {
+ event->accept();
+ actOK();
+ return;
+ }
+ QDialog::keyPressEvent(event);
+}
\ No newline at end of file
diff --git a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h
index 7a9833b41..56c75f707 100644
--- a/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h
+++ b/cockatrice/src/dialogs/dlg_load_deck_from_clipboard.h
@@ -26,6 +26,9 @@ public:
{
return deckList;
}
+
+protected:
+ void keyPressEvent(QKeyEvent *event) override;
};
#endif
diff --git a/cockatrice/src/main.cpp b/cockatrice/src/main.cpp
index b9bf7ea56..2384fb7e5 100644
--- a/cockatrice/src/main.cpp
+++ b/cockatrice/src/main.cpp
@@ -136,6 +136,9 @@ int main(int argc, char *argv[])
SetUnhandledExceptionFilter(CockatriceUnhandledExceptionFilter);
#endif
+ // Set the QT_LOGGING_CONF environment variable
+ qputenv("QT_LOGGING_CONF", "./qtlogging.ini");
+
QApplication app(argc, argv);
QObject::connect(&app, &QApplication::lastWindowClosed, &app, &QApplication::quit);
diff --git a/cockatrice/src/settings/debug_settings.cpp b/cockatrice/src/settings/debug_settings.cpp
index 75276a091..f6f12f60e 100644
--- a/cockatrice/src/settings/debug_settings.cpp
+++ b/cockatrice/src/settings/debug_settings.cpp
@@ -5,9 +5,9 @@
DebugSettings::DebugSettings(const QString &settingPath, QObject *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()) {
- setValue(false, "showCardId", "debug");
+ QFile::copy(":/resources/config/debug.ini", settingPath + "debug.ini");
}
}
diff --git a/cockatrice/src/settings/recents_settings.cpp b/cockatrice/src/settings/recents_settings.cpp
index da3c5313e..5bbec3c8c 100644
--- a/cockatrice/src/settings/recents_settings.cpp
+++ b/cockatrice/src/settings/recents_settings.cpp
@@ -29,4 +29,14 @@ void RecentsSettings::updateRecentlyOpenedDeckPaths(const QString &deckPath)
setValue(deckPaths, "deckpaths", "deckbuilder");
emit recentlyOpenedDeckPathsChanged();
+}
+
+QString RecentsSettings::getLatestDeckDirPath()
+{
+ return getValue("latestDeckDir", "dirs").toString();
+}
+
+void RecentsSettings::setLatestDeckDirPath(const QString &dirPath)
+{
+ setValue(dirPath, "latestDeckDir", "dirs");
}
\ No newline at end of file
diff --git a/cockatrice/src/settings/recents_settings.h b/cockatrice/src/settings/recents_settings.h
index c240b100d..6e91cd2f0 100644
--- a/cockatrice/src/settings/recents_settings.h
+++ b/cockatrice/src/settings/recents_settings.h
@@ -16,6 +16,9 @@ public:
void clearRecentlyOpenedDeckPaths();
void updateRecentlyOpenedDeckPaths(const QString &deckPath);
+ QString getLatestDeckDirPath();
+ void setLatestDeckDirPath(const QString &dirPath);
+
signals:
void recentlyOpenedDeckPathsChanged();
};