summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorisanae <14251494+isanae@users.noreply.github.com>2019-06-28 14:21:10 -0400
committerisanae <14251494+isanae@users.noreply.github.com>2019-07-02 10:10:20 -0400
commit41292e02bdebea8b09c2c11ee87221672e970cdf (patch)
treeae130b7767feedc07bf0a5790824a9508ba588d1
parentb4c26c516412b2f7270be02494b85be9cad0cadb (diff)
changed how the mod url works:
- it is now independent from the nexus mod url - it can be set in addition to having a valid mod id - both urls can be displayed in the context menu re-arranged some of the widgets on the nexus tab added a track button added a custom url checkbox and open in browser button added a max-width to the browser
-rw-r--r--src/mainwindow.cpp44
-rw-r--r--src/modinfo.cpp19
-rw-r--r--src/modinfo.h29
-rw-r--r--src/modinfodialog.ui341
-rw-r--r--src/modinfodialognexus.cpp147
-rw-r--r--src/modinfodialognexus.h11
-rw-r--r--src/modinforegular.cpp85
-rw-r--r--src/modinforegular.h16
8 files changed, 462 insertions, 230 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index d75e8d9d..d48fae4f 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -3429,18 +3429,16 @@ void MainWindow::visitOnNexus_clicked()
int row_idx;
ModInfo::Ptr info;
QString gameName;
- QString webUrl;
+
for (QModelIndex idx : selection->selectedRows()) {
row_idx = idx.data(Qt::UserRole + 1).toInt();
info = ModInfo::getByIndex(row_idx);
int modID = info->getNexusID();
- webUrl = info->getURL();
gameName = info->getGameName();
if (modID > 0) {
linkClicked(NexusInterface::instance(&m_PluginContainer)->getModURL(modID, gameName));
- }
- else if (webUrl != "") {
- linkClicked(webUrl);
+ } else {
+ qCritical() << "mod '" << info->name() << "' has no nexus id";
}
}
}
@@ -3450,14 +3448,13 @@ void MainWindow::visitOnNexus_clicked()
if (modID > 0) {
linkClicked(NexusInterface::instance(&m_PluginContainer)->getModURL(modID, gameName));
} else {
- MessageDialog::showMessage(tr("Nexus ID for this Mod is unknown"), this);
+ MessageDialog::showMessage(tr("Nexus ID for this mod is unknown"), this);
}
}
}
void MainWindow::visitWebPage_clicked()
{
-
QItemSelectionModel *selection = ui->modList->selectionModel();
if (selection->hasSelection() && selection->selectedRows().count() > 1) {
int count = selection->selectedRows().count();
@@ -3471,28 +3468,22 @@ void MainWindow::visitWebPage_clicked()
int row_idx;
ModInfo::Ptr info;
QString gameName;
- QString webUrl;
for (QModelIndex idx : selection->selectedRows()) {
row_idx = idx.data(Qt::UserRole + 1).toInt();
info = ModInfo::getByIndex(row_idx);
- int modID = info->getNexusID();
- webUrl = info->getURL();
- gameName = info->getGameName();
- if (modID > 0) {
- linkClicked(NexusInterface::instance(&m_PluginContainer)->getModURL(modID, gameName));
- }
- else if (webUrl != "") {
- linkClicked(webUrl);
+
+ const auto url = info->parseCustomURL();
+ if (url.isValid()) {
+ linkClicked(url.toString());
}
}
}
else {
ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow);
- if (info->getURL() != "") {
- linkClicked(info->getURL());
- }
- else {
- MessageDialog::showMessage(tr("Web page for this mod is unknown"), this);
+
+ const auto url = info->parseCustomURL();
+ if (url.isValid()) {
+ linkClicked(url.toString());
}
}
}
@@ -4711,7 +4702,7 @@ void MainWindow::exportModListCSV()
builder.writeHeader();
auto indexesByPriority = m_OrganizerCore.currentProfile()->getAllIndexesByPriority();
- for (auto& iter : indexesByPriority) {
+ for (auto& iter : indexesByPriority) {
ModInfo::Ptr info = ModInfo::getByIndex(iter.second);
bool enabled = m_OrganizerCore.currentProfile()->modEnabled(iter.second);
if ((selectedRowID == 1) && !enabled) {
@@ -4991,8 +4982,13 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos)
if (info->getNexusID() > 0) {
menu.addAction(tr("Visit on Nexus"), this, SLOT(visitOnNexus_clicked()));
- } else if ((info->getURL() != "")) {
- menu.addAction(tr("Visit web page"), this, SLOT(visitWebPage_clicked()));
+ }
+
+ const auto url = info->parseCustomURL();
+ if (url.isValid()) {
+ menu.addAction(
+ tr("Visit on %1").arg(url.host()),
+ this, SLOT(visitWebPage_clicked()));
}
menu.addAction(tr("Open in Explorer"), this, SLOT(openExplorer_clicked()));
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index bc2979ef..585d4963 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -520,3 +520,22 @@ void ModInfo::testValid()
dirIter.next();
}
}
+
+QUrl ModInfo::parseCustomURL() const
+{
+ if (!hasCustomURL() || getCustomURL().isEmpty()) {
+ return {};
+ }
+
+ const auto url = QUrl::fromUserInput(getCustomURL());
+
+ if (!url.isValid()) {
+ qCritical()
+ << "mod '" << name() << "' has an invalid custom url "
+ << "'" << getCustomURL() << "'";
+
+ return {};
+ }
+
+ return url;
+}
diff --git a/src/modinfo.h b/src/modinfo.h
index f1d816fe..e395f45b 100644
--- a/src/modinfo.h
+++ b/src/modinfo.h
@@ -733,14 +733,31 @@ public:
virtual void doConflictCheck() const {}
/**
- * @brief set the URL for a mod
- */
- virtual void setURL(QString const &) {}
+ * @brief sets whether this mod uses a custom url
+ **/
+ virtual void setHasCustomURL(bool) {}
/**
- * @returns the URL for a mod
- */
- virtual QString getURL() const { return ""; }
+ * @brief returns whether this mod uses a custom url
+ **/
+ virtual bool hasCustomURL() const { return false; }
+
+ /**
+ * @brief sets the custom url
+ **/
+ virtual void setCustomURL(QString const &) {}
+
+ /**
+ * @brief returns the custom url
+ **/
+ virtual QString getCustomURL() const { return ""; }
+
+ /**
+ * If hasCustomURL() is true and getCustomURL() is not empty, tries to parse
+ * the url using QUrl::fromUserInput() and returns it. Otherwise, returns an
+ * empty QUrl.
+ **/
+ QUrl parseCustomURL() const;
signals:
diff --git a/src/modinfodialog.ui b/src/modinfodialog.ui
index 4de65e95..78f19a36 100644
--- a/src/modinfodialog.ui
+++ b/src/modinfodialog.ui
@@ -491,7 +491,7 @@ Most mods do not have optional esps, so chances are good you are looking at an e
<item>
<widget class="QTabWidget" name="tabConflictsTabs">
<property name="currentIndex">
- <number>1</number>
+ <number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
@@ -887,138 +887,8 @@ text-align: left;</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
- <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0,0,0,0,0,0,0,0,1">
- <item>
- <widget class="QToolButton" name="refresh">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="toolTip">
- <string>Refresh</string>
- </property>
- <property name="whatsThis">
- <string>Refresh all information from Nexus.</string>
- </property>
- <property name="text">
- <string>Refresh</string>
- </property>
- <property name="icon">
- <iconset resource="resources.qrc">
- <normaloff>:/MO/gui/refresh</normaloff>:/MO/gui/refresh</iconset>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="openInBrowser">
- <property name="text">
- <string>Open in Browser</string>
- </property>
- <property name="icon">
- <iconset resource="resources.qrc">
- <normaloff>:/MO/gui/resources/internet-web-browser.png</normaloff>:/MO/gui/resources/internet-web-browser.png</iconset>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QToolButton" name="endorse">
- <property name="text">
- <string>Endorse</string>
- </property>
- <property name="icon">
- <iconset resource="resources.qrc">
- <normaloff>:/MO/gui/icon_favorite</normaloff>:/MO/gui/icon_favorite</iconset>
- </property>
- <property name="toolButtonStyle">
- <enum>Qt::ToolButtonTextBesideIcon</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_3">
- <property name="text">
- <string>Mod ID</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="ModIDLineEdit" name="modID">
- <property name="toolTip">
- <string>Mod ID for this mod on Nexus.</string>
- </property>
- <property name="whatsThis">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Mod ID for this mod on Nexus. This is filled in automatically if you downloaded and installed the mod from inside MO. Otherwise you can enter it manually. To find the correct id, find the mod on nexus. The URL will look like this: &lt;a href=&quot; https://www.nexusmods.com/skyrimspecialedition/mods/6194&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.nexusmods.com/skyrimspecialedition/mods/6194&lt;/span&gt;&lt;/a&gt;. In this example, 6194 is the id you're looking for. Besides: The above is the link to Mod Organizer 2 on Nexus. Why not go there now and endorse us?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="label_10">
- <property name="text">
- <string>Source Game</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QComboBox" name="sourceGame">
- <property name="toolTip">
- <string>Source game for this mod.</string>
- </property>
- <property name="whatsThis">
- <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Source game for this mod. This determines where the mod was downloaded from and decides where to fetch info, version updates, and send endorsements. Changing this will likely require you to enter a new Mod ID.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="versionLabel">
- <property name="whatsThis">
- <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
-&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
-p, li { white-space: pre-wrap; }
-&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
-&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Installed Version of the Mod. The tooltip will contain the current version available on nexus. The installed version is only set if you installed the mod through MO.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
- </property>
- <property name="text">
- <string>Version</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLineEdit" name="version">
- <property name="maxLength">
- <number>32</number>
- </property>
- </widget>
- </item>
- <item>
- <spacer name="horizontalSpacer_2">
- <property name="orientation">
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" stdset="0">
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QWidget" name="widget_13" native="true">
- <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <widget class="QWidget" name="widget_14" native="true">
+ <layout class="QVBoxLayout" name="verticalLayout_25">
<property name="leftMargin">
<number>0</number>
</property>
@@ -1032,17 +902,169 @@ p, li { white-space: pre-wrap; }
<number>0</number>
</property>
<item>
- <widget class="QLabel" name="label_11">
- <property name="text">
- <string>URL</string>
- </property>
- </widget>
+ <layout class="QHBoxLayout" name="horizontalLayout_6" stretch="0,0,0,0,0,0,1">
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Mod ID</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="ModIDLineEdit" name="modID">
+ <property name="toolTip">
+ <string>Mod ID for this mod on Nexus.</string>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;Mod ID for this mod on Nexus. This is filled in automatically if you downloaded and installed the mod from inside MO. Otherwise you can enter it manually. To find the correct id, find the mod on nexus. The URL will look like this: &lt;a href=&quot; https://www.nexusmods.com/skyrimspecialedition/mods/6194&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#0000ff;&quot;&gt;https://www.nexusmods.com/skyrimspecialedition/mods/6194&lt;/span&gt;&lt;/a&gt;. In this example, 6194 is the id you're looking for. Besides: The above is the link to Mod Organizer 2 on Nexus. Why not go there now and endorse us?&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_10">
+ <property name="text">
+ <string>Source Game</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="sourceGame">
+ <property name="toolTip">
+ <string>Source game for this mod.</string>
+ </property>
+ <property name="whatsThis">
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Source game for this mod. This determines where the mod was downloaded from and decides where to fetch info, version updates, and send endorsements. Changing this will likely require you to enter a new Mod ID.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="versionLabel">
+ <property name="whatsThis">
+ <string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
+&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
+p, li { white-space: pre-wrap; }
+&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-size:8pt;&quot;&gt;Installed Version of the Mod. The tooltip will contain the current version available on nexus. The installed version is only set if you installed the mod through MO.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="text">
+ <string>Version</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="version">
+ <property name="maxLength">
+ <number>32</number>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</item>
<item>
- <widget class="QLineEdit" name="url">
- <property name="readOnly">
- <bool>true</bool>
- </property>
+ <widget class="QWidget" name="widget_15" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_7">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="refresh">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Minimum" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="toolTip">
+ <string>Refresh</string>
+ </property>
+ <property name="whatsThis">
+ <string>Refresh all information from Nexus.</string>
+ </property>
+ <property name="text">
+ <string>Refresh</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/MO/gui/refresh</normaloff>:/MO/gui/refresh</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="visitNexus">
+ <property name="text">
+ <string>Open in Browser</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/MO/gui/resources/internet-web-browser.png</normaloff>:/MO/gui/resources/internet-web-browser.png</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="endorse">
+ <property name="text">
+ <string>Endorse</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/MO/gui/icon_favorite</normaloff>:/MO/gui/icon_favorite</iconset>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="track">
+ <property name="text">
+ <string>Track</string>
+ </property>
+ <property name="icon">
+ <iconset resource="resources.qrc">
+ <normaloff>:/MO/gui/tracked</normaloff>:/MO/gui/tracked</iconset>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_3">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</widget>
</item>
</layout>
@@ -1093,6 +1115,41 @@ p, li { white-space: pre-wrap; }
</layout>
</widget>
</item>
+ <item>
+ <widget class="QWidget" name="widget_13" native="true">
+ <layout class="QHBoxLayout" name="horizontalLayout_5">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QCheckBox" name="hasCustomURL">
+ <property name="text">
+ <string>Use Custom URL</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="customURL"/>
+ </item>
+ <item>
+ <widget class="QPushButton" name="visitCustomURL">
+ <property name="text">
+ <string>Open in Browser</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="tabNotes">
diff --git a/src/modinfodialognexus.cpp b/src/modinfodialognexus.cpp
index e1fbe352..8c8ce55a 100644
--- a/src/modinfodialognexus.cpp
+++ b/src/modinfodialognexus.cpp
@@ -7,6 +7,8 @@
#include <versioninfo.h>
#include <utility.h>
+namespace shell = MOBase::shell;
+
bool isValidModID(int id)
{
return (id > 0);
@@ -22,15 +24,20 @@ NexusTab::NexusTab(
ui->endorse->setVisible(core().settings().endorsementIntegration());
connect(ui->modID, &QLineEdit::editingFinished, [&]{ onModIDChanged(); });
- connect(ui->version, &QLineEdit::editingFinished, [&]{ onVersionChanged(); });
- connect(ui->openInBrowser, &QToolButton::clicked, [&]{ onOpenLink(); });
- connect(ui->endorse, &QToolButton::clicked, [&]{ onEndorse(); });
- connect(ui->refresh, &QToolButton::clicked, [&]{ onRefreshBrowser(); });
-
connect(
ui->sourceGame,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
[&]{ onSourceGameChanged(); });
+ connect(ui->version, &QLineEdit::editingFinished, [&]{ onVersionChanged(); });
+
+ connect(ui->refresh, &QPushButton::clicked, [&]{ onRefreshBrowser(); });
+ connect(ui->visitNexus, &QPushButton::clicked, [&]{ onVisitNexus(); });
+ connect(ui->endorse, &QPushButton::clicked, [&]{ onEndorse(); });
+ connect(ui->track, &QPushButton::clicked, [&]{ onTrack(); });
+
+ connect(ui->hasCustomURL, &QCheckBox::toggled, [&]{ onCustomURLToggled(); });
+ connect(ui->customURL, &QLineEdit::editingFinished, [&]{ onCustomURLChanged(); });
+ connect(ui->visitCustomURL, &QPushButton::clicked, [&]{ onVisitCustomURL(); });
}
NexusTab::~NexusTab()
@@ -52,7 +59,8 @@ void NexusTab::clear()
ui->sourceGame->clear();
ui->version->clear();
ui->browser->setPage(new NexusTabWebpage(ui->browser));
- ui->url->clear();
+ ui->hasCustomURL->setChecked(false);
+ ui->customURL->clear();
setHasData(false);
}
@@ -89,7 +97,7 @@ void NexusTab::update()
connect(
page, &NexusTabWebpage::linkClicked,
- [&](const QUrl& url){ MOBase::shell::OpenLink(url); });
+ [&](const QUrl& url){ shell::OpenLink(url); });
ui->endorse->setEnabled(
(mod()->endorsedState() == ModInfo::ENDORSED_FALSE) ||
@@ -138,15 +146,52 @@ void NexusTab::updateWebpage()
const QString nexusLink = NexusInterface::instance(&plugin())
->getModURL(modID, mod()->getGameName());
- ui->openInBrowser->setToolTip(nexusLink);
- mod()->setURL(nexusLink);
+ ui->visitNexus->setToolTip(nexusLink);
refreshData(modID);
} else {
onModChanged();
}
ui->version->setText(mod()->getVersion().displayString());
- ui->url->setText(mod()->getURL());
+ ui->hasCustomURL->setChecked(mod()->hasCustomURL());
+ ui->customURL->setText(mod()->getCustomURL());
+ ui->customURL->setEnabled(mod()->hasCustomURL());
+ ui->visitCustomURL->setEnabled(mod()->hasCustomURL());
+ ui->visitCustomURL->setToolTip(mod()->parseCustomURL().toString());
+
+ updateTracking();
+}
+
+void NexusTab::updateTracking()
+{
+ if (mod()->trackedState() == ModInfo::TRACKED_TRUE) {
+ ui->track->setChecked(true);
+ ui->track->setText(tr("Tracked"));
+ } else {
+ ui->track->setChecked(false);
+ ui->track->setText(tr("Untracked"));
+ }
+}
+
+void NexusTab::refreshData(int modID)
+{
+ if (tryRefreshData(modID)) {
+ m_requestStarted = true;
+ } else {
+ onModChanged();
+ }
+}
+
+bool NexusTab::tryRefreshData(int modID)
+{
+ if (isValidModID(modID) && !m_requestStarted) {
+ if (mod()->updateNXMInfo()) {
+ ui->browser->setHtml("");
+ return true;
+ }
+ }
+
+ return false;
}
void NexusTab::onModChanged()
@@ -165,6 +210,9 @@ void NexusTab::onModChanged()
font-size: 14px;
background: #404040;
color: #f1f1f1;
+ max-width: 1060px;
+ margin-left: auto;
+ margin-right: auto;
}
a
@@ -178,12 +226,11 @@ void NexusTab::onModChanged()
</html>)";
if (nexusDescription.isEmpty()) {
- descriptionAsHTML = descriptionAsHTML.arg(tr(
- "<div style=\"text-align: center;\">"
- "<h1>Uh oh!</h1>"
- "<p>Sorry, there is no description available for this mod. :(</p>"
- "</div>"));
-
+ descriptionAsHTML = descriptionAsHTML.arg(tr(R"(
+ <div style="text-align: center;">
+ <p>This mod does not have a valid Nexus ID. You can add a custom web
+ page for it in the "Custom URL" box below.</p>
+ </div>)"));
} else {
descriptionAsHTML = descriptionAsHTML.arg(
BBCode::convertToHTML(nexusDescription));
@@ -191,6 +238,7 @@ void NexusTab::onModChanged()
ui->browser->page()->setHtml(descriptionAsHTML);
updateVersionColor();
+ updateTracking();
}
void NexusTab::onModIDChanged()
@@ -241,18 +289,6 @@ void NexusTab::onVersionChanged()
updateVersionColor();
}
-void NexusTab::onOpenLink()
-{
- const int modID = mod()->getNexusID();
-
- if (isValidModID(modID)) {
- const QString nexusLink = NexusInterface::instance(&plugin())
- ->getModURL(modID, mod()->getGameName());
-
- MOBase::shell::OpenLink(QUrl(nexusLink));
- }
-}
-
void NexusTab::onRefreshBrowser()
{
const auto modID = mod()->getNexusID();
@@ -265,28 +301,59 @@ void NexusTab::onRefreshBrowser()
}
}
+void NexusTab::onVisitNexus()
+{
+ const int modID = mod()->getNexusID();
+
+ if (isValidModID(modID)) {
+ const QString nexusLink = NexusInterface::instance(&plugin())
+ ->getModURL(modID, mod()->getGameName());
+
+ shell::OpenLink(QUrl(nexusLink));
+ }
+}
+
void NexusTab::onEndorse()
{
core().loggedInAction(parentWidget(), [m=mod()]{ m->endorse(true); });
}
-void NexusTab::refreshData(int modID)
+void NexusTab::onTrack()
{
- if (tryRefreshData(modID)) {
- m_requestStarted = true;
- } else {
- onModChanged();
+ core().loggedInAction(parentWidget(), [m=mod()] {
+ if (m->trackedState() == ModInfo::TRACKED_TRUE) {
+ m->track(false);
+ } else {
+ m->track(true);
+ }
+ });
+}
+
+void NexusTab::onCustomURLToggled()
+{
+ if (m_loading) {
+ return;
}
+
+ mod()->setHasCustomURL(ui->hasCustomURL->isChecked());
+ ui->customURL->setEnabled(mod()->hasCustomURL());
+ ui->visitCustomURL->setEnabled(mod()->hasCustomURL());
}
-bool NexusTab::tryRefreshData(int modID)
+void NexusTab::onCustomURLChanged()
{
- if (isValidModID(modID) && !m_requestStarted) {
- if (mod()->updateNXMInfo()) {
- ui->browser->setHtml("");
- return true;
- }
+ if (m_loading) {
+ return;
}
- return false;
+ mod()->setCustomURL(ui->customURL->text());
+ ui->visitCustomURL->setToolTip(mod()->parseCustomURL().toString());
+}
+
+void NexusTab::onVisitCustomURL()
+{
+ const auto url = mod()->parseCustomURL();
+ if (url.isValid()) {
+ shell::OpenLink(url);
+ }
}
diff --git a/src/modinfodialognexus.h b/src/modinfodialognexus.h
index 8528f0af..930c1ffc 100644
--- a/src/modinfodialognexus.h
+++ b/src/modinfodialognexus.h
@@ -53,17 +53,24 @@ private:
void cleanup();
void updateVersionColor();
void updateWebpage();
+ void updateTracking();
void refreshData(int modID);
bool tryRefreshData(int modID);
-
void onModChanged();
- void onOpenLink();
+
void onModIDChanged();
void onSourceGameChanged();
void onVersionChanged();
+
void onRefreshBrowser();
+ void onVisitNexus();
void onEndorse();
+ void onTrack();
+
+ void onCustomURLToggled();
+ void onCustomURLChanged();
+ void onVisitCustomURL();
};
#endif // MODINFODIALOGNEXUS_H
diff --git a/src/modinforegular.cpp b/src/modinforegular.cpp
index 4333e351..448447e1 100644
--- a/src/modinforegular.cpp
+++ b/src/modinforegular.cpp
@@ -100,7 +100,70 @@ void ModInfoRegular::readMeta()
m_Repository = metaFile.value("repository", "Nexus").toString();
m_Converted = metaFile.value("converted", false).toBool();
m_Validated = metaFile.value("validated", false).toBool();
- m_URL = metaFile.value("url", "").toString();
+
+ // this handles changes to how the URL works after 2.2.0
+ //
+ // in 2.2.0, "hasCustomUrl" does not exist and "url" is only used when the mod
+ // id is invalid, although it can be set at any time in the mod info dialog
+ //
+ // post 2.2.0, a custom url can be set on any mod, whether the mod id is
+ // valid or not, so an additional flag "hasCustomURL" is required, with a
+ // corresponding checkbox in the mod info dialog
+ //
+ // there are several cases to handle to make sure no data is lost and to
+ // determine whether the user has set a custom url before:
+ //
+ // 1) some mods have an incorrect url set along with a valid mod id;
+ // there is apparently a bug with the fomod installer that can set the
+ // url of a mod to a value used by a _previous_ installation
+ //
+ // 2) it is possible to set the url even if the mod id is valid, in which
+ // case it is saved, but never used in 2.2.0
+ //
+ // 3) opening the mod info dialog on the nexus tab for a mod that has a
+ // valid id will force the url to be the same as what the plugin gives
+ // back
+ //
+ // the algorithm is as follows:
+ // always read the url from the meta file and store it so this piece of data
+ // is never lost; the problem then only becomes about whether to enable
+ // hasCustomURL
+ //
+ // if hasCustomURL is present in the meta file, just read that and be
+ // done with it
+ //
+ // if not, then the flag depends on the mod id and the url
+ // if the mod id is valid, the custom url is disabled; although the url
+ // could be _set_ by the user when a mod id was valid, it was never
+ // _used_, so the behaviour won't change
+ //
+ // if the mod id is invalid, the url should normally be empty, unless the
+ // user specified one, in which case hasCustomURL should be true
+ // (the only case where this fails is if a mod id was valid before and
+ // the user visited the nexus tab, in which case the url was set
+ // automatically, but then the id was manually changed to 0
+ //
+ // in that case, the mod id is invalid and the url is not empty, but it
+ // was never set by the user; this case is impossible to distinguish
+ // from a user manually entering a url, and so is handled as such)
+
+ // always read the url
+ m_CustomURL = metaFile.value("url").toString();
+
+ if (metaFile.contains("hasCustomURL")) {
+ m_HasCustomURL = metaFile.value("hasCustomURL").toBool();
+ } else {
+ if (m_NexusID > 0) {
+ // the mod id is valid, disable the custom url
+ m_HasCustomURL = false;
+ } else {
+ if (!m_CustomURL.isEmpty()) {
+ // the mod id is invalid and the url is not empty, enable it
+ m_HasCustomURL = true;
+ }
+ }
+ }
+
m_LastNexusQuery = QDateTime::fromString(metaFile.value("lastNexusQuery", "").toString(), Qt::ISODate);
m_LastNexusUpdate = QDateTime::fromString(metaFile.value("lastNexusUpdate", "").toString(), Qt::ISODate);
m_NexusLastModified = QDateTime::fromString(metaFile.value("nexusLastModified", QDateTime::currentDateTimeUtc()).toString(), Qt::ISODate);
@@ -166,7 +229,8 @@ void ModInfoRegular::saveMeta()
metaFile.setValue("comments", m_Comments);
metaFile.setValue("notes", m_Notes);
metaFile.setValue("nexusDescription", m_NexusDescription);
- metaFile.setValue("url", m_URL);
+ metaFile.setValue("url", m_CustomURL);
+ metaFile.setValue("hasCustomURL", m_HasCustomURL);
metaFile.setValue("nexusFileStatus", m_NexusFileStatus);
metaFile.setValue("lastNexusQuery", m_LastNexusQuery.toString(Qt::ISODate));
metaFile.setValue("lastNexusUpdate", m_LastNexusUpdate.toString(Qt::ISODate));
@@ -769,18 +833,27 @@ void ModInfoRegular::setNexusLastModified(QDateTime time)
emit modDetailsUpdated(true);
}
-void ModInfoRegular::setURL(QString const &url)
+void ModInfoRegular::setCustomURL(QString const &url)
{
- m_URL = url;
+ m_CustomURL = url;
m_MetaInfoChanged = true;
}
-QString ModInfoRegular::getURL() const
+QString ModInfoRegular::getCustomURL() const
{
- return m_URL;
+ return m_CustomURL;
}
+void ModInfoRegular::setHasCustomURL(bool b)
+{
+ m_HasCustomURL = b;
+ m_MetaInfoChanged = true;
+}
+bool ModInfoRegular::hasCustomURL() const
+{
+ return m_HasCustomURL;
+}
QStringList ModInfoRegular::archives(bool checkOnDisk)
{
diff --git a/src/modinforegular.h b/src/modinforegular.h
index cfe713ca..705e66a8 100644
--- a/src/modinforegular.h
+++ b/src/modinforegular.h
@@ -397,15 +397,10 @@ public:
void readMeta();
- /**
- * @brief set the URL for a mod
- */
- virtual void setURL(QString const &);
-
- /**
- * @returns the URL for a mod
- */
- virtual QString getURL() const;
+ virtual void setHasCustomURL(bool b) override;
+ virtual bool hasCustomURL() const override;
+ virtual void setCustomURL(QString const &) override;
+ virtual QString getCustomURL() const override;
private:
@@ -432,7 +427,8 @@ private:
QString m_Notes;
QString m_NexusDescription;
QString m_Repository;
- QString m_URL;
+ QString m_CustomURL;
+ bool m_HasCustomURL;
QString m_GameName;
mutable QStringList m_Archives;