diff --git a/es-app/src/FileData.cpp b/es-app/src/FileData.cpp index 75ade3117..e257e47be 100644 --- a/es-app/src/FileData.cpp +++ b/es-app/src/FileData.cpp @@ -90,6 +90,15 @@ const std::string& FileData::getName() const std::string& FileData::getSortName() { + if (mSystem->isCustomCollection() && mType == GAME) { + if (!metadata.get("collectionsortname").empty()) + return metadata.get("collectionsortname"); + else if (!metadata.get("sortname").empty()) + return metadata.get("sortname"); + else + return metadata.get("name"); + } + if (metadata.get("sortname").empty()) return metadata.get("name"); else diff --git a/es-app/src/FileSorts.cpp b/es-app/src/FileSorts.cpp index 916ecd819..c6f18e5b1 100644 --- a/es-app/src/FileSorts.cpp +++ b/es-app/src/FileSorts.cpp @@ -9,6 +9,7 @@ #include "FileSorts.h" +#include "SystemData.h" #include "utils/StringUtil.h" #include @@ -55,8 +56,28 @@ namespace FileSorts { // We compare the actual metadata name, as collection files have the system // appended which messes up the order. - std::string name1 = Utils::String::toUpper(file1->metadata.get("sortname")); - std::string name2 = Utils::String::toUpper(file2->metadata.get("sortname")); + std::string name1; + std::string name2; + + if (file1->getSystem()->isCustomCollection()) { + if (Utils::String::toUpper(file1->metadata.get("collectionsortname")) != "") + name1 = Utils::String::toUpper(file1->metadata.get("collectionsortname")); + else if (Utils::String::toUpper(file1->metadata.get("sortname")) != "") + name1 = Utils::String::toUpper(file1->metadata.get("sortname")); + else + name1 = Utils::String::toUpper(file1->metadata.get("name")); + + if (Utils::String::toUpper(file2->metadata.get("collectionsortname")) != "") + name2 = Utils::String::toUpper(file2->metadata.get("collectionsortname")); + else if (Utils::String::toUpper(file2->metadata.get("sortname")) != "") + name2 = Utils::String::toUpper(file2->metadata.get("sortname")); + else + name2 = Utils::String::toUpper(file2->metadata.get("name")); + return name1.compare(name2) < 0; + } + + name1 = Utils::String::toUpper(file1->metadata.get("sortname")); + name2 = Utils::String::toUpper(file2->metadata.get("sortname")); if (name1.empty()) name1 = Utils::String::toUpper(file1->metadata.get("name")); if (name2.empty()) @@ -66,8 +87,28 @@ namespace FileSorts bool compareNameDescending(const FileData* file1, const FileData* file2) { - std::string name1 = Utils::String::toUpper(file1->metadata.get("sortname")); - std::string name2 = Utils::String::toUpper(file2->metadata.get("sortname")); + std::string name1; + std::string name2; + + if (file1->getSystem()->isCustomCollection()) { + if (Utils::String::toUpper(file1->metadata.get("collectionsortname")) != "") + name1 = Utils::String::toUpper(file1->metadata.get("collectionsortname")); + else if (Utils::String::toUpper(file1->metadata.get("sortname")) != "") + name1 = Utils::String::toUpper(file1->metadata.get("sortname")); + else + name1 = Utils::String::toUpper(file1->metadata.get("name")); + + if (Utils::String::toUpper(file2->metadata.get("collectionsortname")) != "") + name2 = Utils::String::toUpper(file2->metadata.get("collectionsortname")); + else if (Utils::String::toUpper(file2->metadata.get("sortname")) != "") + name2 = Utils::String::toUpper(file2->metadata.get("sortname")); + else + name2 = Utils::String::toUpper(file2->metadata.get("name")); + return name1.compare(name2) > 0; + } + + name1 = Utils::String::toUpper(file1->metadata.get("sortname")); + name2 = Utils::String::toUpper(file2->metadata.get("sortname")); if (name1.empty()) name1 = Utils::String::toUpper(file1->metadata.get("name")); if (name2.empty()) diff --git a/es-app/src/MetaData.cpp b/es-app/src/MetaData.cpp index 7fd5660d3..8dd72a95e 100644 --- a/es-app/src/MetaData.cpp +++ b/es-app/src/MetaData.cpp @@ -20,28 +20,29 @@ namespace // The statistic entries must be placed at the bottom or otherwise there will be problems with // saving the values in GuiMetaDataEd. MetaDataDecl gameDecls[] = { - // key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd, shouldScrape - {"name", MD_STRING, "", false, "name", "enter name", true}, - {"sortname", MD_STRING, "", false, "sortname", "enter sortname", false}, - {"desc", MD_MULTILINE_STRING, "", false, "description", "enter description", true}, - {"rating", MD_RATING, "0", false, "rating", "enter rating", true}, - {"releasedate", MD_DATE, "19700101T000000", false, "release date", "enter release date", true}, - {"developer", MD_STRING, "unknown", false, "developer", "enter developer", true}, - {"publisher", MD_STRING, "unknown", false, "publisher", "enter publisher", true}, - {"genre", MD_STRING, "unknown", false, "genre", "enter genre", true}, - {"players", MD_STRING, "unknown", false, "players", "enter number of players", true}, - {"favorite", MD_BOOL, "false", false, "favorite", "enter favorite off/on", false}, - {"completed", MD_BOOL, "false", false, "completed", "enter completed off/on", false}, - {"kidgame", MD_BOOL, "false", false, "kidgame", "enter kidgame off/on", false}, - {"hidden", MD_BOOL, "false", false, "hidden", "enter hidden off/on", false}, - {"broken", MD_BOOL, "false", false, "broken/not working", "enter broken off/on", false}, - {"nogamecount", MD_BOOL, "false", false, "exclude from game counter", "enter don't count as game off/on", false}, - {"nomultiscrape", MD_BOOL, "false", false, "exclude from multi-scraper", "enter no multi-scrape off/on", false}, - {"hidemetadata", MD_BOOL, "false", false, "hide metadata fields", "enter hide metadata off/on", false}, - {"playcount", MD_INT, "0", false, "times played", "enter number of times played", false}, - {"controller", MD_CONTROLLER, "", false, "controller", "select controller", true}, - {"altemulator", MD_ALT_EMULATOR, "", false, "alternative emulator", "select alternative emulator", false}, - {"lastplayed", MD_TIME, "0", true, "last played", "enter last played date", false} + // key, type, default, statistic, name in GuiMetaDataEd, prompt in GuiMetaDataEd, shouldScrape + {"name", MD_STRING, "", false, "name", "enter name", true}, + {"sortname", MD_STRING, "", false, "sortname", "enter sortname", false}, + {"collectionsortname", MD_STRING, "", false, "custom collections sortname", "enter collections sortname", false}, + {"desc", MD_MULTILINE_STRING, "", false, "description", "enter description", true}, + {"rating", MD_RATING, "0", false, "rating", "enter rating", true}, + {"releasedate", MD_DATE, "19700101T000000", false, "release date", "enter release date", true}, + {"developer", MD_STRING, "unknown", false, "developer", "enter developer", true}, + {"publisher", MD_STRING, "unknown", false, "publisher", "enter publisher", true}, + {"genre", MD_STRING, "unknown", false, "genre", "enter genre", true}, + {"players", MD_STRING, "unknown", false, "players", "enter number of players", true}, + {"favorite", MD_BOOL, "false", false, "favorite", "enter favorite off/on", false}, + {"completed", MD_BOOL, "false", false, "completed", "enter completed off/on", false}, + {"kidgame", MD_BOOL, "false", false, "kidgame", "enter kidgame off/on", false}, + {"hidden", MD_BOOL, "false", false, "hidden", "enter hidden off/on", false}, + {"broken", MD_BOOL, "false", false, "broken/not working", "enter broken off/on", false}, + {"nogamecount", MD_BOOL, "false", false, "exclude from game counter", "enter don't count as game off/on", false}, + {"nomultiscrape", MD_BOOL, "false", false, "exclude from multi-scraper", "enter no multi-scrape off/on", false}, + {"hidemetadata", MD_BOOL, "false", false, "hide metadata fields", "enter hide metadata off/on", false}, + {"playcount", MD_INT, "0", false, "times played", "enter number of times played", false}, + {"controller", MD_CONTROLLER, "", false, "controller", "select controller", true}, + {"altemulator", MD_ALT_EMULATOR, "", false, "alternative emulator", "select alternative emulator", false}, + {"lastplayed", MD_TIME, "0", true, "last played", "enter last played date", false} }; MetaDataDecl folderDecls[] = { diff --git a/es-app/src/guis/GuiMetaDataEd.cpp b/es-app/src/guis/GuiMetaDataEd.cpp index 24cfd0b3f..62790a7b4 100644 --- a/es-app/src/guis/GuiMetaDataEd.cpp +++ b/es-app/src/guis/GuiMetaDataEd.cpp @@ -45,16 +45,21 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, , mBackground{window, ":/graphics/frame.svg"} , mGrid{window, glm::ivec2{2, 6}} , mScraperParams{scraperParams} + , mControllerBadges{BadgeComponent::getGameControllers()} , mMetaDataDecl{mdd} , mMetaData{md} , mSavedCallback{saveCallback} , mClearGameFunc{clearGameFunc} , mDeleteGameFunc{deleteGameFunc} + , mIsCustomCollection{false} , mMediaFilesUpdated{false} , mSavedMediaAndAborted{false} , mInvalidEmulatorEntry{false} { - mControllerBadges = BadgeComponent::getGameControllers(); + if (ViewController::getInstance()->getState().getSystem()->isCustomCollection() || + ViewController::getInstance()->getState().getSystem()->getThemeFolder() == + "custom-collections") + mIsCustomCollection = true; // Remove the last "unknown" controller entry. if (mControllerBadges.size() > 1) @@ -115,6 +120,11 @@ GuiMetaDataEd::GuiMetaDataEd(Window* window, std::string originalValue = mMetaData->get(it->key); std::string gamePath; + // Only display the custom collections sortname entry if we're editing the game + // from within a custom collection. + if (currentKey == "collectionsortname" && !mIsCustomCollection) + continue; + // Don't add statistics. if (it->isStatistic) continue; @@ -619,36 +629,45 @@ void GuiMetaDataEd::save() // We need this to handle the special situation where the user sets a game to hidden while // ShowHiddenGames is set to false, meaning it will immediately disappear from the gamelist. - bool showHiddenGames = Settings::getInstance()->getBool("ShowHiddenGames"); - bool hideGameWhileHidden = false; - bool setGameAsCounted = false; + bool showHiddenGames{Settings::getInstance()->getBool("ShowHiddenGames")}; + bool hideGameWhileHidden{false}; + bool setGameAsCounted{false}; + int offset{0}; for (unsigned int i = 0; i < mEditors.size(); ++i) { - if (mMetaDataDecl.at(i).isStatistic) - continue; - - if (mMetaDataDecl.at(i).key == "altemulator" && mInvalidEmulatorEntry == true) - continue; - - if (mMetaDataDecl.at(i).key == "controller" && mEditors.at(i)->getValue() != "") { - std::string shortName = BadgeComponent::getShortName(mEditors.at(i)->getValue()); - if (shortName != "unknown") - mMetaData->set(mMetaDataDecl.at(i).key, shortName); + // The offset is needed to make the editor and metadata fields match up if we're + // skipping the custom collections sortname field (which we do if not editing the + // game from within a custom collection gamelist). + if (mMetaDataDecl.at(i).key == "collectionsortname" && !mIsCustomCollection) { + offset = 1; continue; } - if (!showHiddenGames && mMetaDataDecl.at(i).key == "hidden" && + if (mMetaDataDecl.at(i + offset).isStatistic) + continue; + + if (mMetaDataDecl.at(i + offset).key == "altemulator" && mInvalidEmulatorEntry == true) + continue; + + if (mMetaDataDecl.at(i + offset).key == "controller" && mEditors.at(i)->getValue() != "") { + std::string shortName = BadgeComponent::getShortName(mEditors.at(i)->getValue()); + if (shortName != "unknown") + mMetaData->set(mMetaDataDecl.at(i + offset).key, shortName); + continue; + } + + if (!showHiddenGames && mMetaDataDecl.at(i + offset).key == "hidden" && mEditors.at(i)->getValue() != mMetaData->get("hidden")) hideGameWhileHidden = true; // Check whether the flag to count the entry as a game was set to enabled. - if (mMetaDataDecl.at(i).key == "nogamecount" && + if (mMetaDataDecl.at(i + offset).key == "nogamecount" && mEditors.at(i)->getValue() != mMetaData->get("nogamecount") && mMetaData->get("nogamecount") == "true") { setGameAsCounted = true; } - mMetaData->set(mMetaDataDecl.at(i).key, mEditors.at(i)->getValue()); + mMetaData->set(mMetaDataDecl.at(i + offset).key, mEditors.at(i)->getValue()); } // If hidden games are not shown and the hide flag was set for the entry, then write the @@ -780,16 +799,27 @@ void GuiMetaDataEd::fetchDone(const ScraperSearchResult& result) void GuiMetaDataEd::close() { // Find out if the user made any changes. - bool metadataUpdated = false; + bool metadataUpdated{false}; + int offset{0}; + for (unsigned int i = 0; i < mEditors.size(); ++i) { - const std::string& key = mMetaDataDecl.at(i).key; - std::string mMetaDataValue = mMetaData->get(key); - std::string mEditorsValue = mEditors.at(i)->getValue(); + const std::string& key{mMetaDataDecl.at(i + offset).key}; + // The offset is needed to make the editor and metadata fields match up if we're + // skipping the custom collections sortname field (which we do if not editing the + // game from within a custom collection gamelist). + if (key == "collectionsortname" && !mIsCustomCollection) { + offset = 1; + ++i; + continue; + } if (key == "altemulator" && mInvalidEmulatorEntry == true) continue; - if (mMetaDataDecl.at(i).key == "controller" && mEditors.at(i)->getValue() != "") { + std::string mMetaDataValue{mMetaData->get(key)}; + std::string mEditorsValue{mEditors.at(i)->getValue()}; + + if (key == "controller" && mEditors.at(i)->getValue() != "") { std::string shortName = BadgeComponent::getShortName(mEditors.at(i)->getValue()); if (shortName == "unknown" || mMetaDataValue == shortName) continue; diff --git a/es-app/src/guis/GuiMetaDataEd.h b/es-app/src/guis/GuiMetaDataEd.h index fd932858e..90ed9c3bb 100644 --- a/es-app/src/guis/GuiMetaDataEd.h +++ b/es-app/src/guis/GuiMetaDataEd.h @@ -69,6 +69,7 @@ private: std::function mClearGameFunc; std::function mDeleteGameFunc; + bool mIsCustomCollection; bool mMediaFilesUpdated; bool mSavedMediaAndAborted; bool mInvalidEmulatorEntry;