From e3629c193ad100edde4039868ae809f8fc2aab06 Mon Sep 17 00:00:00 2001 From: LostDragonist Date: Fri, 18 Oct 2019 14:55:33 -0500 Subject: Improve selection of mod ID when querying info The mod ID selection was fairly unreliable when the mod author decided to use certain values in the mod name or filename. A filename of "K-9 - Armor-1-2-3" would automatically set the mod ID to 9 with no chance for the user to correct it. Other filenames would only present 2 choices of mod ID to the user, neither being correct. The primary intent of this change is to present the user with all the numbers found in the filename as options for the mod ID. This should allow the correct mod ID to be easily chosen in all cases. --- src/nexusinterface.cpp | 94 +++++++++++++++++++++++++++----------------------- 1 file changed, 51 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/nexusinterface.cpp b/src/nexusinterface.cpp index 0e2bb45b..12310d4b 100644 --- a/src/nexusinterface.cpp +++ b/src/nexusinterface.cpp @@ -280,52 +280,60 @@ void NexusInterface::setUserAccount(const APIUserAccount& user) void NexusInterface::interpretNexusFileName(const QString &fileName, QString &modName, int &modID, bool query) { - //Look for something along the lines of modulename-Vn-m + any old rubbish. - static std::regex exp(R"exp(^([a-zA-Z0-9_'"\-.() ]*?)([-_ ][VvRr]?[0-9_]+)?-([1-9][0-9]*).*\.(zip|rar|7z))exp"); - static std::regex simpleexp("^([a-zA-Z0-9_]+)"); - - QByteArray fileNameUTF8 = fileName.toUtf8(); - std::cmatch result; - if (std::regex_search(fileNameUTF8.constData(), result, exp)) { - modName = QString::fromUtf8(result[1].str().c_str()); - modName = modName.replace('_', ' ').trimmed(); - - std::string candidate = result[3].str(); - std::string candidate2 = result[2].str(); - if (candidate2.length() != 0 && (candidate2.find_last_of("VvRr") == std::string::npos)) { - // well, that second match might be an id too... - size_t offset = strspn(candidate2.c_str(), "-_ "); - if (offset < candidate2.length() && query) { - SelectionDialog selection(tr("Failed to guess mod id for \"%1\", please pick the correct one").arg(fileName)); - QString r2Highlight(fileName); - r2Highlight.insert(result.position(2) + result.length(2), "* ") - .insert(result.position(2) + static_cast(offset), " *"); - QString r3Highlight(fileName); - r3Highlight.insert(result.position(3) + result.length(3), "* ").insert(result.position(3), " *"); - - selection.addChoice(candidate.c_str(), r3Highlight, static_cast(strtol(candidate.c_str(), nullptr, 10))); - selection.addChoice(candidate2.c_str() + offset, r2Highlight, static_cast(abs(strtol(candidate2.c_str() + offset, nullptr, 10)))); - if (selection.exec() == QDialog::Accepted) { - modID = selection.getChoiceData().toInt(); - } else { - modID = -1; - } - } else { - modID = -1; + // guess the mod name from the file name + static const QRegularExpression complex("^([a-zA-Z0-9_'\"\\-.() ]*?)([-_ ][VvRr]?[0-9_]+)?-([1-9][0-9]*).*\\.(zip|rar|7z)"); + static const QRegularExpression simple("^[a-zA-Z0-9_]+"); + auto complexMatch = complex.match(fileName); + auto simpleMatch = simple.match(fileName); + if (complexMatch.hasMatch()) { + modName = complexMatch.captured(1); + } + else if (simpleMatch.hasMatch()) { + modName = simpleMatch.captured(0); + } + else { + modName.clear(); + } + + if (query) { + SelectionDialog selection(tr("Please pick the mod ID for \"%1\"").arg(fileName)); + int index = 0; + auto splits = fileName.split(QRegExp("[^0-9]"), QString::KeepEmptyParts); + for (auto substr : splits) { + bool ok = false; + int value = substr.toInt(&ok); + if (ok) { + QString highlight(fileName); + highlight.insert(index, " *"); + highlight.insert(index + substr.length() + 2, "* "); + + QStringList choice; + choice << substr; + choice << (index > 0 ? fileName.left(index - 1) : substr); + selection.addChoice(substr, highlight, choice); } - } else { - modID = strtol(candidate.c_str(), nullptr, 10); + index += substr.length() + 1; } - log::debug("mod id guessed: {} -> {}", fileName, modID); - } else if (std::regex_search(fileNameUTF8.constData(), result, simpleexp)) { - log::debug("simple expression matched, using name only"); - modName = QString::fromUtf8(result[1].str().c_str()); - modName = modName.replace('_', ' ').trimmed(); - modID = -1; - } else { - log::debug("no expression matched!"); - modName.clear(); + if (selection.numChoices() > 0) { + if (selection.exec() == QDialog::Accepted) { + auto choice = selection.getChoiceData().toStringList(); + modID = choice.at(0).toInt(); + modName = choice.at(1); + modName = modName.replace('_', ' ').trimmed(); + log::debug("user selected mod ID {} and mod name \"{}\"", modID, modName); + } + else { + log::debug("user canceled mod ID selection"); + modID = -1; + } + } + else { + log::debug("no possible mod IDs found in file name"); + modID = -1; + } + } + else { modID = -1; } } -- cgit v1.3.1