summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/editexecutablesdialog.cpp10
-rw-r--r--src/mainwindow.cpp2
-rw-r--r--src/modinfodialog.ui7
-rw-r--r--src/modinfodialogimages.cpp45
-rw-r--r--src/modinfodialogimages.h3
-rw-r--r--src/nexusinterface.cpp88
-rw-r--r--src/pluginlist.cpp12
-rw-r--r--src/pluginlist.h2
-rw-r--r--src/version.rc4
9 files changed, 113 insertions, 60 deletions
diff --git a/src/editexecutablesdialog.cpp b/src/editexecutablesdialog.cpp
index 3efadc4c..8535b7a7 100644
--- a/src/editexecutablesdialog.cpp
+++ b/src/editexecutablesdialog.cpp
@@ -408,7 +408,7 @@ void EditExecutablesDialog::save()
// get the new title, but ignore it if it's conflicting with an already
// existing executable
- QString newTitle = ui->title->text();
+ QString newTitle = ui->title->text().trimmed();
if (isTitleConflicting(newTitle)) {
newTitle = e->title();
}
@@ -677,7 +677,7 @@ void EditExecutablesDialog::addFromFile()
return;
}
- addNew(Executable(binary.fileName()));
+ addNew(Executable(binary.completeBaseName()));
setBinary(binary);
}
@@ -726,7 +726,7 @@ void EditExecutablesDialog::setBinary(const QFileInfo& binary)
// setting title if some variation of "New Executable"
if (ui->title->text().startsWith(tr("New Executable"), Qt::CaseInsensitive)) {
- const auto prefix = binary.baseName();
+ const auto prefix = binary.completeBaseName();
const auto newTitle = m_executablesList.makeNonConflictingTitle(prefix);
if (newTitle) {
@@ -804,8 +804,8 @@ void EditExecutablesDialog::setJarBinary(const QFileInfo& binary)
if (java.isEmpty()) {
QMessageBox::information(
- this, tr("Java (32-bit) required"),
- tr("MO requires 32-bit java to run this application. If you already "
+ this, tr("Java required"),
+ tr("MO requires Java to run this application. If you already "
"have it installed, select javaw.exe from that installation as "
"the binary."));
}
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 177c2a23..12ed40b3 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -5329,7 +5329,7 @@ void MainWindow::addAsExecutable()
case FileExecutionTypes::Executable: {
QString name = QInputDialog::getText(this, tr("Enter Name"),
tr("Please enter a name for the executable"), QLineEdit::Normal,
- targetInfo.baseName());
+ targetInfo.completeBaseName());
if (!name.isEmpty()) {
//Note: If this already exists, you'll lose custom settings
diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui
index ba2db799..13a245f1 100644
--- a/src/modinfodialog.ui
+++ b/src/modinfodialog.ui
@@ -268,6 +268,13 @@
<number>0</number>
</property>
<item>
+ <widget class="QPushButton" name="previewPluginButton">
+ <property name="text">
+ <string>Open with Preview Plugin</string>
+ </property>
+ </widget>
+ </item>
+ <item>
<widget class="QToolButton" name="imagesExplore">
<property name="text">
<string>Open in Explorer</string>
diff --git a/src/modinfodialogimages.cpp b/src/modinfodialogimages.cpp
index c5b04538..48b3bb3b 100644
--- a/src/modinfodialogimages.cpp
+++ b/src/modinfodialogimages.cpp
@@ -53,6 +53,8 @@ ImagesTab::ImagesTab(ModInfoDialogTabContext cx) :
ui->tabImagesSplitter->setStretchFactor(0, 0);
ui->tabImagesSplitter->setStretchFactor(1, 1);
+ ui->previewPluginButton->setEnabled(false);
+
ui->imagesThumbnails->setTab(this);
ui->imagesScrollerVBar->setTab(this);
@@ -65,6 +67,7 @@ ImagesTab::ImagesTab(ModInfoDialogTabContext cx) :
connect(ui->imagesExplore, &QAbstractButton::clicked, [&]{ onExplore(); });
connect(ui->imagesShowDDS, &QCheckBox::toggled, [&]{ onShowDDS(); });
+ connect(ui->previewPluginButton, &QAbstractButton::clicked, [&] { onPreviewButton(); });
ui->imagesShowDDS->setEnabled(m_ddsAvailable);
@@ -251,13 +254,34 @@ void ImagesTab::select(std::size_t i, Visibility v)
ui->imagesPath->setText(QDir::toNativeSeparators(f->path()));
ui->imagesExplore->setEnabled(true);
+ if (plugin().previewGenerator().previewSupported(QString::fromStdWString(std::filesystem::path(f->path().toStdWString()).extension().wstring()).remove(0,1)))
+ ui->previewPluginButton->setEnabled(true);
+ else
+ ui->previewPluginButton->setEnabled(false);
ui->imagesSize->setText(dimensionString(f->original().size()));
- m_image->setImage(f->original());
+ if (f->original().isNull()) {
+ m_image->clear();
+
+ QImage image(300, 100, QImage::Format_RGBA64);
+ QPainter paint;
+ paint.begin(&image);
+ paint.fillRect(0, 0, 300, 100, QBrush(QColor(0, 0, 0, 255)));
+ paint.setPen(m_theme.textColor);
+ paint.setFont(m_theme.font);
+ paint.drawImage(QPoint(150-16, 50-20-16), QImage(":/MO/gui/warning"));
+ const auto flags = Qt::AlignHCenter | Qt::AlignVCenter | Qt::TextWordWrap;
+ paint.drawText(0, 46, 300, 54, flags, "This image format is not supported by Qt, but the preview plugin may be able to display it. Use the button above.");
+ paint.end();
+
+ m_image->setImage(image);
+ } else
+ m_image->setImage(f->original());
ensureVisible(i, v);
} else {
ui->imagesPath->clear();
ui->imagesExplore->setEnabled(false);
+ ui->previewPluginButton->setEnabled(false);
ui->imagesSize->clear();
m_image->clear();
}
@@ -560,6 +584,11 @@ void ImagesTab::onShowDDS()
}
}
+void ImagesTab::onPreviewButton()
+{
+ core().previewFileWithAlternatives(parentWidget(), m_files.selectedFile()->path());
+}
+
void ImagesTab::onFilterChanged()
{
update();
@@ -958,13 +987,17 @@ void File::load(const Geometry& geo)
ensureOriginalLoaded();
if (m_failed) {
- return;
- }
+ QImage warning(":/MO/gui/warning");
+ const auto scaledSize = geo.scaledImageSize(warning.size());
- const auto scaledSize = geo.scaledImageSize(m_original.size());
+ m_thumbnail = warning.scaled(
+ scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ } else {
+ const auto scaledSize = geo.scaledImageSize(m_original.size());
- m_thumbnail = m_original.scaled(
- scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ m_thumbnail = m_original.scaled(
+ scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ }
}
diff --git a/src/modinfodialogimages.h b/src/modinfodialogimages.h
index 8d9b965b..5717b8b9 100644
--- a/src/modinfodialogimages.h
+++ b/src/modinfodialogimages.h
@@ -4,6 +4,8 @@
#include "modinfodialogtab.h"
#include "filterwidget.h"
#include <QScrollBar>
+#include "plugincontainer.h"
+#include "organizercore.h"
class ImagesTab;
@@ -359,6 +361,7 @@ private:
void showTooltip(QHelpEvent* e);
void onExplore();
void onShowDDS();
+ void onPreviewButton();
void onFilterChanged();
void select(std::size_t i, Visibility v=Visibility::Full);
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_]+)");
+ // 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();
+ }
- 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();
+ 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, "* ");
- 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<int>(offset), " *");
- QString r3Highlight(fileName);
- r3Highlight.insert(result.position(3) + result.length(3), "* ").insert(result.position(3), " *");
+ QStringList choice;
+ choice << substr;
+ choice << (index > 0 ? fileName.left(index - 1) : substr);
+ selection.addChoice(substr, highlight, choice);
+ }
+ index += substr.length() + 1;
+ }
- selection.addChoice(candidate.c_str(), r3Highlight, static_cast<int>(strtol(candidate.c_str(), nullptr, 10)));
- selection.addChoice(candidate2.c_str() + offset, r2Highlight, static_cast<int>(abs(strtol(candidate2.c_str() + offset, nullptr, 10))));
- if (selection.exec() == QDialog::Accepted) {
- modID = selection.getChoiceData().toInt();
- } else {
- modID = -1;
- }
- } else {
+ 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 {
- modID = strtol(candidate.c_str(), nullptr, 10);
}
- 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();
+ else {
+ log::debug("no possible mod IDs found in file name");
+ modID = -1;
+ }
+ }
+ else {
modID = -1;
}
}
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index 5f1ae347..f35f9409 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -170,6 +170,7 @@ void PluginList::refresh(const QString &profileName
ChangeBracket<PluginList> layoutChange(this);
QStringList primaryPlugins = m_GamePlugin->primaryPlugins();
+ bool lightPluginsAreSupported = m_GamePlugin->feature<GamePlugins>()->lightPluginsAreSupported();
m_CurrentProfile = profileName;
@@ -223,7 +224,7 @@ void PluginList::refresh(const QString &profileName
originName = modInfo->name();
}
- m_ESPs.push_back(ESPInfo(filename, forceEnabled, originName, ToQString(current->getFullPath()), hasIni, loadedArchives));
+ m_ESPs.push_back(ESPInfo(filename, forceEnabled, originName, ToQString(current->getFullPath()), hasIni, loadedArchives, lightPluginsAreSupported));
m_ESPs.rbegin()->m_Priority = -1;
} catch (const std::exception &e) {
reportError(tr("failed to update esp info for file %1 (source id: %2), error: %3").arg(filename).arg(current->getOrigin(archive)).arg(e.what()));
@@ -843,6 +844,7 @@ void PluginList::generatePluginIndexes()
{
int numESLs = 0;
int numSkipped = 0;
+ bool lightPluginsSupported = m_GamePlugin->feature<GamePlugins>()->lightPluginsAreSupported();
for (int l = 0; l < m_ESPs.size(); ++l) {
int i = m_ESPsByPriority.at(l);
if (!m_ESPs[i].m_Enabled) {
@@ -850,7 +852,7 @@ void PluginList::generatePluginIndexes()
++numSkipped;
continue;
}
- if (m_ESPs[i].m_IsLight || m_ESPs[i].m_IsLightFlagged) {
+ if (lightPluginsSupported && (m_ESPs[i].m_IsLight || m_ESPs[i].m_IsLightFlagged)) {
int ESLpos = 254 + ((numESLs + 1) / 4096);
m_ESPs[i].m_Index = QString("%1:%2").arg(ESLpos, 2, 16, QChar('0')).arg((numESLs) % 4096, 3, 16, QChar('0')).toUpper();
++numESLs;
@@ -1355,7 +1357,7 @@ bool PluginList::eventFilter(QObject *obj, QEvent *event)
PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled,
const QString &originName, const QString &fullPath,
- bool hasIni, std::set<QString> archives)
+ bool hasIni, std::set<QString> archives, bool lightPluginsAreSupported)
: m_Name(name), m_FullPath(fullPath), m_Enabled(enabled), m_ForceEnabled(enabled),
m_Priority(0), m_LoadOrder(-1), m_OriginName(originName), m_HasIni(hasIni), m_Archives(archives), m_ModSelected(false)
{
@@ -1363,8 +1365,8 @@ PluginList::ESPInfo::ESPInfo(const QString &name, bool enabled,
ESP::File file(ToWString(fullPath));
m_IsMaster = file.isMaster();
auto extension = name.right(3).toLower();
- m_IsLight = (extension == "esl");
- m_IsLightFlagged = file.isLight();
+ m_IsLight = lightPluginsAreSupported && (extension == "esl");
+ m_IsLightFlagged = lightPluginsAreSupported && file.isLight();
m_Author = QString::fromLatin1(file.author().c_str());
m_Description = QString::fromLatin1(file.description().c_str());
diff --git a/src/pluginlist.h b/src/pluginlist.h
index 228ccdec..092ba378 100644
--- a/src/pluginlist.h
+++ b/src/pluginlist.h
@@ -296,7 +296,7 @@ private:
struct ESPInfo {
- ESPInfo(const QString &name, bool enabled, const QString &originName, const QString &fullPath, bool hasIni, std::set<QString> archives);
+ ESPInfo(const QString &name, bool enabled, const QString &originName, const QString &fullPath, bool hasIni, std::set<QString> archives, bool lightSupported);
QString m_Name;
QString m_FullPath;
bool m_Enabled;
diff --git a/src/version.rc b/src/version.rc
index 5a893759..be73324c 100644
--- a/src/version.rc
+++ b/src/version.rc
@@ -3,8 +3,8 @@
// If VS_FF_PRERELEASE is not set, MO labels the build as a release and uses VER_FILEVERSION to determine version number.
// Otherwise, if letters are used in VER_FILEVERSION_STR, uses the full MOBase::VersionInfo parser
// Otherwise, uses the numbers from VER_FILEVERSION and sets the release type as pre-alpha
-#define VER_FILEVERSION 2,2,2,4
-#define VER_FILEVERSION_STR "2.2.2alpha4.1\0"
+#define VER_FILEVERSION 2,2,2,5
+#define VER_FILEVERSION_STR "2.2.2alpha5\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION