From 9c1535621a4a469c5548ce2b12f2259583ba25b7 Mon Sep 17 00:00:00 2001 From: FearlessTobi Date: Sat, 9 Nov 2019 02:46:23 +0100 Subject: [PATCH] citra_qt/game_list: Specify string conversions explicitly --- src/citra_qt/game_list.cpp | 112 ++++++++++++++++-------------- src/citra_qt/game_list.h | 2 +- src/citra_qt/game_list_p.h | 14 ++-- src/citra_qt/game_list_worker.cpp | 6 +- 4 files changed, 71 insertions(+), 63 deletions(-) diff --git a/src/citra_qt/game_list.cpp b/src/citra_qt/game_list.cpp index 933077a7e..f8fc341be 100644 --- a/src/citra_qt/game_list.cpp +++ b/src/citra_qt/game_list.cpp @@ -27,7 +27,6 @@ #include "citra_qt/game_list_worker.h" #include "citra_qt/main.h" #include "citra_qt/uisettings.h" -#include "common/common_paths.h" #include "common/logging/log.h" #include "core/file_sys/archive_extsavedata.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); } else { gamelist->search_field->edit_filter->clear(); - edit_filter_text = ""; + edit_filter_text.clear(); } break; } @@ -67,9 +66,9 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve QString file_path = gamelist->getLastFilterResultItem(); // To avoid loading error dialog loops while confirming them using enter - // Also users usually want to run a diffrent game after closing one - gamelist->search_field->edit_filter->setText(""); - edit_filter_text = ""; + // Also users usually want to run a different game after closing one + gamelist->search_field->edit_filter->clear(); + edit_filter_text.clear(); emit gamelist->GameChosen(file_path); } else { return QObject::eventFilter(obj, event); @@ -96,7 +95,7 @@ void GameListSearchField::setFilterResult(int visible, int total) { result_text = tr("results"); } 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 { @@ -119,7 +118,7 @@ QString GameList::getLastFilterResultItem() const { } void GameListSearchField::clear() { - edit_filter->setText(""); + edit_filter->clear(); } void GameListSearchField::setFocus() { @@ -129,25 +128,26 @@ void GameListSearchField::setFocus() { } 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->setMargin(8); label_filter = new QLabel; label_filter->setText(tr("Filter:")); edit_filter = new QLineEdit; - edit_filter->setText(""); + edit_filter->clear(); edit_filter->setPlaceholderText(tr("Enter pattern to filter")); - edit_filter->installEventFilter(keyReleaseEater); + edit_filter->installEventFilter(key_release_eater); edit_filter->setClearButtonEnabled(true); connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged); label_filter_result = new QLabel; 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->setStyleSheet("QToolButton{ border: none; padding: 0px; color: " - "#000000; font-weight: bold; background: #F0F0F0; }" - "QToolButton:hover{ border: none; padding: 0px; color: " - "#EEEEEE; font-weight: bold; background: #E81123}"); + button_filter_close->setStyleSheet( + QStringLiteral("QToolButton{ border: none; padding: 0px; color: " + "#000000; font-weight: bold; background: #F0F0F0; }" + "QToolButton:hover{ border: none; padding: 0px; color: " + "#EEEEEE; font-weight: bold; background: #E81123}")); connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked); layout_filter->setSpacing(10); layout_filter->addWidget(label_filter); @@ -167,7 +167,7 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} { */ static bool ContainsAllWords(const QString& haystack, const QString& userinput) { 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(), [&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 -void GameList::onTextChanged(const QString& newText) { - const int folderCount = tree_view->model()->rowCount(); - QString edit_filter_text = newText.toLower(); +void GameList::onTextChanged(const QString& new_text) { + const int folder_count = tree_view->model()->rowCount(); + QString edit_filter_text = new_text.toLower(); QStandardItem* folder; int children_total = 0; // If the searchfield is empty every item is visible // Otherwise the filter gets applied 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); const QModelIndex folder_index = folder->index(); const int children_count = folder->rowCount(); @@ -204,7 +204,7 @@ void GameList::onTextChanged(const QString& newText) { search_field->setFilterResult(children_total, children_total); } else { 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); const QModelIndex folder_index = folder->index(); const int children_count = folder->rowCount(); @@ -213,10 +213,9 @@ void GameList::onTextChanged(const QString& newText) { const QStandardItem* child = folder->child(j, 0); const QString file_path = child->data(GameListItemPath::FullPathRole).toString().toLower(); - QString file_name = file_path.mid(file_path.lastIndexOf("/") + 1); const QString file_title = child->data(GameListItemPath::LongTitleRole).toString().toLower(); - const QString file_programmid = + const QString file_program_id = child->data(GameListItemPath::ProgramIdRole).toString().toLower(); // 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() // I decided not to use Qt::CaseInsensitive in containsAllWords to prevent // multiple conversions of edit_filter_text for each game in the gamelist - if (ContainsAllWords(file_name.append(' ').append(file_title), edit_filter_text) || - (file_programmid.count() == 16 && edit_filter_text.contains(file_programmid))) { + const QString file_name = + 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); ++result_count; } else { @@ -243,20 +245,23 @@ void GameList::onUpdateThemedIcons() { switch (child->data(GameListItem::TypeRole).value()) { 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; case GameListItemType::SystemDir: - child->setData(QIcon::fromTheme("chip").pixmap(48), Qt::DecorationRole); + child->setData(QIcon::fromTheme(QStringLiteral("chip")).pixmap(48), Qt::DecorationRole); break; case GameListItemType::CustomDir: { const UISettings::GameDir* game_dir = child->data(GameListDir::GameDirRole).value(); - 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); break; } case GameListItemType::AddDir: - child->setData(QIcon::fromTheme("plus").pixmap(48), Qt::DecorationRole); + child->setData(QIcon::fromTheme(QStringLiteral("plus")).pixmap(48), Qt::DecorationRole); break; } } @@ -286,7 +291,7 @@ GameList::GameList(GMainWindow* parent) : QWidget{parent} { tree_view->setSortingEnabled(true); tree_view->setEditTriggers(QHeaderView::NoEditTriggers); 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->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name")); @@ -561,7 +566,7 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) { } 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)) { LOG_ERROR(Frontend, "Unable to open game compatibility list"); @@ -579,25 +584,27 @@ void GameList::LoadCompatibilityList() { return; } - const QString string_content = content; - QJsonDocument json = QJsonDocument::fromJson(string_content.toUtf8()); - QJsonArray arr = json.array(); + const QJsonDocument json = QJsonDocument::fromJson(content); + const QJsonArray arr = json.array(); - for (const QJsonValueRef value : arr) { - QJsonObject game = value.toObject(); + for (const QJsonValue value : arr) { + const QJsonObject game = value.toObject(); + const QString compatibility_key = QStringLiteral("compatibility"); - if (game.contains("compatibility") && game["compatibility"].isDouble()) { - int compatibility = game["compatibility"].toInt(); - QString directory = game["directory"].toString(); - QJsonArray ids = game["releases"].toArray(); + if (!game.contains(compatibility_key) || !game[compatibility_key].isDouble()) { + continue; + } - for (const QJsonValueRef id_ref : ids) { - QJsonObject id_object = id_ref.toObject(); - QString id = id_object["id"].toString(); - compatibility_list.emplace( - id.toUpper().toStdString(), - std::make_pair(QString::number(compatibility), directory)); - } + const int compatibility = game[compatibility_key].toInt(); + const QString directory = game[QStringLiteral("directory")].toString(); + const QJsonArray ids = game[QStringLiteral("releases")].toArray(); + + for (const QJsonValue id_ref : ids) { + 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()); } -const QStringList GameList::supported_file_extensions = {"3ds", "3dsx", "elf", "axf", - "cci", "cxi", "app"}; +const QStringList GameList::supported_file_extensions = { + QStringLiteral("3ds"), QStringLiteral("3dsx"), QStringLiteral("elf"), QStringLiteral("axf"), + QStringLiteral("cci"), QStringLiteral("cxi"), QStringLiteral("app")}; void GameList::RefreshGameDirectory() { 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 ""; + return QString(); } GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} { @@ -681,7 +689,7 @@ GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} image = new QLabel; text = new QLabel; 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")); QFont font = text->font(); @@ -698,7 +706,7 @@ GameListPlaceholder::GameListPlaceholder(GMainWindow* parent) : QWidget{parent} GameListPlaceholder::~GameListPlaceholder() = default; 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) { diff --git a/src/citra_qt/game_list.h b/src/citra_qt/game_list.h index bef23f31b..b6ed72eae 100644 --- a/src/citra_qt/game_list.h +++ b/src/citra_qt/game_list.h @@ -81,7 +81,7 @@ signals: private slots: void onItemExpanded(const QModelIndex& item); - void onTextChanged(const QString& newText); + void onTextChanged(const QString& new_text); void onFilterCloseClicked(); void onUpdateThemedIcons(); diff --git a/src/citra_qt/game_list_p.h b/src/citra_qt/game_list_p.h index fb64c34c0..63bdb887a 100644 --- a/src/citra_qt/game_list_p.h +++ b/src/citra_qt/game_list_p.h @@ -244,13 +244,13 @@ public: }; // clang-format off static const std::map status_data = { - {"0", {"#5c93ed", QT_TR_NOOP("Perfect"), QT_TR_NOOP("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.")}}, - {"1", {"#47d35c", QT_TR_NOOP("Great"), QT_TR_NOOP("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.")}}, - {"2", {"#94b242", QT_TR_NOOP("Okay"), QT_TR_NOOP("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.")}}, - {"3", {"#f2d624", QT_TR_NOOP("Bad"), QT_TR_NOOP("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.")}}, - {"4", {"#ff0000", QT_TR_NOOP("Intro/Menu"), QT_TR_NOOP("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.")}}, - {"5", {"#828282", QT_TR_NOOP("Won't Boot"), QT_TR_NOOP("The game crashes when attempting to startup.")}}, - {"99", {"#000000", QT_TR_NOOP("Not Tested"), QT_TR_NOOP("The game has not yet been tested.")}}}; + {QStringLiteral("0"), {QStringLiteral("#5c93ed"), QT_TR_NOOP("Perfect"), QT_TR_NOOP("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.")}}, + {QStringLiteral("1"), {QStringLiteral("#47d35c"), QT_TR_NOOP("Great"), QT_TR_NOOP("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.")}}, + {QStringLiteral("2"), {QStringLiteral("#94b242"), QT_TR_NOOP("Okay"), QT_TR_NOOP("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.")}}, + {QStringLiteral("3"), {QStringLiteral("#f2d624"), QT_TR_NOOP("Bad"), QT_TR_NOOP("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.")}}, + {QStringLiteral("4"), {QStringLiteral("#ff0000"), QT_TR_NOOP("Intro/Menu"), QT_TR_NOOP("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.")}}, + {QStringLiteral("5"), {QStringLiteral("#828282"), QT_TR_NOOP("Won't Boot"), QT_TR_NOOP("The game crashes when attempting to startup.")}}, + {QStringLiteral("99"), {QStringLiteral("#000000"), QT_TR_NOOP("Not Tested"), QT_TR_NOOP("The game has not yet been tested.")}}}; // clang-format on auto iterator = status_data.find(compatibility); diff --git a/src/citra_qt/game_list_worker.cpp b/src/citra_qt/game_list_worker.cpp index 13ba8c676..d0a3ab2ab 100644 --- a/src/citra_qt/game_list_worker.cpp +++ b/src/citra_qt/game_list_worker.cpp @@ -91,7 +91,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id); // The game list uses this as compatibility number for untested games - QString compatibility("99"); + QString compatibility(QStringLiteral("99")); if (it != compatibility_list.end()) compatibility = it->second.first; @@ -121,7 +121,7 @@ void GameListWorker::AddFstEntriesToGameList(const std::string& dir_path, unsign void GameListWorker::run() { stop_processing = false; for (UISettings::GameDir& game_dir : game_dirs) { - if (game_dir.path == "INSTALLED") { + if (game_dir.path == QStringLiteral("INSTALLED")) { QString games_path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)) + "Nintendo " @@ -138,7 +138,7 @@ void GameListWorker::run() { emit DirEntryReady({game_list_dir}); AddFstEntriesToGameList(games_path.toStdString(), 2, game_list_dir); AddFstEntriesToGameList(demos_path.toStdString(), 2, game_list_dir); - } else if (game_dir.path == "SYSTEM") { + } else if (game_dir.path == QStringLiteral("SYSTEM")) { QString path = QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)) + "00000000000000000000000000000000/title/00040010";