|
|
@@ -27,7 +27,6 @@
|
|
|
|
#include "citra_qt/game_list_worker.h"
|
|
|
|
#include "citra_qt/game_list_worker.h"
|
|
|
|
#include "citra_qt/main.h"
|
|
|
|
#include "citra_qt/main.h"
|
|
|
|
#include "citra_qt/uisettings.h"
|
|
|
|
#include "citra_qt/uisettings.h"
|
|
|
|
#include "common/common_paths.h"
|
|
|
|
|
|
|
|
#include "common/logging/log.h"
|
|
|
|
#include "common/logging/log.h"
|
|
|
|
#include "core/file_sys/archive_extsavedata.h"
|
|
|
|
#include "core/file_sys/archive_extsavedata.h"
|
|
|
|
#include "core/file_sys/archive_source_sd_savedata.h"
|
|
|
|
#include "core/file_sys/archive_source_sd_savedata.h"
|
|
|
@@ -54,7 +53,7 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve
|
|
|
|
return QObject::eventFilter(obj, event);
|
|
|
|
return QObject::eventFilter(obj, event);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
gamelist->search_field->edit_filter->clear();
|
|
|
|
gamelist->search_field->edit_filter->clear();
|
|
|
|
edit_filter_text = "";
|
|
|
|
edit_filter_text.clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -67,9 +66,9 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve
|
|
|
|
QString file_path = gamelist->getLastFilterResultItem();
|
|
|
|
QString file_path = gamelist->getLastFilterResultItem();
|
|
|
|
|
|
|
|
|
|
|
|
// To avoid loading error dialog loops while confirming them using enter
|
|
|
|
// To avoid loading error dialog loops while confirming them using enter
|
|
|
|
// Also users usually want to run a diffrent game after closing one
|
|
|
|
// Also users usually want to run a different game after closing one
|
|
|
|
gamelist->search_field->edit_filter->setText("");
|
|
|
|
gamelist->search_field->edit_filter->clear();
|
|
|
|
edit_filter_text = "";
|
|
|
|
edit_filter_text.clear();
|
|
|
|
emit gamelist->GameChosen(file_path);
|
|
|
|
emit gamelist->GameChosen(file_path);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
return QObject::eventFilter(obj, event);
|
|
|
|
return QObject::eventFilter(obj, event);
|
|
|
@@ -96,7 +95,7 @@ void GameListSearchField::setFilterResult(int visible, int total) {
|
|
|
|
result_text = tr("results");
|
|
|
|
result_text = tr("results");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
label_filter_result->setText(
|
|
|
|
label_filter_result->setText(
|
|
|
|
QString("%1 %2 %3 %4").arg(visible).arg(result_of_text).arg(total).arg(result_text));
|
|
|
|
QStringLiteral("%1 %2 %3 %4").arg(visible).arg(result_of_text).arg(total).arg(result_text));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QString GameList::getLastFilterResultItem() const {
|
|
|
|
QString GameList::getLastFilterResultItem() const {
|
|
|
@@ -119,7 +118,7 @@ QString GameList::getLastFilterResultItem() const {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GameListSearchField::clear() {
|
|
|
|
void GameListSearchField::clear() {
|
|
|
|
edit_filter->setText("");
|
|
|
|
edit_filter->clear();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GameListSearchField::setFocus() {
|
|
|
|
void GameListSearchField::setFocus() {
|
|
|
@@ -129,25 +128,26 @@ void GameListSearchField::setFocus() {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
|
|
|
|
GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
|
|
|
|
KeyReleaseEater* keyReleaseEater = new KeyReleaseEater(parent);
|
|
|
|
auto* const key_release_eater = new KeyReleaseEater(parent);
|
|
|
|
layout_filter = new QHBoxLayout;
|
|
|
|
layout_filter = new QHBoxLayout;
|
|
|
|
layout_filter->setMargin(8);
|
|
|
|
layout_filter->setMargin(8);
|
|
|
|
label_filter = new QLabel;
|
|
|
|
label_filter = new QLabel;
|
|
|
|
label_filter->setText(tr("Filter:"));
|
|
|
|
label_filter->setText(tr("Filter:"));
|
|
|
|
edit_filter = new QLineEdit;
|
|
|
|
edit_filter = new QLineEdit;
|
|
|
|
edit_filter->setText("");
|
|
|
|
edit_filter->clear();
|
|
|
|
edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
|
|
|
|
edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
|
|
|
|
edit_filter->installEventFilter(keyReleaseEater);
|
|
|
|
edit_filter->installEventFilter(key_release_eater);
|
|
|
|
edit_filter->setClearButtonEnabled(true);
|
|
|
|
edit_filter->setClearButtonEnabled(true);
|
|
|
|
connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged);
|
|
|
|
connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged);
|
|
|
|
label_filter_result = new QLabel;
|
|
|
|
label_filter_result = new QLabel;
|
|
|
|
button_filter_close = new QToolButton(this);
|
|
|
|
button_filter_close = new QToolButton(this);
|
|
|
|
button_filter_close->setText("X");
|
|
|
|
button_filter_close->setText(QStringLiteral("X"));
|
|
|
|
button_filter_close->setCursor(Qt::ArrowCursor);
|
|
|
|
button_filter_close->setCursor(Qt::ArrowCursor);
|
|
|
|
button_filter_close->setStyleSheet("QToolButton{ border: none; padding: 0px; color: "
|
|
|
|
button_filter_close->setStyleSheet(
|
|
|
|
"#000000; font-weight: bold; background: #F0F0F0; }"
|
|
|
|
QStringLiteral("QToolButton{ border: none; padding: 0px; color: "
|
|
|
|
"QToolButton:hover{ border: none; padding: 0px; color: "
|
|
|
|
"#000000; font-weight: bold; background: #F0F0F0; }"
|
|
|
|
"#EEEEEE; font-weight: bold; background: #E81123}");
|
|
|
|
"QToolButton:hover{ border: none; padding: 0px; color: "
|
|
|
|
|
|
|
|
"#EEEEEE; font-weight: bold; background: #E81123}"));
|
|
|
|
connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked);
|
|
|
|
connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked);
|
|
|
|
layout_filter->setSpacing(10);
|
|
|
|
layout_filter->setSpacing(10);
|
|
|
|
layout_filter->addWidget(label_filter);
|
|
|
|
layout_filter->addWidget(label_filter);
|
|
|
@@ -167,7 +167,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
static bool ContainsAllWords(const QString& haystack, const QString& userinput) {
|
|
|
|
static bool ContainsAllWords(const QString& haystack, const QString& userinput) {
|
|
|
|
const QStringList userinput_split =
|
|
|
|
const QStringList userinput_split =
|
|
|
|
userinput.split(' ', QString::SplitBehavior::SkipEmptyParts);
|
|
|
|
userinput.split(QLatin1Char{' '}, QString::SplitBehavior::SkipEmptyParts);
|
|
|
|
|
|
|
|
|
|
|
|
return std::all_of(userinput_split.begin(), userinput_split.end(),
|
|
|
|
return std::all_of(userinput_split.begin(), userinput_split.end(),
|
|
|
|
[&haystack](const QString& s) { return haystack.contains(s); });
|
|
|
|
[&haystack](const QString& s) { return haystack.contains(s); });
|
|
|
@@ -183,16 +183,16 @@ void GameList::onItemExpanded(const QModelIndex& item) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Event in order to filter the gamelist after editing the searchfield
|
|
|
|
// Event in order to filter the gamelist after editing the searchfield
|
|
|
|
void GameList::onTextChanged(const QString& newText) {
|
|
|
|
void GameList::onTextChanged(const QString& new_text) {
|
|
|
|
const int folderCount = tree_view->model()->rowCount();
|
|
|
|
const int folder_count = tree_view->model()->rowCount();
|
|
|
|
QString edit_filter_text = newText.toLower();
|
|
|
|
QString edit_filter_text = new_text.toLower();
|
|
|
|
QStandardItem* folder;
|
|
|
|
QStandardItem* folder;
|
|
|
|
int children_total = 0;
|
|
|
|
int children_total = 0;
|
|
|
|
|
|
|
|
|
|
|
|
// If the searchfield is empty every item is visible
|
|
|
|
// If the searchfield is empty every item is visible
|
|
|
|
// Otherwise the filter gets applied
|
|
|
|
// Otherwise the filter gets applied
|
|
|
|
if (edit_filter_text.isEmpty()) {
|
|
|
|
if (edit_filter_text.isEmpty()) {
|
|
|
|
for (int i = 0; i < folderCount; ++i) {
|
|
|
|
for (int i = 0; i < folder_count; ++i) {
|
|
|
|
folder = item_model->item(i, 0);
|
|
|
|
folder = item_model->item(i, 0);
|
|
|
|
const QModelIndex folder_index = folder->index();
|
|
|
|
const QModelIndex folder_index = folder->index();
|
|
|
|
const int children_count = folder->rowCount();
|
|
|
|
const int children_count = folder->rowCount();
|
|
|
@@ -204,7 +204,7 @@ void GameList::onTextChanged(const QString& newText) {
|
|
|
|
search_field->setFilterResult(children_total, children_total);
|
|
|
|
search_field->setFilterResult(children_total, children_total);
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
int result_count = 0;
|
|
|
|
int result_count = 0;
|
|
|
|
for (int i = 0; i < folderCount; ++i) {
|
|
|
|
for (int i = 0; i < folder_count; ++i) {
|
|
|
|
folder = item_model->item(i, 0);
|
|
|
|
folder = item_model->item(i, 0);
|
|
|
|
const QModelIndex folder_index = folder->index();
|
|
|
|
const QModelIndex folder_index = folder->index();
|
|
|
|
const int children_count = folder->rowCount();
|
|
|
|
const int children_count = folder->rowCount();
|
|
|
@@ -213,10 +213,9 @@ void GameList::onTextChanged(const QString& newText) {
|
|
|
|
const QStandardItem* child = folder->child(j, 0);
|
|
|
|
const QStandardItem* child = folder->child(j, 0);
|
|
|
|
const QString file_path =
|
|
|
|
const QString file_path =
|
|
|
|
child->data(GameListItemPath::FullPathRole).toString().toLower();
|
|
|
|
child->data(GameListItemPath::FullPathRole).toString().toLower();
|
|
|
|
QString file_name = file_path.mid(file_path.lastIndexOf("/") + 1);
|
|
|
|
|
|
|
|
const QString file_title =
|
|
|
|
const QString file_title =
|
|
|
|
child->data(GameListItemPath::LongTitleRole).toString().toLower();
|
|
|
|
child->data(GameListItemPath::LongTitleRole).toString().toLower();
|
|
|
|
const QString file_programmid =
|
|
|
|
const QString file_program_id =
|
|
|
|
child->data(GameListItemPath::ProgramIdRole).toString().toLower();
|
|
|
|
child->data(GameListItemPath::ProgramIdRole).toString().toLower();
|
|
|
|
|
|
|
|
|
|
|
|
// Only items which filename in combination with its title contains all words
|
|
|
|
// Only items which filename in combination with its title contains all words
|
|
|
@@ -224,8 +223,11 @@ void GameList::onTextChanged(const QString& newText) {
|
|
|
|
// The search is case insensitive because of toLower()
|
|
|
|
// The search is case insensitive because of toLower()
|
|
|
|
// I decided not to use Qt::CaseInsensitive in containsAllWords to prevent
|
|
|
|
// I decided not to use Qt::CaseInsensitive in containsAllWords to prevent
|
|
|
|
// multiple conversions of edit_filter_text for each game in the gamelist
|
|
|
|
// multiple conversions of edit_filter_text for each game in the gamelist
|
|
|
|
if (ContainsAllWords(file_name.append(' ').append(file_title), edit_filter_text) ||
|
|
|
|
const QString file_name =
|
|
|
|
(file_programmid.count() == 16 && edit_filter_text.contains(file_programmid))) {
|
|
|
|
file_path.mid(file_path.lastIndexOf(QLatin1Char{'/'}) + 1) + QLatin1Char{' '} +
|
|
|
|
|
|
|
|
file_title;
|
|
|
|
|
|
|
|
if (ContainsAllWords(file_name, edit_filter_text) ||
|
|
|
|
|
|
|
|
(file_program_id.count() == 16 && edit_filter_text.contains(file_program_id))) {
|
|
|
|
tree_view->setRowHidden(j, folder_index, false);
|
|
|
|
tree_view->setRowHidden(j, folder_index, false);
|
|
|
|
++result_count;
|
|
|
|
++result_count;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
@@ -243,20 +245,23 @@ void GameList::onUpdateThemedIcons() {
|
|
|
|
|
|
|
|
|
|
|
|
switch (child->data(GameListItem::TypeRole).value<GameListItemType>()) {
|
|
|
|
switch (child->data(GameListItem::TypeRole).value<GameListItemType>()) {
|
|
|
|
case GameListItemType::InstalledDir:
|
|
|
|
case GameListItemType::InstalledDir:
|
|
|
|
child->setData(QIcon::fromTheme("sd_card").pixmap(48), Qt::DecorationRole);
|
|
|
|
child->setData(QIcon::fromTheme(QStringLiteral("sd_card")).pixmap(48),
|
|
|
|
|
|
|
|
Qt::DecorationRole);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case GameListItemType::SystemDir:
|
|
|
|
case GameListItemType::SystemDir:
|
|
|
|
child->setData(QIcon::fromTheme("chip").pixmap(48), Qt::DecorationRole);
|
|
|
|
child->setData(QIcon::fromTheme(QStringLiteral("chip")).pixmap(48), Qt::DecorationRole);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
case GameListItemType::CustomDir: {
|
|
|
|
case GameListItemType::CustomDir: {
|
|
|
|
const UISettings::GameDir* game_dir =
|
|
|
|
const UISettings::GameDir* game_dir =
|
|
|
|
child->data(GameListDir::GameDirRole).value<UISettings::GameDir*>();
|
|
|
|
child->data(GameListDir::GameDirRole).value<UISettings::GameDir*>();
|
|
|
|
const QString icon_name = QFileInfo::exists(game_dir->path) ? "folder" : "bad_folder";
|
|
|
|
const QString icon_name = QFileInfo::exists(game_dir->path)
|
|
|
|
|
|
|
|
? QStringLiteral("folder")
|
|
|
|
|
|
|
|
: QStringLiteral("bad_folder");
|
|
|
|
child->setData(QIcon::fromTheme(icon_name).pixmap(48), Qt::DecorationRole);
|
|
|
|
child->setData(QIcon::fromTheme(icon_name).pixmap(48), Qt::DecorationRole);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
case GameListItemType::AddDir:
|
|
|
|
case GameListItemType::AddDir:
|
|
|
|
child->setData(QIcon::fromTheme("plus").pixmap(48), Qt::DecorationRole);
|
|
|
|
child->setData(QIcon::fromTheme(QStringLiteral("plus")).pixmap(48), Qt::DecorationRole);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -286,7 +291,7 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} {
|
|
|
|
tree_view->setSortingEnabled(true);
|
|
|
|
tree_view->setSortingEnabled(true);
|
|
|
|
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
|
|
|
|
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
|
|
|
|
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
|
|
|
|
tree_view->setStyleSheet("QTreeView{ border: none; }");
|
|
|
|
tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
|
|
|
|
|
|
|
|
|
|
|
|
item_model->insertColumns(0, COLUMN_COUNT);
|
|
|
|
item_model->insertColumns(0, COLUMN_COUNT);
|
|
|
|
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
|
|
|
|
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
|
|
|
@@ -561,7 +566,7 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GameList::LoadCompatibilityList() {
|
|
|
|
void GameList::LoadCompatibilityList() {
|
|
|
|
QFile compat_list{":compatibility_list/compatibility_list.json"};
|
|
|
|
QFile compat_list{QStringLiteral(":compatibility_list/compatibility_list.json")};
|
|
|
|
|
|
|
|
|
|
|
|
if (!compat_list.open(QFile::ReadOnly | QFile::Text)) {
|
|
|
|
if (!compat_list.open(QFile::ReadOnly | QFile::Text)) {
|
|
|
|
LOG_ERROR(Frontend, "Unable to open game compatibility list");
|
|
|
|
LOG_ERROR(Frontend, "Unable to open game compatibility list");
|
|
|
@@ -579,25 +584,27 @@ void GameList::LoadCompatibilityList() {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const QString string_content = content;
|
|
|
|
const QJsonDocument json = QJsonDocument::fromJson(content);
|
|
|
|
QJsonDocument json = QJsonDocument::fromJson(string_content.toUtf8());
|
|
|
|
const QJsonArray arr = json.array();
|
|
|
|
QJsonArray arr = json.array();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const QJsonValueRef value : arr) {
|
|
|
|
for (const QJsonValue value : arr) {
|
|
|
|
QJsonObject game = value.toObject();
|
|
|
|
const QJsonObject game = value.toObject();
|
|
|
|
|
|
|
|
const QString compatibility_key = QStringLiteral("compatibility");
|
|
|
|
|
|
|
|
|
|
|
|
if (game.contains("compatibility") && game["compatibility"].isDouble()) {
|
|
|
|
if (!game.contains(compatibility_key) || !game[compatibility_key].isDouble()) {
|
|
|
|
int compatibility = game["compatibility"].toInt();
|
|
|
|
continue;
|
|
|
|
QString directory = game["directory"].toString();
|
|
|
|
}
|
|
|
|
QJsonArray ids = game["releases"].toArray();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (const QJsonValueRef id_ref : ids) {
|
|
|
|
const int compatibility = game[compatibility_key].toInt();
|
|
|
|
QJsonObject id_object = id_ref.toObject();
|
|
|
|
const QString directory = game[QStringLiteral("directory")].toString();
|
|
|
|
QString id = id_object["id"].toString();
|
|
|
|
const QJsonArray ids = game[QStringLiteral("releases")].toArray();
|
|
|
|
compatibility_list.emplace(
|
|
|
|
|
|
|
|
id.toUpper().toStdString(),
|
|
|
|
for (const QJsonValue id_ref : ids) {
|
|
|
|
std::make_pair(QString::number(compatibility), directory));
|
|
|
|
const QJsonObject id_object = id_ref.toObject();
|
|
|
|
}
|
|
|
|
const QString id = id_object[QStringLiteral("id")].toString();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
compatibility_list.emplace(id.toUpper().toStdString(),
|
|
|
|
|
|
|
|
std::make_pair(QString::number(compatibility), directory));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@@ -645,8 +652,9 @@ void GameList::LoadInterfaceLayout() {
|
|
|
|
item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
|
|
|
|
item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const QStringList GameList::supported_file_extensions = {"3ds", "3dsx", "elf", "axf",
|
|
|
|
const QStringList GameList::supported_file_extensions = {
|
|
|
|
"cci", "cxi", "app"};
|
|
|
|
QStringLiteral("3ds"), QStringLiteral("3dsx"), QStringLiteral("elf"), QStringLiteral("axf"),
|
|
|
|
|
|
|
|
QStringLiteral("cci"), QStringLiteral("cxi"), QStringLiteral("app")};
|
|
|
|
|
|
|
|
|
|
|
|
void GameList::RefreshGameDirectory() {
|
|
|
|
void GameList::RefreshGameDirectory() {
|
|
|
|
if (!UISettings::values.game_dirs.isEmpty() && current_worker != nullptr) {
|
|
|
|
if (!UISettings::values.game_dirs.isEmpty() && current_worker != nullptr) {
|
|
|
@@ -670,7 +678,7 @@ QString GameList::FindGameByProgramID(QStandardItem* current_item, u64 program_i
|
|
|
|
return path;
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return "";
|
|
|
|
return QString();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} {
|
|
|
|
GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} {
|
|
|
@@ -681,7 +689,7 @@ GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent}
|
|
|
|
image = new QLabel;
|
|
|
|
image = new QLabel;
|
|
|
|
text = new QLabel;
|
|
|
|
text = new QLabel;
|
|
|
|
layout->setAlignment(Qt::AlignCenter);
|
|
|
|
layout->setAlignment(Qt::AlignCenter);
|
|
|
|
image->setPixmap(QIcon::fromTheme("plus_folder").pixmap(200));
|
|
|
|
image->setPixmap(QIcon::fromTheme(QStringLiteral("plus_folder")).pixmap(200));
|
|
|
|
|
|
|
|
|
|
|
|
text->setText(tr("Double-click to add a new folder to the game list"));
|
|
|
|
text->setText(tr("Double-click to add a new folder to the game list"));
|
|
|
|
QFont font = text->font();
|
|
|
|
QFont font = text->font();
|
|
|
@@ -698,7 +706,7 @@ GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent}
|
|
|
|
GameListPlaceholder::~GameListPlaceholder() = default;
|
|
|
|
GameListPlaceholder::~GameListPlaceholder() = default;
|
|
|
|
|
|
|
|
|
|
|
|
void GameListPlaceholder::onUpdateThemedIcons() {
|
|
|
|
void GameListPlaceholder::onUpdateThemedIcons() {
|
|
|
|
image->setPixmap(QIcon::fromTheme("plus_folder").pixmap(200));
|
|
|
|
image->setPixmap(QIcon::fromTheme(QStringLiteral("plus_folder")).pixmap(200));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void GameListPlaceholder::mouseDoubleClickEvent(QMouseEvent* event) {
|
|
|
|
void GameListPlaceholder::mouseDoubleClickEvent(QMouseEvent* event) {
|
|
|
|