summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/installationmanager.cpp2
-rw-r--r--src/main.cpp19
-rw-r--r--src/mainwindow.cpp75
-rw-r--r--src/mainwindow.h3
-rw-r--r--src/modlist.cpp15
-rw-r--r--src/organizer.pro9
-rw-r--r--src/problemsdialog.cpp58
-rw-r--r--src/problemsdialog.h35
-rw-r--r--src/problemsdialog.ui104
-rw-r--r--src/resources.qrc3
10 files changed, 293 insertions, 30 deletions
diff --git a/src/installationmanager.cpp b/src/installationmanager.cpp
index 1abb19da..63945150 100644
--- a/src/installationmanager.cpp
+++ b/src/installationmanager.cpp
@@ -18,9 +18,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
#include "installationmanager.h"
-
#include "utility.h"
-
#include "report.h"
#include "categories.h"
#include "questionboxmemory.h"
diff --git a/src/main.cpp b/src/main.cpp
index 268bb98f..ab740467 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -64,6 +64,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QDesktopServices>
#include <eh.h>
#include <windows_error.h>
+#include <boost/scoped_array.hpp>
#pragma comment(linker, "/manifestDependency:\"name='dlls' processorArchitecture='x86' version='1.0.0.0' type='win32' \"")
@@ -284,6 +285,24 @@ int main(int argc, char *argv[])
QSplashScreen splash(pixmap);
splash.show();
+ { // extend path to include dll directory so plugins don't need a manifest
+ static const int BUFSIZE = 4096;
+
+ boost::scoped_array<TCHAR> oldPath(new TCHAR[BUFSIZE]);
+ DWORD offset = ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), BUFSIZE);
+ if (offset > BUFSIZE) {
+ oldPath.reset(new TCHAR[offset]);
+ ::GetEnvironmentVariable(TEXT("PATH"), oldPath.get(), offset);
+ }
+
+ std::tstring newPath(oldPath.get());
+ newPath += TEXT(";");
+ newPath += ToWString(QDir::toNativeSeparators(QCoreApplication::applicationDirPath())).c_str();
+ newPath += TEXT("\\dlls");
+
+ ::SetEnvironmentVariable(TEXT("PATH"), newPath.c_str());
+ }
+
registerMetaTypes();
QStringList arguments = application.arguments();
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 6b546d4d..2fd47537 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -54,9 +54,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "csvbuilder.h"
#include "gameinfoimpl.h"
#include "savetextasdialog.h"
+#include "problemsdialog.h"
#include <gameinfo.h>
#include <appconfig.h>
#include <utility.h>
+#include <ipluginproxy.h>
#include <map>
#include <ctime>
#include <QTime>
@@ -84,14 +86,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QPluginLoader>
#include <QRadioButton>
#include <QDesktopWidget>
+#include <QtPlugin>
#include <QIdentityProxyModel>
#include <boost/bind.hpp>
#include <boost/foreach.hpp>
#include <Psapi.h>
#include <shlobj.h>
#include <TlHelp32.h>
-
-
#include <QNetworkInterface>
@@ -394,8 +395,7 @@ void MainWindow::updateToolBar()
void MainWindow::updateProblemsButton()
{
- QString problemDescription;
- if (checkForProblems(problemDescription)) {
+ if (checkForProblems()) {
ui->actionProblems->setEnabled(true);
ui->actionProblems->setIconText(tr("Problems"));
ui->actionProblems->setToolTip(tr("There are potential problems with your setup"));
@@ -436,17 +436,19 @@ bool MainWindow::errorReported(QString &logFile)
}
-bool MainWindow::checkForProblems(QString &problemDescription)
+bool MainWindow::checkForProblems()
{
- problemDescription = "";
+// problemDescription = "";
foreach (IPluginDiagnose *diagnose, m_DiagnosisPlugins) {
std::vector<unsigned int> activeProblems = diagnose->activeProblems();
- foreach (unsigned int key, activeProblems) {
- problemDescription.append(tr("<li>%1</li>").arg(diagnose->shortDescription(key)));
+ if (activeProblems.size() > 0) {
+ return true;
}
}
+ return false;
+/*
QString NCCBinary = QCoreApplication::applicationDirPath().mid(0).append("/NCC/NexusClientCLI.exe");
if (!QFile::exists(NCCBinary)) {
problemDescription.append(tr("<li>NCC not installed. You won't be able to install some scripted mod-installers. Get NCC from <a href=\"http://skyrim.nexusmods.com/downloads/file.php?id=1334\">the MO page on nexus</a></li>"));
@@ -479,7 +481,7 @@ bool MainWindow::checkForProblems(QString &problemDescription)
} else {
ui->actionProblems->setToolTip(tr("Everything seems to be in order"));
}
- return res;
+ return res;*/
}
@@ -886,6 +888,8 @@ void MainWindow::toolPluginInvoke()
plugin->display();
} catch (const std::exception &e) {
reportError(tr("Plugin \"%1\" failed: %2").arg(plugin->name()).arg(e.what()));
+ } catch (...) {
+ reportError(tr("Plugin \"%1\" failed").arg(plugin->name()));
}
}
@@ -912,13 +916,15 @@ bool MainWindow::registerPlugin(QObject *plugin)
m_Settings.registerPlugin(pluginObj);
}
+ bool addon = false;
+
{ // diagnosis plugins
IPluginDiagnose *diagnose = qobject_cast<IPluginDiagnose*>(plugin);
if (diagnose != NULL) {
m_DiagnosisPlugins.push_back(diagnose);
+ addon = true;
}
}
-
{ // tool plugins
IPluginTool *tool = qobject_cast<IPluginTool*>(plugin);
if (verifyPlugin(tool)) {
@@ -934,7 +940,25 @@ bool MainWindow::registerPlugin(QObject *plugin)
return true;
}
}
- return false;
+ { // proxy plugins
+ IPluginProxy *proxy = qobject_cast<IPluginProxy*>(plugin);
+ if (verifyPlugin(proxy)) {
+ QStringList pluginNames = proxy->pluginList(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath()));
+ foreach (const QString &pluginName, pluginNames) {
+ QObject *proxiedPlugin = proxy->instantiate(pluginName);
+ if (proxiedPlugin != NULL) {
+ if (registerPlugin(proxiedPlugin)) {
+ qDebug("loaded plugin \"%s\"", pluginName.toUtf8().constData());
+ } else {
+ qWarning("plugin \"%s\" failed to load", pluginName.toUtf8().constData());
+ }
+ }
+ }
+ return true;
+ }
+ }
+
+ return addon;
}
@@ -978,12 +1002,20 @@ IGameInfo &MainWindow::gameInfo() const
QString MainWindow::profileName() const
{
- return m_CurrentProfile->getName();
+ if (m_CurrentProfile != NULL) {
+ return m_CurrentProfile->getName();
+ } else {
+ return "";
+ }
}
QString MainWindow::profilePath() const
{
- return m_CurrentProfile->getPath();
+ if (m_CurrentProfile != NULL) {
+ return m_CurrentProfile->getPath();
+ } else {
+ return "";
+ }
}
QString MainWindow::downloadsPath() const
@@ -1045,6 +1077,12 @@ QVariant MainWindow::pluginSetting(const QString &pluginName, const QString &key
return m_Settings.pluginSetting(pluginName, key);
}
+QString MainWindow::pluginDataPath() const
+{
+ QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath());
+ return pluginPath + "/data";
+}
+
void MainWindow::startSteam()
{
@@ -4058,11 +4096,16 @@ void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int)
m_CheckBSATimer.start(500);
}
+
void MainWindow::on_actionProblems_triggered()
{
- QString problemDescription;
- checkForProblems(problemDescription);
- QMessageBox::information(this, tr("Problems"), problemDescription);
+// QString problemDescription;
+// checkForProblems(problemDescription);
+// QMessageBox::information(this, tr("Problems"), problemDescription);
+ ProblemsDialog problems(m_DiagnosisPlugins, this);
+ if (problems.hasProblems()) {
+ problems.exec();
+ }
}
void MainWindow::setCategoryListVisible(bool visible)
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 5880fcb8..e50a8c23 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -103,6 +103,7 @@ public:
virtual bool removeMod(MOBase::IModInterface *mod);
virtual void modDataChanged(MOBase::IModInterface *mod);
virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const;
+ virtual QString pluginDataPath() const;
void addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info);
@@ -205,7 +206,7 @@ private:
bool extractProgress(QProgressDialog &extractProgress, int percentage, std::string fileName);
- bool checkForProblems(QString &problemDescription);
+ bool checkForProblems();
int getBinaryExecuteInfo(const QFileInfo &targetInfo, QFileInfo &binaryInfo, QString &arguments);
QTreeWidgetItem *addFilterItem(QTreeWidgetItem *root, const QString &name, int categoryID);
diff --git a/src/modlist.cpp b/src/modlist.cpp
index f186ce8e..2183ce09 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -20,12 +20,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modlist.h"
#include "report.h"
-#include "utility.h"
#include "messagedialog.h"
#include "installationtester.h"
#include "qtgroupingproxy.h"
#include <gameinfo.h>
-
+#include <utility.h>
#include <QFileInfo>
#include <QDir>
#include <QDirIterator>
@@ -301,19 +300,25 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
bool ModList::renameMod(int index, const QString &newName)
{
+ QString nameFixed = newName;
+ if (!fixDirectoryName(nameFixed) || nameFixed.isEmpty()) {
+ MessageDialog::showMessage(tr("Invalid name"), NULL);
+ return false;
+ }
+
// before we rename, write back the current profile so we don't lose changes and to ensure
// there is no scheduled asynchronous rewrite anytime soon
m_Profile->writeModlistNow();
ModInfo::Ptr modInfo = ModInfo::getByIndex(index);
QString oldName = modInfo->name();
- modInfo->setName(newName);
+ modInfo->setName(nameFixed);
// this just broke all profiles! The recipient of modRenamed has to do some magic
// to can't write the currently active profile back
- emit modRenamed(oldName, newName);
+ emit modRenamed(oldName, nameFixed);
// invalidate the currently displayed state of this list
-// notifyChange(-1);
+ notifyChange(-1);
return true;
}
diff --git a/src/organizer.pro b/src/organizer.pro
index 582ba633..cfdf990b 100644
--- a/src/organizer.pro
+++ b/src/organizer.pro
@@ -78,7 +78,8 @@ SOURCES += \
csvbuilder.cpp \
savetextasdialog.cpp \
qtgroupingproxy.cpp \
- modlistview.cpp
+ modlistview.cpp \
+ problemsdialog.cpp
HEADERS += \
transfersavesdialog.h \
@@ -144,7 +145,8 @@ HEADERS += \
csvbuilder.h \
savetextasdialog.h \
qtgroupingproxy.h \
- modlistview.h
+ modlistview.h \
+ problemsdialog.h
FORMS += \
transfersavesdialog.ui \
@@ -174,7 +176,8 @@ FORMS += \
baincomplexinstallerdialog.ui \
activatemodsdialog.ui \
profileinputdialog.ui \
- savetextasdialog.ui
+ savetextasdialog.ui \
+ problemsdialog.ui
INCLUDEPATH += ../shared ../archive ../uibase ../bsatk "$(BOOSTPATH)"
diff --git a/src/problemsdialog.cpp b/src/problemsdialog.cpp
new file mode 100644
index 00000000..e0837f45
--- /dev/null
+++ b/src/problemsdialog.cpp
@@ -0,0 +1,58 @@
+#include "problemsdialog.h"
+#include "ui_problemsdialog.h"
+#include <utility.h>
+#include <iplugindiagnose.h>
+#include <QPushButton>
+#include <Shellapi.h>
+
+
+using namespace MOBase;
+
+
+ProblemsDialog::ProblemsDialog(std::vector<MOBase::IPluginDiagnose *> diagnosePlugins, QWidget *parent)
+ : QDialog(parent), ui(new Ui::ProblemsDialog)
+{
+ ui->setupUi(this);
+
+ foreach (IPluginDiagnose *diagnose, diagnosePlugins) {
+ std::vector<unsigned int> activeProblems = diagnose->activeProblems();
+ foreach (unsigned int key, activeProblems) {
+ QTreeWidgetItem *newItem = new QTreeWidgetItem();
+ newItem->setText(0, diagnose->shortDescription(key));
+ newItem->setData(0, Qt::UserRole, diagnose->fullDescription(key));
+
+ if (diagnose->hasGuidedFix(key)) {
+ ui->problemsWidget->setItemWidget(newItem, 1, new QPushButton(tr("Fix")));
+ } else {
+ newItem->setText(1, tr("No guided fix :("));
+ }
+ ui->problemsWidget->addTopLevelItem(newItem);
+ }
+ }
+ connect(ui->problemsWidget, SIGNAL(itemSelectionChanged()), this, SLOT(selectionChanged()));
+ connect(ui->descriptionText, SIGNAL(anchorClicked(QUrl)), this, SLOT(urlClicked(QUrl)));
+}
+
+
+ProblemsDialog::~ProblemsDialog()
+{
+ delete ui;
+}
+
+
+bool ProblemsDialog::hasProblems() const
+{
+ return ui->problemsWidget->topLevelItemCount() != 0;
+}
+
+void ProblemsDialog::selectionChanged()
+{
+ QString text = ui->problemsWidget->currentItem()->data(0, Qt::UserRole).toString();
+ ui->descriptionText->setText(text);
+ ui->descriptionText->setLineWrapMode(text.contains('\n') ? QTextEdit::NoWrap : QTextEdit::WidgetWidth);
+}
+
+void ProblemsDialog::urlClicked(const QUrl &url)
+{
+ ::ShellExecuteW(NULL, L"open", ToWString(url.toString()).c_str(), NULL, NULL, SW_SHOWNORMAL);
+}
diff --git a/src/problemsdialog.h b/src/problemsdialog.h
new file mode 100644
index 00000000..299faf8d
--- /dev/null
+++ b/src/problemsdialog.h
@@ -0,0 +1,35 @@
+#ifndef PROBLEMSDIALOG_H
+#define PROBLEMSDIALOG_H
+
+
+#include <QDialog>
+#include <QUrl>
+#include <iplugindiagnose.h>
+
+
+namespace Ui {
+class ProblemsDialog;
+}
+
+
+class ProblemsDialog : public QDialog
+{
+ Q_OBJECT
+
+public:
+ explicit ProblemsDialog(std::vector<MOBase::IPluginDiagnose*> diagnosePlugins, QWidget *parent = 0);
+ ~ProblemsDialog();
+
+ bool hasProblems() const;
+
+private slots:
+
+ void selectionChanged();
+ void urlClicked(const QUrl &url);
+
+private:
+
+ Ui::ProblemsDialog *ui;
+};
+
+#endif // PROBLEMSDIALOG_H
diff --git a/src/problemsdialog.ui b/src/problemsdialog.ui
new file mode 100644
index 00000000..b194bf31
--- /dev/null
+++ b/src/problemsdialog.ui
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ProblemsDialog</class>
+ <widget class="QDialog" name="ProblemsDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>574</width>
+ <height>376</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Problems</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0">
+ <item>
+ <widget class="QTreeWidget" name="problemsWidget">
+ <property name="columnCount">
+ <number>2</number>
+ </property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerDefaultSectionSize">
+ <number>420</number>
+ </attribute>
+ <column>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string notr="true">2</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ <item>
+ <widget class="QTextBrowser" name="descriptionText">
+ <property name="lineWrapMode">
+ <enum>QTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ <property name="html">
+ <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:7.8pt; font-weight:400; font-style:normal;&quot;&gt;
+&lt;p style=&quot;-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-size:8pt;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QDialogButtonBox" name="buttonBox">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="standardButtons">
+ <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>accepted()</signal>
+ <receiver>ProblemsDialog</receiver>
+ <slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>248</x>
+ <y>254</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>157</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ <connection>
+ <sender>buttonBox</sender>
+ <signal>rejected()</signal>
+ <receiver>ProblemsDialog</receiver>
+ <slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>316</x>
+ <y>260</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>286</x>
+ <y>274</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/src/resources.qrc b/src/resources.qrc
index a743ba39..855a23fc 100644
--- a/src/resources.qrc
+++ b/src/resources.qrc
@@ -50,8 +50,5 @@
<file alias="emblem_conflict_overwritten">resources/conflict-overwritten.png</file>
<file alias="emblem_conflict_redundant">resources/conflict-redundant.png</file>
<file alias="emblem_notes">resources/accessories-text-editor.png</file>
- <file alias="network_idle">resources/network-idle.png</file>
- <file alias="network_offline">resources/network-offline.png</file>
- <file alias="network_error">resources/network-error.png</file>
</qresource>
</RCC>