summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/activatemodsdialog.cpp5
-rw-r--r--src/activatemodsdialog.h1
-rw-r--r--src/archivetree.cpp98
-rw-r--r--src/archivetree.h55
-rw-r--r--src/executableslist.cpp10
-rw-r--r--src/finddialog.cpp48
-rw-r--r--src/finddialog.h73
-rw-r--r--src/main.cpp2
-rw-r--r--src/mainwindow.cpp94
-rw-r--r--src/mainwindow.h6
-rw-r--r--src/modlist.cpp8
-rw-r--r--src/modlist.h8
-rw-r--r--src/noeditdelegate.cpp10
-rw-r--r--src/noeditdelegate.h12
-rw-r--r--src/organizer.pro15
-rw-r--r--src/overwriteinfodialog.cpp1
-rw-r--r--src/pluginlist.cpp8
-rw-r--r--src/profile.cpp1
-rw-r--r--src/profileinputdialog.cpp55
-rw-r--r--src/profilesdialog.cpp45
-rw-r--r--src/settings.cpp80
-rw-r--r--src/settings.h47
-rw-r--r--src/settingsdialog.cpp12
-rw-r--r--src/settingsdialog.h2
-rw-r--r--src/settingsdialog.ui182
-rw-r--r--src/shared/gameinfo.cpp20
-rw-r--r--src/shared/skyriminfo.cpp4
-rw-r--r--src/shared/skyriminfo.h2
-rw-r--r--src/version.rc4
29 files changed, 456 insertions, 452 deletions
diff --git a/src/activatemodsdialog.cpp b/src/activatemodsdialog.cpp
index cf798189..8d463fba 100644
--- a/src/activatemodsdialog.cpp
+++ b/src/activatemodsdialog.cpp
@@ -65,11 +65,6 @@ ActivateModsDialog::~ActivateModsDialog()
}
-void ActivateModsDialog::on_buttonBox_accepted()
-{
-}
-
-
std::set<QString> ActivateModsDialog::getModsToActivate()
{
std::set<QString> result;
diff --git a/src/activatemodsdialog.h b/src/activatemodsdialog.h
index db0bf7fa..845167aa 100644
--- a/src/activatemodsdialog.h
+++ b/src/activatemodsdialog.h
@@ -62,7 +62,6 @@ public:
std::set<QString> getESPsToActivate();
private slots:
- void on_buttonBox_accepted();
private:
Ui::ActivateModsDialog *ui;
diff --git a/src/archivetree.cpp b/src/archivetree.cpp
deleted file mode 100644
index 0484b241..00000000
--- a/src/archivetree.cpp
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "archivetree.h"
-#include <QDragMoveEvent>
-
-ArchiveTree::ArchiveTree(QWidget *parent) :
- QTreeWidget(parent)
-{
-}
-
-
-bool ArchiveTree::testMovePossible(QTreeWidgetItem *source, QTreeWidgetItem *target)
-{
- if ((target == NULL) ||
- (source == NULL)) {
- return false;
- }
-
- if ((source == target) ||
- (source->parent() == target)) {
- return false;
- }
-
- return true;
-}
-
-void ArchiveTree::dragEnterEvent(QDragEnterEvent *event)
-{
- QTreeWidgetItem *source = this->currentItem();
- if ((source == NULL) || (source->parent() == NULL)) {
- // can't change top level
- event->ignore();
- return;
- } else {
- QTreeWidget::dragEnterEvent(event);
- }
-
-}
-
-void ArchiveTree::dragMoveEvent(QDragMoveEvent *event)
-{
- if (!testMovePossible(this->currentItem(), itemAt(event->pos()))) {
- event->ignore();
- } else {
- QTreeWidget::dragMoveEvent(event);
- }
-}
-
-
-void ArchiveTree::dropEvent(QDropEvent *event)
-{
- event->ignore();
-
- QTreeWidgetItem *target = itemAt(event->pos());
-
- QList<QTreeWidgetItem*> sourceItems = this->selectedItems();
- for (QList<QTreeWidgetItem*>::iterator iter = sourceItems.begin();
- iter != sourceItems.end(); ++iter) {
- QTreeWidgetItem *source = *iter;
- if ((source->parent() != NULL) &&
- testMovePossible(source, target)) {
- source->parent()->removeChild(source);
- if (target->data(0, Qt::UserRole).toInt() != 0) {
- // target is a file
- if (target->parent() == NULL) {
- // this should really not happen, how should a
- // file get to the top level?
- return;
- }
- int index = target->parent()->indexOfChild(target);
- target->parent()->insertChild(index, source);
- emit changed();
- } else {
- // target is a directory
- target->insertChild(target->childCount(), source);
- emit changed();
- }
- }
- }
-
-}
diff --git a/src/archivetree.h b/src/archivetree.h
deleted file mode 100644
index 775bf8b9..00000000
--- a/src/archivetree.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef ARCHIVETREE_H
-#define ARCHIVETREE_H
-
-#include <QTreeWidget>
-
-/**
- * @brief QT tree widget used to display the content of an archive in the manual installation dialog
- **/
-class ArchiveTree : public QTreeWidget
-{
-
- Q_OBJECT
-
-public:
-
- explicit ArchiveTree(QWidget *parent = 0);
-
-signals:
-
- void changed();
-
-public slots:
-
-protected:
-
- virtual void dragEnterEvent(QDragEnterEvent *event);
- virtual void dragMoveEvent(QDragMoveEvent *event);
- virtual void dropEvent(QDropEvent *event);
-
-private:
-
- bool testMovePossible(QTreeWidgetItem *source, QTreeWidgetItem *target);
-
-};
-
-#endif // ARCHIVETREE_H
diff --git a/src/executableslist.cpp b/src/executableslist.cpp
index 4e39c1a3..c486a4ca 100644
--- a/src/executableslist.cpp
+++ b/src/executableslist.cpp
@@ -172,16 +172,6 @@ void ExecutablesList::addExecutable(const QString &title, const QString &executa
}
}
-/*void ExecutablesList::remove(const QString &executableName)
-{
- for (std::vector<Executable>::iterator iter = m_Executables.begin(); iter != m_Executables.end(); ++iter) {
- if (iter->m_Custom && (iter->m_BinaryInfo.absoluteFilePath() == executableName)) {
- m_Executables.erase(iter);
- break;
- }
- }
-}*/
-
void ExecutablesList::remove(const QString &title)
{
diff --git a/src/finddialog.cpp b/src/finddialog.cpp
deleted file mode 100644
index 58b70ade..00000000
--- a/src/finddialog.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "finddialog.h"
-#include "ui_finddialog.h"
-
-FindDialog::FindDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::FindDialog)
-{
- ui->setupUi(this);
-}
-
-FindDialog::~FindDialog()
-{
- delete ui;
-}
-
-void FindDialog::on_nextBtn_clicked()
-{
- emit findNext();
-}
-
-void FindDialog::on_patternEdit_textChanged(const QString &pattern)
-{
- emit patternChanged(pattern);
-}
-
-void FindDialog::on_closeBtn_clicked()
-{
- this->close();
-}
diff --git a/src/finddialog.h b/src/finddialog.h
deleted file mode 100644
index 70493654..00000000
--- a/src/finddialog.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef FINDDIALOG_H
-#define FINDDIALOG_H
-
-#include <QDialog>
-
-namespace Ui {
- class FindDialog;
-}
-
-/**
- * @brief Find dialog used in the TextView dialog
- **/
-class FindDialog : public QDialog
-{
-
- Q_OBJECT
-
-public:
-
- /**
- * @brief constructor
- *
- * @param parent parent widget
- **/
- explicit FindDialog(QWidget *parent = 0);
-
- ~FindDialog();
-
-signals:
-
- /**
- * @brief emitted when the user wants to jump to the next location matching the pattern
- **/
- void findNext();
-
- /**
- * @brief emitted when the user changes the pattern to search for
- *
- * @param pattern the new search pattern
- **/
- void patternChanged(const QString &pattern);
-
-private slots:
- void on_nextBtn_clicked();
-
- void on_patternEdit_textChanged(const QString &arg1);
-
- void on_closeBtn_clicked();
-
-private:
- Ui::FindDialog *ui;
-};
-
-#endif // FINDDIALOG_H
diff --git a/src/main.cpp b/src/main.cpp
index 1d40dfeb..5a694121 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -343,7 +343,7 @@ int main(int argc, char *argv[])
bool done = false;
while (!done) {
- if (!GameInfo::init(moPath, ToWString(gamePath))) {
+ if (!GameInfo::init(moPath, ToWString(QDir::toNativeSeparators(gamePath)))) {
if (!gamePath.isEmpty()) {
reportError(QObject::tr("No game identified in \"%1\". The directory is required to contain "
"the game binary and its launcher.").arg(gamePath));
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index 2c5e3707..ffec91a1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -98,6 +98,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QNetworkInterface>
#include <QNetworkProxy>
#include <QtConcurrentRun>
+#include <QCoreApplication>
#ifdef TEST_MODELS
@@ -233,6 +234,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget
connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), this, SLOT(modlistChanged(QModelIndex, int)));
connect(&m_ModList, SIGNAL(removeSelectedMods()), this, SLOT(removeMod_clicked()));
connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), this, SLOT(displayColumnSelection(QPoint)));
+ connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), this, SLOT(fileMoved(QString, QString, QString)));
connect(ui->modList, SIGNAL(dropModeUpdate(bool)), &m_ModList, SLOT(dropModeUpdate(bool)));
connect(m_ModListSortProxy, SIGNAL(filterActive(bool)), this, SLOT(modFilterActive(bool)));
connect(ui->modFilterEdit, SIGNAL(textChanged(QString)), m_ModListSortProxy, SLOT(updateFilter(QString)));
@@ -997,6 +999,7 @@ bool MainWindow::registerPlugin(QObject *plugin)
{ // proxy plugins
IPluginProxy *proxy = qobject_cast<IPluginProxy*>(plugin);
if (verifyPlugin(proxy)) {
+ proxy->setParentWidget(this);
QStringList pluginNames = proxy->pluginList(QCoreApplication::applicationDirPath() + "/" + ToQString(AppConfig::pluginPath()));
foreach (const QString &pluginName, pluginNames) {
try {
@@ -1040,11 +1043,38 @@ void MainWindow::loadPlugins()
registerPlugin(plugin);
}
+ QFile loadCheck(QCoreApplication::applicationDirPath() + "/plugin_loadcheck.tmp");
+ if (loadCheck.exists() && loadCheck.open(QIODevice::ReadOnly)) {
+ // oh, there was a failed plugin load last time. Find out which plugin was loaded last
+ QString fileName;
+ while (!loadCheck.atEnd()) {
+ fileName = QString::fromUtf8(loadCheck.readLine().constData()).trimmed();
+ }
+ if (QMessageBox::question(this, tr("Plugin error"),
+ tr("It appears the plugin \"%1\" failed to load last startup and caused MO to crash. Do you want to disable it?\n"
+ "(Please note: If this is the first time you see this message for this plugin you may want to give it another try. "
+ "The plugin may be able to recover from the problem)").arg(fileName),
+ QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes) == QMessageBox::Yes) {
+ m_Settings.addBlacklistPlugin(fileName);
+ }
+ loadCheck.close();
+ }
+
+ loadCheck.open(QIODevice::WriteOnly);
+
QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath());
qDebug("looking for plugins in %s", QDir::toNativeSeparators(pluginPath).toUtf8().constData());
QDirIterator iter(pluginPath, QDir::Files | QDir::NoDotAndDotDot);
+
while (iter.hasNext()) {
iter.next();
+ if (m_Settings.pluginBlacklisted(iter.fileName())) {
+ qDebug("plugin \"%s\" blacklisted", qPrintable(iter.fileName()));
+ continue;
+ }
+ loadCheck.write(iter.fileName().toUtf8());
+ loadCheck.write("\n");
+ loadCheck.flush();
QString pluginName = iter.filePath();
if (QLibrary::isLibrary(pluginName)) {
QPluginLoader pluginLoader(pluginName);
@@ -1063,6 +1093,9 @@ void MainWindow::loadPlugins()
}
}
+ // remove the load check file on success
+ loadCheck.remove();
+
m_DownloadManager.setSupportedExtensions(m_InstallationManager.getSupportedExtensions());
m_DiagnosisPlugins.push_back(this);
@@ -1172,6 +1205,21 @@ QVariant MainWindow::pluginSetting(const QString &pluginName, const QString &key
return m_Settings.pluginSetting(pluginName, key);
}
+void MainWindow::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value)
+{
+ m_Settings.setPluginSetting(pluginName, key, value);
+}
+
+QVariant MainWindow::persistent(const QString &pluginName, const QString &key, const QVariant &def) const
+{
+ return m_Settings.pluginPersistent(pluginName, key, def);
+}
+
+void MainWindow::setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync)
+{
+ m_Settings.setPluginPersistent(pluginName, key, value, sync);
+}
+
QString MainWindow::pluginDataPath() const
{
QString pluginPath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getOrganizerDirectory())) + "/" + ToQString(AppConfig::pluginPath());
@@ -1273,11 +1321,9 @@ void MainWindow::spawnBinary(const QFileInfo &binary, const QString &arguments,
this->setEnabled(true);
refreshDirectoryStructure();
- refreshDataTree();
if (GameInfo::instance().getLoadOrderMechanism() == GameInfo::TYPE_FILETIME) {
QFile::remove(m_CurrentProfile->getLoadOrderFileName());
}
- refreshLists();
dialog->hide();
}
}
@@ -1622,11 +1668,15 @@ void MainWindow::refreshESPList()
m_CurrentProfile->writeModlist();
// clear list
- m_PluginList.refresh(m_CurrentProfile->getName(),
- *m_DirectoryStructure,
- m_CurrentProfile->getPluginsFileName(),
- m_CurrentProfile->getLoadOrderFileName(),
- m_CurrentProfile->getLockedOrderFileName());
+ try {
+ m_PluginList.refresh(m_CurrentProfile->getName(),
+ *m_DirectoryStructure,
+ m_CurrentProfile->getPluginsFileName(),
+ m_CurrentProfile->getLoadOrderFileName(),
+ m_CurrentProfile->getLockedOrderFileName());
+ } catch (const std::exception &e) {
+ reportError(tr("Failed to refresh list of esps: %s").arg(e.what()));
+ }
}
@@ -1926,7 +1976,6 @@ void MainWindow::on_btnRefreshData_clicked()
{
if (!m_DirectoryUpdate) {
refreshDirectoryStructure();
- refreshDataTree();
} else {
qDebug("directory update");
}
@@ -2331,8 +2380,12 @@ void MainWindow::directory_refreshed()
{
DirectoryEntry *newStructure = m_DirectoryRefresher.getDirectoryStructure();
if (newStructure != NULL) {
- delete m_DirectoryStructure;
+ DirectoryEntry *oldStructure = m_DirectoryStructure;
m_DirectoryStructure = newStructure;
+ delete oldStructure;
+
+ refreshDataTree();
+ refreshLists();
} else {
// TODO: don't know why this happens, this slot seems to get called twice with only one emit
return;
@@ -2541,6 +2594,29 @@ void MainWindow::modlistChanged(int)
}
+void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName)
+{
+ const FileEntry::Ptr filePtr = m_DirectoryStructure->findFile(ToWString(filePath));
+ if (filePtr.get() != NULL) {
+ try {
+ FilesOrigin &oldOrigin = m_DirectoryStructure->getOriginByName(ToWString(oldOriginName));
+ FilesOrigin &newOrigin = m_DirectoryStructure->getOriginByName(ToWString(newOriginName));
+
+ QString fullNewPath = ToQString(newOrigin.getPath()) + "\\" + filePath;
+ WIN32_FIND_DATAW findData;
+ ::FindFirstFileW(ToWString(fullNewPath).c_str(), &findData);
+
+ filePtr->addOrigin(newOrigin.getID(), findData.ftCreationTime, L"");
+ filePtr->removeOrigin(oldOrigin.getID());
+ } catch (const std::exception &e) {
+ reportError(tr("Failed to move \"%1\" from mod \"%2\" to \"%3\": %4").arg(filePath).arg(oldOriginName).arg(newOriginName).arg(e.what()));
+ }
+ } else {
+ reportError(tr("Failed to relocate \"%1\"").arg(filePath));
+ }
+}
+
+
QTreeWidgetItem *MainWindow::addFilterItem(QTreeWidgetItem *root, const QString &name, int categoryID)
{
QTreeWidgetItem *item = new QTreeWidgetItem(QStringList(name));
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 152c0a27..54ae0e96 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -105,6 +105,9 @@ public:
virtual bool removeMod(MOBase::IModInterface *mod);
virtual void modDataChanged(MOBase::IModInterface *mod);
virtual QVariant pluginSetting(const QString &pluginName, const QString &key) const;
+ virtual void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value);
+ virtual QVariant persistent(const QString &pluginName, const QString &key, const QVariant &def = QVariant()) const;
+ virtual void setPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync = true);
virtual QString pluginDataPath() const;
virtual void installMod(const QString &fileName);
virtual QString resolvePath(const QString &fileName) const;
@@ -315,6 +318,8 @@ private:
std::vector<MOBase::IPluginDiagnose*> m_DiagnosisPlugins;
std::vector<QString> m_UnloadedPlugins;
+ QFile m_PluginsCheck;
+
private slots:
void showMessage(const QString &message);
@@ -435,6 +440,7 @@ private slots:
void updateStyle(const QString &style);
void modlistChanged(const QModelIndex &index, int role);
+ void fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName);
void savePluginList();
diff --git a/src/modlist.cpp b/src/modlist.cpp
index 5aa8fbb9..b5a7182e 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -477,6 +477,7 @@ Qt::ItemFlags ModList::flags(const QModelIndex &modelIndex) const
return result;
}
+
QStringList ModList::mimeTypes() const
{
QStringList result = QAbstractItemModel::mimeTypes();
@@ -544,6 +545,12 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa
QDir modDirectory(modInfo->absolutePath());
QDir gameDirectory(QDir::fromNativeSeparators(ToQString(MOShared::GameInfo::instance().getOverwriteDir())));
+ unsigned int overwriteIndex = ModInfo::findMod([](ModInfo::Ptr mod) -> bool {
+ std::vector<ModInfo::EFlag> flags = mod->getFlags();
+ return std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end(); });
+
+ QString overwriteName = ModInfo::getByIndex(overwriteIndex)->name();
+
foreach (const QUrl &url, mimeData->urls()) {
QString relativePath = gameDirectory.relativeFilePath(url.toLocalFile());
if (relativePath.startsWith("..")) {
@@ -552,6 +559,7 @@ bool ModList::dropURLs(const QMimeData *mimeData, int row, const QModelIndex &pa
}
source.append(url.toLocalFile());
target.append(modDirectory.absoluteFilePath(relativePath));
+ emit fileMoved(relativePath, overwriteName, modInfo->name());
}
if (source.count() != 0) {
diff --git a/src/modlist.h b/src/modlist.h
index 069de40b..7e76d677 100644
--- a/src/modlist.h
+++ b/src/modlist.h
@@ -182,6 +182,14 @@ signals:
*/
void removeSelectedMods();
+ /**
+ * @brief fileMoved emitted when a file is moved from one mod to another
+ * @param relativePath relative path of the file moved
+ * @param oldOriginName name of the origin that previously contained the file
+ * @param newOriginName name of the origin that now contains the file
+ */
+ void fileMoved(const QString &relativePath, const QString &oldOriginName, const QString &newOriginName);
+
protected:
// event filter, handles event from the header and the tree view itself
diff --git a/src/noeditdelegate.cpp b/src/noeditdelegate.cpp
new file mode 100644
index 00000000..ab8a4880
--- /dev/null
+++ b/src/noeditdelegate.cpp
@@ -0,0 +1,10 @@
+#include "noeditdelegate.h"
+
+NoEditDelegate::NoEditDelegate(QObject *parent)
+ : QStyledItemDelegate(parent)
+{
+}
+
+QWidget *NoEditDelegate::createEditor(QWidget*, const QStyleOptionViewItem&, const QModelIndex&) const {
+ return NULL;
+}
diff --git a/src/noeditdelegate.h b/src/noeditdelegate.h
new file mode 100644
index 00000000..d0ba2f68
--- /dev/null
+++ b/src/noeditdelegate.h
@@ -0,0 +1,12 @@
+#ifndef NOEDITDELEGATE_H
+#define NOEDITDELEGATE_H
+
+#include <QStyledItemDelegate>
+
+class NoEditDelegate: public QStyledItemDelegate {
+public:
+ NoEditDelegate(QObject *parent = NULL);
+ virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
+};
+
+#endif // NOEDITDELEGATE_H
diff --git a/src/organizer.pro b/src/organizer.pro
index 339a50cd..e89b6e99 100644
--- a/src/organizer.pro
+++ b/src/organizer.pro
@@ -51,7 +51,6 @@ SOURCES += \
json.cpp \
installationmanager.cpp \
helper.cpp \
- finddialog.cpp \
filedialogmemory.cpp \
executableslist.cpp \
editexecutablesdialog.cpp \
@@ -66,7 +65,6 @@ SOURCES += \
categoriesdialog.cpp \
categories.cpp \
bbcode.cpp \
- archivetree.cpp \
activatemodsdialog.cpp \
moapplication.cpp \
profileinputdialog.cpp \
@@ -80,7 +78,8 @@ SOURCES += \
serverinfo.cpp \
../esptk/record.cpp \
../esptk/espfile.cpp \
- ../esptk/subrecord.cpp
+ ../esptk/subrecord.cpp \
+ noeditdelegate.cpp
HEADERS += \
transfersavesdialog.h \
@@ -119,7 +118,6 @@ HEADERS += \
json.h \
installationmanager.h \
helper.h \
- finddialog.h \
filedialogmemory.h \
executableslist.h \
editexecutablesdialog.h \
@@ -134,7 +132,6 @@ HEADERS += \
categoriesdialog.h \
categories.h \
bbcode.h \
- archivetree.h \
activatemodsdialog.h \
moapplication.h \
profileinputdialog.h \
@@ -148,7 +145,9 @@ HEADERS += \
serverinfo.h \
../esptk/record.h \
../esptk/espfile.h \
- ../esptk/subrecord.h
+ ../esptk/subrecord.h \
+ ../esptk/espexceptions.h \
+ noeditdelegate.h
FORMS += \
transfersavesdialog.ui \
@@ -218,8 +217,8 @@ TRANSLATIONS = organizer_de.ts \
organizer_zh_CN.ts \
organizer_cs.ts \
organizer_tr.ts \
- organizer_ru.ts \
- organizer.en.ts
+# organizer.en.ts \
+ organizer_ru.ts
!isEmpty(TRANSLATIONS) {
isEmpty(QMAKE_LRELEASE) {
diff --git a/src/overwriteinfodialog.cpp b/src/overwriteinfodialog.cpp
index 11e7b552..e215146f 100644
--- a/src/overwriteinfodialog.cpp
+++ b/src/overwriteinfodialog.cpp
@@ -37,7 +37,6 @@ public:
virtual int columnCount(const QModelIndex &parent) const {
m_RegularColumnCount = QFileSystemModel::columnCount(parent);
-// return m_RegularColumnCount + 1;
return m_RegularColumnCount;
}
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index ea23fcdd..6cb9bdf7 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -140,8 +140,12 @@ void PluginList::refresh(const QString &profileName, const DirectoryEntry &baseD
std::find(primaryPlugins.begin(), primaryPlugins.end(), ToWString(filename.toLower())) != primaryPlugins.end();
bool archive = false;
- FilesOrigin &origin = baseDirectory.getOriginByID(current->getOrigin(archive));
- m_ESPs.push_back(ESPInfo(filename, forceEnabled, current->getFileTime(), ToQString(origin.getName()), ToQString(current->getFullPath())));
+ try {
+ FilesOrigin &origin = baseDirectory.getOriginByID(current->getOrigin(archive));
+ m_ESPs.push_back(ESPInfo(filename, forceEnabled, current->getFileTime(), ToQString(origin.getName()), ToQString(current->getFullPath())));
+ } 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()));
+ }
}
}
diff --git a/src/profile.cpp b/src/profile.cpp
index 330bfa09..07f7010e 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -755,6 +755,7 @@ QString Profile::getIniFileName() const
return m_Directory.absoluteFilePath(ToQString(primaryIniFile));
}
+
QString Profile::getPath() const
{
return QDir::cleanPath(m_Directory.absolutePath());
diff --git a/src/profileinputdialog.cpp b/src/profileinputdialog.cpp
index 7402d4d5..af33dcdd 100644
--- a/src/profileinputdialog.cpp
+++ b/src/profileinputdialog.cpp
@@ -17,29 +17,32 @@ You should have received a copy of the GNU General Public License
along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "profileinputdialog.h"
-#include "ui_profileinputdialog.h"
-
-ProfileInputDialog::ProfileInputDialog(QWidget *parent) :
- QDialog(parent),
- ui(new Ui::ProfileInputDialog)
-{
- ui->setupUi(this);
-}
-
-ProfileInputDialog::~ProfileInputDialog()
-{
- delete ui;
-}
-
-QString ProfileInputDialog::getName() const
-{
- return ui->nameEdit->text().trimmed();
-}
-
-
-bool ProfileInputDialog::getPreferDefaultSettings() const
-{
- return ui->defaultSettingsBox->checkState() == Qt::Checked;
-}
-
+#include "profileinputdialog.h"
+#include "ui_profileinputdialog.h"
+#include <utility.h>
+
+ProfileInputDialog::ProfileInputDialog(QWidget *parent) :
+ QDialog(parent),
+ ui(new Ui::ProfileInputDialog)
+{
+ ui->setupUi(this);
+}
+
+ProfileInputDialog::~ProfileInputDialog()
+{
+ delete ui;
+}
+
+QString ProfileInputDialog::getName() const
+{
+ QString result = ui->nameEdit->text();
+ MOBase::fixDirectoryName(result);
+ return result;
+}
+
+
+bool ProfileInputDialog::getPreferDefaultSettings() const
+{
+ return ui->defaultSettingsBox->checkState() == Qt::Checked;
+}
+
diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp
index 9955ecd2..69872a24 100644
--- a/src/profilesdialog.cpp
+++ b/src/profilesdialog.cpp
@@ -150,36 +150,55 @@ void ProfilesDialog::on_copyProfileButton_clicked()
{
bool okClicked;
QString name = QInputDialog::getText(this, tr("Name"), tr("Please enter a name for the new profile"), QLineEdit::Normal, QString(), &okClicked);
- if (okClicked && (name.size() > 0)) {
- QListWidget *profilesList = findChild<QListWidget*>("profilesList");
+ fixDirectoryName(name);
+ if (okClicked) {
+ if (name.size() > 0) {
+ QListWidget *profilesList = findChild<QListWidget*>("profilesList");
- try {
- const Profile::Ptr currentProfile = profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
- createProfile(name, *currentProfile);
- } catch (const std::exception &e) {
- reportError(tr("failed to copy profile: %1").arg(e.what()));
+ try {
+ const Profile::Ptr currentProfile = profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
+ createProfile(name, *currentProfile);
+ } catch (const std::exception &e) {
+ reportError(tr("failed to copy profile: %1").arg(e.what()));
+ }
+ } else {
+ QMessageBox::warning(this, tr("Invalid name"), tr("Invalid profile name"));
}
}
}
void ProfilesDialog::on_removeProfileButton_clicked()
{
- QMessageBox confirmBox(QMessageBox::Question, tr("Confirm"), tr("Are you sure you want to remove this profile?"),
+ QMessageBox confirmBox(QMessageBox::Question, tr("Confirm"), tr("Are you sure you want to remove this profile (including local savegames if any)?"),
QMessageBox::Yes | QMessageBox::No);
if (confirmBox.exec() == QMessageBox::Yes) {
QListWidget *profilesList = findChild<QListWidget*>("profilesList");
Profile::Ptr currentProfile = profilesList->currentItem()->data(Qt::UserRole).value<Profile::Ptr>();
-
- // on destruction, the profile object would write the profile.ini file again, so
- // we have to get rid of the it before deleting the directory
- QString profilePath = currentProfile->getPath();
+ QString profilePath;
+ if (currentProfile.get() == NULL) {
+ profilePath = QDir::fromNativeSeparators(ToQString(GameInfo::instance().getProfilesDir())) + "/" + profilesList->currentItem()->text();
+ if (QMessageBox::question(this, tr("Profile broken"),
+ tr("This profile you're about to delete seems to be broken or the path is invalid. "
+ "I'm about to delete the following folder: \"%1\". Proceed?").arg(profilePath), QMessageBox::Yes | QMessageBox::No) == QMessageBox::No) {
+ return;
+ }
+ } else {
+ // on destruction, the profile object would write the profile.ini file again, so
+ // we have to get rid of the it before deleting the directory
+ profilePath = currentProfile->getPath();
+ }
QListWidgetItem* item = profilesList->takeItem(profilesList->currentRow());
if (item != NULL) {
delete item;
}
- shellDelete(QStringList(profilePath));
+ if (!shellDelete(QStringList(profilePath))) {
+ qWarning("Failed to shell-delete \"%s\" (errorcode %lu), trying regular delete", qPrintable(profilePath), ::GetLastError());
+ if (!removeDir(profilePath)) {
+ qWarning("regular delete failed too");
+ }
+ }
}
}
diff --git a/src/settings.cpp b/src/settings.cpp
index 39b6dba7..42a8d693 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -87,6 +87,19 @@ void Settings::clearPlugins()
{
m_Plugins.clear();
m_PluginSettings.clear();
+
+ m_PluginBlacklist.clear();
+ int count = m_Settings.beginReadArray("pluginBlacklist");
+ for (int i = 0; i < count; ++i) {
+ m_Settings.setArrayIndex(i);
+ m_PluginBlacklist.insert(m_Settings.value("name").toString());
+ }
+ m_Settings.endArray();
+}
+
+bool Settings::pluginBlacklisted(const QString &fileName) const
+{
+ return m_PluginBlacklist.contains(fileName);
}
void Settings::registerPlugin(IPlugin *plugin)
@@ -275,16 +288,47 @@ QVariant Settings::pluginSetting(const QString &pluginName, const QString &key)
{
auto iterPlugin = m_PluginSettings.find(pluginName);
if (iterPlugin == m_PluginSettings.end()) {
- throw MyException(tr("setting for invalid plugin \"%1\" requested").arg(key));
+ return QVariant();
}
auto iterSetting = iterPlugin->find(key);
if (iterSetting == iterPlugin->end()) {
- throw MyException(tr("invalid setting \"%1\" requested for plugin \"%2\"").arg(key).arg(pluginName));
+ return QVariant();
}
return *iterSetting;
}
+void Settings::setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value)
+{
+ auto iterPlugin = m_PluginSettings.find(pluginName);
+ if (iterPlugin == m_PluginSettings.end()) {
+ throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
+ }
+
+ // store the new setting both in memory and in the ini
+ m_PluginSettings[pluginName][key] = value;
+ m_Settings.setValue("Plugins/" + pluginName + "/" + key, value);
+}
+
+QVariant Settings::pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const
+{
+ if (!m_PluginSettings.contains(pluginName)) {
+ return def;
+ }
+ return m_Settings.value("PluginPersistance/" + pluginName + "/" + key, def);
+}
+
+void Settings::setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync)
+{
+ if (!m_PluginSettings.contains(pluginName)) {
+ throw MyException(tr("attempt to store setting for unknown plugin \"%1\"").arg(pluginName));
+ }
+ m_Settings.setValue("PluginPersistance/" + pluginName + "/" + key, value);
+ if (sync) {
+ m_Settings.sync();
+ }
+}
+
QString Settings::language()
{
QString result = m_Settings.value("Settings/language", "").toString();
@@ -330,6 +374,23 @@ void Settings::updateServers(const QList<ServerInfo> &servers)
m_Settings.sync();
}
+void Settings::addBlacklistPlugin(const QString &fileName)
+{
+ m_PluginBlacklist.insert(fileName);
+ writePluginBlacklist();
+}
+
+void Settings::writePluginBlacklist()
+{
+ m_Settings.beginWriteArray("pluginBlacklist");
+ int idx = 0;
+ foreach (const QString &plugin, m_PluginBlacklist) {
+ m_Settings.setArrayIndex(idx++);
+ m_Settings.setValue("name", plugin);
+ }
+
+ m_Settings.endArray();
+}
void Settings::addLanguages(QComboBox *languageBox)
{
@@ -443,6 +504,7 @@ void Settings::query(QWidget *parent)
// plugis page
QListWidget *pluginsList = dialog.findChild<QListWidget*>("pluginsList");
+ QListWidget *pluginBlacklistList = dialog.findChild<QListWidget*>("pluginBlacklist");
// workarounds page
QCheckBox *forceEnableBox = dialog.findChild<QCheckBox*>("forceEnableBox");
@@ -522,6 +584,7 @@ void Settings::query(QWidget *parent)
nmmVersionEdit->setText(m_Settings.value("Settings/nmm_version", "0.33.1").toString());
logLevelBox->setCurrentIndex(logLevel());
+ // display plugin settings
foreach (IPlugin *plugin, m_Plugins) {
QListWidgetItem *listItem = new QListWidgetItem(plugin->name(), pluginsList);
listItem->setData(Qt::UserRole, QVariant::fromValue((void*)plugin));
@@ -529,6 +592,12 @@ void Settings::query(QWidget *parent)
pluginsList->addItem(listItem);
}
+ // display plugin blacklist
+ foreach (const QString &pluginName, m_PluginBlacklist) {
+ pluginBlacklistList->addItem(pluginName);
+ }
+
+ // display server preferences
m_Settings.beginGroup("Servers");
foreach (const QString &key, m_Settings.childKeys()) {
QVariantMap val = m_Settings.value(key).toMap();
@@ -624,6 +693,13 @@ void Settings::query(QWidget *parent)
}
}
+ // store plugin blacklist
+ m_PluginBlacklist.clear();
+ foreach (QListWidgetItem *item, pluginBlacklistList->findItems("*", Qt::MatchWildcard)) {
+ m_PluginBlacklist.insert(item->text());
+ }
+ writePluginBlacklist();
+
// store server preference
m_Settings.beginGroup("Servers");
for (int i = 0; i < knownServersList->count(); ++i) {
diff --git a/src/settings.h b/src/settings.h
index bf17d162..51ee6b92 100644
--- a/src/settings.h
+++ b/src/settings.h
@@ -57,6 +57,7 @@ public:
/**
* @brief register plugin to be configurable
* @param plugin the plugin to register
+ * @return true if the plugin may be registered, false if it is blacklisted
*/
void registerPlugin(MOBase::IPlugin *plugin);
@@ -195,11 +196,38 @@ public:
* @param pluginName name of the plugin
* @param key name of the setting to retrieve
* @return the requested value as a QVariant
- * @throws an exception is thrown if this setting doesn't exist
+ * @note an invalid QVariant is returned if the the plugin/setting is not declared
*/
QVariant pluginSetting(const QString &pluginName, const QString &key) const;
/**
+ * @brief set a setting for one of the installed mods
+ * @param pluginName name of the plugin
+ * @param key name of the setting to change
+ * @param value the new value to set
+ * @throw an exception is thrown if pluginName is invalid
+ */
+ void setPluginSetting(const QString &pluginName, const QString &key, const QVariant &value);
+
+ /**
+ * @brief retrieve a persistent value for a plugin
+ * @param pluginName name of the plugin to store data for
+ * @param key id of the value to retrieve
+ * @param def default value to return if the value is not set
+ * @return the requested value
+ */
+ QVariant pluginPersistent(const QString &pluginName, const QString &key, const QVariant &def) const;
+
+ /**
+ * @brief set a persistent value for a plugin
+ * @param pluginName name of the plugin to store data for
+ * @param key id of the value to retrieve
+ * @param value value to set
+ * @throw an exception is thrown if pluginName is invalid
+ */
+ void setPluginPersistent(const QString &pluginName, const QString &key, const QVariant &value, bool sync);
+
+ /**
* @return short code of the configured language (corresponding to the translation files)
*/
QString language();
@@ -210,6 +238,19 @@ public:
*/
void updateServers(const QList<ServerInfo> &servers);
+ /**
+ * @brief add a plugin that is to be blacklisted
+ * @param fileName name of the plugin to blacklist
+ */
+ void addBlacklistPlugin(const QString &fileName);
+
+ /**
+ * @brief test if a plugin is blacklisted and shouldn't be loaded
+ * @param fileName name of the plugin
+ * @return true if the file is blacklisted
+ */
+ bool pluginBlacklisted(const QString &fileName) const;
+
private:
QString obfuscate(const QString &password) const;
@@ -219,6 +260,8 @@ private:
void addStyles(QComboBox *styleBox);
bool isNXMHandler(bool *modifyable);
void setNXMHandlerActive(bool active, bool writable);
+ void readPluginBlacklist();
+ void writePluginBlacklist();
private slots:
@@ -241,6 +284,8 @@ private:
QMap<QString, QMap<QString, QVariant> > m_PluginSettings;
+ QSet<QString> m_PluginBlacklist;
+
};
#endif // WORKAROUNDS_H
diff --git a/src/settingsdialog.cpp b/src/settingsdialog.cpp
index 9f268455..c8908ddb 100644
--- a/src/settingsdialog.cpp
+++ b/src/settingsdialog.cpp
@@ -21,10 +21,12 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "ui_settingsdialog.h"
#include "categoriesdialog.h"
#include "helper.h"
+#include "noeditdelegate.h"
#include <gameinfo.h>
#include <QDirIterator>
#include <QFileDialog>
#include <QMessageBox>
+#include <QShortcut>
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -37,6 +39,9 @@ SettingsDialog::SettingsDialog(QWidget *parent)
: TutorableDialog("SettingsDialog", parent), ui(new Ui::SettingsDialog)
{
ui->setupUi(this);
+
+ QShortcut *delShortcut = new QShortcut(QKeySequence(Qt::Key_Delete), ui->pluginBlacklist);
+ connect(delShortcut, SIGNAL(activated()), this, SLOT(deleteBlacklistItem()));
}
SettingsDialog::~SettingsDialog()
@@ -146,6 +151,8 @@ void SettingsDialog::on_pluginsList_currentItemChanged(QListWidgetItem *current,
for (auto iter = settings.begin(); iter != settings.end(); ++iter) {
QTreeWidgetItem *newItem = new QTreeWidgetItem(QStringList(iter.key()));
QVariant value = *iter;
+
+ ui->pluginSettingsList->setItemDelegateForColumn(0, new NoEditDelegate());
newItem->setData(1, Qt::DisplayRole, value);
newItem->setData(1, Qt::EditRole, value);
@@ -153,3 +160,8 @@ void SettingsDialog::on_pluginsList_currentItemChanged(QListWidgetItem *current,
ui->pluginSettingsList->addTopLevelItem(newItem);
}
}
+
+void SettingsDialog::deleteBlacklistItem()
+{
+ ui->pluginBlacklist->takeItem(ui->pluginBlacklist->currentIndex().row());
+}
diff --git a/src/settingsdialog.h b/src/settingsdialog.h
index 3bfc1706..718574a0 100644
--- a/src/settingsdialog.h
+++ b/src/settingsdialog.h
@@ -73,6 +73,8 @@ private slots:
void on_pluginsList_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);
+ void deleteBlacklistItem();
+
private:
Ui::SettingsDialog *ui;
};
diff --git a/src/settingsdialog.ui b/src/settingsdialog.ui
index b63965f9..e7bd0fa3 100644
--- a/src/settingsdialog.ui
+++ b/src/settingsdialog.ui
@@ -406,102 +406,116 @@ p, li { white-space: pre-wrap; }
<attribute name="title">
<string>Plugins</string>
</attribute>
- <layout class="QHBoxLayout" name="horizontalLayout_7" stretch="0,1">
+ <layout class="QVBoxLayout" name="verticalLayout_9" stretch="0,0,0">
<item>
- <widget class="QListWidget" name="pluginsList">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- </widget>
- </item>
- <item>
- <layout class="QVBoxLayout" name="verticalLayout_7" stretch="0,1">
+ <layout class="QHBoxLayout" name="horizontalLayout_9">
<item>
- <layout class="QFormLayout" name="formLayout_2">
- <item row="0" column="0">
- <widget class="QLabel" name="label_13">
- <property name="text">
- <string>Author:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="authorLabel">
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_15">
- <property name="text">
- <string>Version:</string>
- </property>
- </widget>
+ <widget class="QListWidget" name="pluginsList">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_7" stretch="0,1">
+ <item>
+ <layout class="QFormLayout" name="formLayout_2">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label_13">
+ <property name="text">
+ <string>Author:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLabel" name="authorLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_15">
+ <property name="text">
+ <string>Version:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLabel" name="versionLabel">
+ <property name="text">
+ <string/>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_14">
+ <property name="text">
+ <string>Description:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLabel" name="descriptionLabel">
+ <property name="text">
+ <string/>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
</item>
- <item row="1" column="1">
- <widget class="QLabel" name="versionLabel">
- <property name="text">
- <string/>
+ <item>
+ <widget class="QTreeWidget" name="pluginSettingsList">
+ <property name="indentation">
+ <number>0</number>
</property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_14">
- <property name="text">
- <string>Description:</string>
+ <property name="rootIsDecorated">
+ <bool>false</bool>
</property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="descriptionLabel">
- <property name="text">
- <string/>
+ <property name="itemsExpandable">
+ <bool>false</bool>
</property>
- <property name="wordWrap">
- <bool>true</bool>
+ <property name="expandsOnDoubleClick">
+ <bool>false</bool>
</property>
+ <attribute name="headerVisible">
+ <bool>false</bool>
+ </attribute>
+ <attribute name="headerDefaultSectionSize">
+ <number>100</number>
+ </attribute>
+ <column>
+ <property name="text">
+ <string>Key</string>
+ </property>
+ </column>
+ <column>
+ <property name="text">
+ <string>Value</string>
+ </property>
+ </column>
</widget>
</item>
</layout>
</item>
- <item>
- <widget class="QTreeWidget" name="pluginSettingsList">
- <property name="indentation">
- <number>0</number>
- </property>
- <property name="rootIsDecorated">
- <bool>false</bool>
- </property>
- <property name="itemsExpandable">
- <bool>false</bool>
- </property>
- <property name="expandsOnDoubleClick">
- <bool>false</bool>
- </property>
- <attribute name="headerVisible">
- <bool>false</bool>
- </attribute>
- <attribute name="headerDefaultSectionSize">
- <number>100</number>
- </attribute>
- <column>
- <property name="text">
- <string>Key</string>
- </property>
- </column>
- <column>
- <property name="text">
- <string>Value</string>
- </property>
- </column>
- </widget>
- </item>
</layout>
</item>
+ <item>
+ <widget class="QLabel" name="label_18">
+ <property name="text">
+ <string>Blacklisted Plugins (use &lt;del&gt; to remove):</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QListWidget" name="pluginBlacklist"/>
+ </item>
</layout>
</widget>
<widget class="QWidget" name="workaroundTab">
@@ -638,7 +652,7 @@ Please note that MO does identify itself as MO to the webserver, it's not lying
tl;dr-version: If Nexus-features don't work, insert the current version number of NMM here and try again.</string>
</property>
<property name="inputMask">
- <string notr="true">009.009.009</string>
+ <string notr="true">009.009.009; </string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
diff --git a/src/shared/gameinfo.cpp b/src/shared/gameinfo.cpp
index fd5072bf..6b53450d 100644
--- a/src/shared/gameinfo.cpp
+++ b/src/shared/gameinfo.cpp
@@ -62,36 +62,36 @@ void GameInfo::identifyMyGamesDirectory(const std::wstring &file)
}
-bool GameInfo::identifyGame(const std::wstring &omoDirectory, const std::wstring &searchPath)
+bool GameInfo::identifyGame(const std::wstring &moDirectory, const std::wstring &searchPath)
{
if (OblivionInfo::identifyGame(searchPath)) {
- s_Instance = new OblivionInfo(omoDirectory, searchPath);
+ s_Instance = new OblivionInfo(moDirectory, searchPath);
} else if (Fallout3Info::identifyGame(searchPath)) {
- s_Instance = new Fallout3Info(omoDirectory, searchPath);
+ s_Instance = new Fallout3Info(moDirectory, searchPath);
} else if (FalloutNVInfo::identifyGame(searchPath)) {
- s_Instance = new FalloutNVInfo(omoDirectory, searchPath);
+ s_Instance = new FalloutNVInfo(moDirectory, searchPath);
} else if (SkyrimInfo::identifyGame(searchPath)) {
- s_Instance = new SkyrimInfo(omoDirectory, searchPath);
+ s_Instance = new SkyrimInfo(moDirectory, searchPath);
}
return s_Instance != NULL;
}
-bool GameInfo::init(const std::wstring &omoDirectory, const std::wstring &gamePath)
+bool GameInfo::init(const std::wstring &moDirectory, const std::wstring &gamePath)
{
if (s_Instance == NULL) {
if (gamePath.length() == 0) {
// search upward in the directory until a recognized game-binary is found
- std::wstring searchPath(omoDirectory);
- while (!identifyGame(omoDirectory, searchPath)) {
+ std::wstring searchPath(moDirectory);
+ while (!identifyGame(moDirectory, searchPath)) {
size_t lastSep = searchPath.find_last_of(L"/\\");
if (lastSep == std::string::npos) {
return false;
}
searchPath.erase(lastSep);
}
- } else if (!identifyGame(omoDirectory, gamePath)) {
+ } else if (!identifyGame(moDirectory, gamePath)) {
return false;
}
}
@@ -204,4 +204,4 @@ std::wstring GameInfo::getSpecialPath(LPCWSTR name) const
return temp;
}
-} // namespace MOShared
+} // namespace MOShared
diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp
index 80cf4c80..8c6b79ef 100644
--- a/src/shared/skyriminfo.cpp
+++ b/src/shared/skyriminfo.cpp
@@ -33,8 +33,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
namespace MOShared {
-SkyrimInfo::SkyrimInfo(const std::wstring &omoDirectory, const std::wstring &gameDirectory)
- : GameInfo(omoDirectory, gameDirectory)
+SkyrimInfo::SkyrimInfo(const std::wstring &moDirectory, const std::wstring &gameDirectory)
+ : GameInfo(moDirectory, gameDirectory)
{
identifyMyGamesDirectory(L"skyrim");
diff --git a/src/shared/skyriminfo.h b/src/shared/skyriminfo.h
index 4760c38b..c5d31ff0 100644
--- a/src/shared/skyriminfo.h
+++ b/src/shared/skyriminfo.h
@@ -95,7 +95,7 @@ public:
private:
- SkyrimInfo(const std::wstring &omoDirectory, const std::wstring &gameDirectory);
+ SkyrimInfo(const std::wstring &moDirectory, const std::wstring &gameDirectory);
static bool identifyGame(const std::wstring &searchPath);
diff --git a/src/version.rc b/src/version.rc
index 7e988897..16e006cf 100644
--- a/src/version.rc
+++ b/src/version.rc
@@ -1,7 +1,7 @@
#include "Winver.h"
-#define VER_FILEVERSION 1,0,0,1
-#define VER_FILEVERSION_STR "1,0,0,1\0"
+#define VER_FILEVERSION 1,0,2,0
+#define VER_FILEVERSION_STR "1,0,2,0\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION