diff options
Diffstat (limited to 'src/mainwindow.cpp')
| -rw-r--r-- | src/mainwindow.cpp | 226 |
1 files changed, 180 insertions, 46 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 65633ab1..e7e9f856 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,6 +86,7 @@ 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> @@ -91,12 +94,30 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <Psapi.h> #include <shlobj.h> #include <TlHelp32.h> +#include <QNetworkInterface> using namespace MOBase; using namespace MOShared; +static bool isOnline() +{ + QList<QNetworkInterface> interfaces = QNetworkInterface::allInterfaces(); + + bool connected = false; + for (auto iter = interfaces.begin(); iter != interfaces.end(); ++iter) { + if ( (iter->flags() & QNetworkInterface::IsUp) && + (iter->flags() & QNetworkInterface::IsRunning) && + !(iter->flags() & QNetworkInterface::IsLoopBack)) { + connected = true; + } + } + + return connected; +} + + MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow), m_Tutorial(this, "MainWindow"), m_ExeName(exeName), m_OldProfileIndex(-1), @@ -135,12 +156,11 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget m_ModListSortProxy = new ModListSortProxy(m_CurrentProfile, this); m_ModListSortProxy->setSourceModel(&m_ModList); - QAbstractProxyModel *proxyModel = new QIdentityProxyModel(this); - proxyModel->setSourceModel(m_ModListSortProxy); - ui->modList->setModel(proxyModel); + ui->modList->setModel(m_ModListSortProxy); ui->modList->sortByColumn(ModList::COL_PRIORITY, Qt::AscendingOrder); ui->modList->setItemDelegateForColumn(ModList::COL_FLAGS, new IconDelegate(ui->modList)); + //ui->modList->setAcceptDrops(true); ui->modList->header()->installEventFilter(&m_ModList); ui->modList->header()->restoreState(initSettings.value("mod_list_state").toByteArray()); ui->modList->installEventFilter(&m_ModList); @@ -162,6 +182,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget // set up plugin list m_PluginListSortProxy = new PluginListSortProxy(this); m_PluginListSortProxy->setSourceModel(&m_PluginList); + ui->espList->setModel(m_PluginListSortProxy); ui->espList->sortByColumn(PluginList::COL_PRIORITY, Qt::AscendingOrder); ui->espList->header()->restoreState(initSettings.value("plugin_list_state").toByteArray()); @@ -190,29 +211,28 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget NexusInterface::instance()->setNMMVersion(m_Settings.getNMMVersion()); updateDownloadListDelegate(); - connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), this, SLOT(displayColumnSelection(QPoint))); - - connect(&m_DownloadManager, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString))); - - connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString))); - connect(&m_NexusDialog, SIGNAL(requestDownload(QNetworkReply*, int, QString)), this, SLOT(downloadRequested(QNetworkReply*, int, QString))); ui->savegameList->installEventFilter(this); ui->savegameList->setMouseTracking(true); - connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), - this, SLOT(saveSelectionChanged(QListWidgetItem*))); - connect(&m_PluginList, SIGNAL(saveTimer()), this, SLOT(savePluginList())); + connect(&m_DownloadManager, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString))); + + connect(ui->savegameList, SIGNAL(itemEntered(QListWidgetItem*)), this, SLOT(saveSelectionChanged(QListWidgetItem*))); + connect(&m_ModList, SIGNAL(modorder_changed()), this, SLOT(modorder_changed())); connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString))); connect(&m_ModList, SIGNAL(showMessage(QString)), this, SLOT(showMessage(QString))); connect(&m_ModList, SIGNAL(modRenamed(QString,QString)), this, SLOT(modRenamed(QString,QString))); + 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(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))); + connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), m_PluginListSortProxy, SLOT(updateFilter(QString))); connect(ui->espFilterEdit, SIGNAL(textChanged(QString)), this, SLOT(espFilterChanged(QString))); - connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), this, SLOT(modlistChanged(QModelIndex, int))); - connect(&m_ModList, SIGNAL(removeSelectedMods()), this, SLOT(removeMod_clicked())); + connect(&m_PluginList, SIGNAL(saveTimer()), this, SLOT(savePluginList())); connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this, SLOT(directory_refreshed())); connect(&m_DirectoryRefresher, SIGNAL(progress(int)), this, SLOT(refresher_progress(int))); @@ -220,17 +240,20 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget connect(&m_Settings, SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString))); connect(&m_Settings, SIGNAL(styleChanged(QString)), this, SIGNAL(styleChanged(QString))); - connect(this, SIGNAL(styleChanged(QString)), this, SLOT(updateStyle(QString))); connect(&m_Updater, SIGNAL(restart()), this, SLOT(close())); connect(&m_Updater, SIGNAL(updateAvailable()), this, SLOT(updateAvailable())); connect(&m_Updater, SIGNAL(motdAvailable(QString)), this, SLOT(motdReceived(QString))); + connect(&m_NexusDialog, SIGNAL(requestDownload(QNetworkReply*, int, QString)), this, SLOT(downloadRequested(QNetworkReply*, int, QString))); connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool))); connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString))); + connect(NexusInterface::instance(), SIGNAL(requestNXMDownload(QString)), this, SLOT(downloadRequestedNXM(QString))); connect(&TutorialManager::instance(), SIGNAL(windowTutorialFinished(QString)), this, SLOT(windowTutorialFinished(QString))); + connect(this, SIGNAL(styleChanged(QString)), this, SLOT(updateStyle(QString))); + m_CheckBSATimer.setSingleShot(true); connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList())); @@ -243,7 +266,13 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget FileDialogMemory::restore(initSettings); fixCategories(); - m_Updater.testForUpdate(); + + if (isOnline() && !m_Settings.offlineMode()) { + m_Updater.testForUpdate(); + } else { + qDebug("user doesn't seem to be connected to the internet"); + } + m_StartTime = QTime::currentTime(); m_Tutorial.expose("modList", &m_ModList); @@ -367,8 +396,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")); @@ -409,17 +437,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>")); @@ -452,7 +482,7 @@ bool MainWindow::checkForProblems(QString &problemDescription) } else { ui->actionProblems->setToolTip(tr("Everything seems to be in order")); } - return res; + return res;*/ } @@ -671,6 +701,10 @@ void MainWindow::showEvent(QShowEvent *event) m_Settings.directInterface().setValue("first_start", false); } + + // this has no visible impact when called before the ui is visible + int grouping = m_Settings.directInterface().value("group_state").toInt(); + ui->groupCombo->setCurrentIndex(grouping); } @@ -855,6 +889,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())); } } @@ -865,7 +901,7 @@ void MainWindow::registerPluginTool(IPluginTool *tool) action->setToolTip(tool->tooltip()); tool->setParentWidget(this); action->setData(qVariantFromValue((void*)tool)); - connect(action, SIGNAL(triggered()), this, SLOT(toolPluginInvoke())); + connect(action, SIGNAL(triggered()), this, SLOT(toolPluginInvoke()), Qt::QueuedConnection); QToolButton *toolBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionTool)); toolBtn->menu()->addAction(action); } @@ -876,18 +912,21 @@ bool MainWindow::registerPlugin(QObject *plugin) { // generic treatment for all plugins IPlugin *pluginObj = qobject_cast<IPlugin*>(plugin); if (pluginObj == NULL) { + qDebug("not an IPlugin"); return false; } 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)) { @@ -903,7 +942,27 @@ 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; + } + } + + qDebug("no matching plugin interface"); + + return addon; } @@ -945,14 +1004,28 @@ IGameInfo &MainWindow::gameInfo() const } +IModRepositoryBridge *MainWindow::createNexusBridge() const +{ + return new NexusBridge(); +} + + 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 @@ -979,12 +1052,14 @@ IModInterface *MainWindow::getMod(const QString &name) IModInterface *MainWindow::createMod(const QString &name) { - unsigned int index = ModInfo::getIndex(name); + QString fixedName = name; + fixDirectoryName(fixedName); + unsigned int index = ModInfo::getIndex(fixedName); if (index != UINT_MAX) { - throw MyException(tr("The mod \"%1\" already exists!").arg(name)); + throw MyException(tr("The mod \"%1\" already exists!").arg(fixedName)); } - QString targetDirectory = QDir::fromNativeSeparators(m_Settings.getModDirectory()).append("/").append(name.trimmed()); + QString targetDirectory = QDir::fromNativeSeparators(m_Settings.getModDirectory()).append("/").append(fixedName.trimmed()); QSettings settingsFile(targetDirectory.mid(0).append("/meta.ini"), QSettings::IniFormat); @@ -1012,6 +1087,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() { @@ -1649,9 +1730,6 @@ void MainWindow::readSettings() languageChange(m_Settings.language()); int selectedExecutable = settings.value("selected_executable").toInt(); setExecutableIndex(selectedExecutable); - - int grouping = settings.value("group_state").toInt(); - ui->groupCombo->setCurrentIndex(grouping); } @@ -2490,8 +2568,14 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, { std::vector<ModInfo::EFlag> flags = modInfo->getFlags(); if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) { - OverwriteInfoDialog dialog(modInfo, this); - dialog.exec(); + QDialog *dialog = this->findChild<QDialog*>("__overwriteDialog"); + if (dialog == NULL) { + dialog = new OverwriteInfoDialog(modInfo, this); + dialog->setObjectName("__overwriteDialog"); + } + dialog->show(); + dialog->raise(); + dialog->activateWindow(); } else { ModInfoDialog dialog(modInfo, m_DirectoryStructure, this); connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString))); @@ -2634,6 +2718,17 @@ void MainWindow::testExtractBSA(int modIndex) } +void MainWindow::ignoreMissingData_clicked() +{ + ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); + QDir(info->absolutePath()).mkdir("textures"); + info->testValid(); + connect(this, SIGNAL(modListDataChanged(QModelIndex,QModelIndex)), &m_ModList, SIGNAL(dataChanged(QModelIndex,QModelIndex))); + + emit modListDataChanged(m_ModList.index(m_ContextRow, 0), m_ModList.index(m_ContextRow, m_ModList.columnCount() - 1)); +} + + void MainWindow::visitOnNexus_clicked() { int modID = m_ModList.data(m_ModList.index(m_ContextRow, 0), Qt::UserRole).toInt(); @@ -2674,6 +2769,28 @@ void MainWindow::syncOverwrite() } +void MainWindow::createModFromOverwrite() +{ + QString name = QInputDialog::getText(this, tr("Create Mod..."), + tr("This will move all files from overwrite into a new, regular mod." + "Please enter a name: ")); + QString fixedName = fixDirectoryName(name); + if (fixedName.isEmpty()) { + reportError(tr("Invalid name")); + return; + } else if (getMod(fixedName) != NULL) { + reportError(tr("A mod with this name already exists")); + return; + } + + IModInterface *newMod = createMod(name); + + ModInfo::Ptr overwriteInfo = ModInfo::getByIndex(m_ContextRow); + + shellMove(QStringList(overwriteInfo->absolutePath() + "\\*"), QStringList(newMod->absolutePath()), this); +} + + void MainWindow::cancelModListEditor() { ui->modList->setEnabled(false); @@ -2959,7 +3076,10 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) ModInfo::Ptr info = ModInfo::getByIndex(m_ContextRow); std::vector<ModInfo::EFlag> flags = info->getFlags(); if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_OVERWRITE) != flags.end()) { - menu.addAction(tr("Sync to Mods..."), this, SLOT(syncOverwrite())); + if (QDir(info->absolutePath()).count() > 2) { + menu.addAction(tr("Sync to Mods..."), this, SLOT(syncOverwrite())); + menu.addAction(tr("Create Mod..."), this, SLOT(createModFromOverwrite())); + } } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_BACKUP) != flags.end()) { menu.addAction(tr("Restore Backup"), this, SLOT(restoreBackup_clicked())); menu.addAction(tr("Remove Backup..."), this, SLOT(removeMod_clicked())); @@ -2992,6 +3112,10 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) menu.addAction(action); } break; } + std::vector<ModInfo::EFlag> flags = info->getFlags(); + if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_INVALID) != flags.end()) { + menu.addAction(tr("Ignore missing data"), this, SLOT(ignoreMissingData_clicked())); + } menu.addAction(tr("Visit on Nexus"), this, SLOT(visitOnNexus_clicked())); menu.addAction(tr("Open in explorer"), this, SLOT(openExplorer_clicked())); @@ -3995,11 +4119,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) @@ -4076,25 +4205,30 @@ void MainWindow::on_groupCombo_currentIndexChanged(int index) QAbstractProxyModel *newModel = NULL; switch (index) { case 1: { - newModel = new QtGroupingProxy(m_ModListSortProxy, QModelIndex(), ModList::COL_CATEGORY); + newModel = new QtGroupingProxy(&m_ModList, QModelIndex(), ModList::COL_CATEGORY, Qt::UserRole, + 0, Qt::UserRole + 2); } break; case 2: { - newModel = new QtGroupingProxy(m_ModListSortProxy, QModelIndex(), ModList::COL_MODID); + newModel = new QtGroupingProxy(&m_ModList, QModelIndex(), ModList::COL_MODID, Qt::DisplayRole, + QtGroupingProxy::FLAG_NOGROUPNAME | QtGroupingProxy::FLAG_NOSINGLE, + Qt::UserRole + 2); } break; default: { newModel = NULL; } break; } - if (newModel != NULL) { - newModel->setSourceModel(m_ModListSortProxy); +// newModel->setSourceModel(m_ModListSortProxy); + m_ModListSortProxy->setSourceModel(newModel); connect(ui->modList, SIGNAL(expanded(QModelIndex)),newModel, SLOT(expanded(QModelIndex))); connect(ui->modList, SIGNAL(collapsed(QModelIndex)), newModel, SLOT(collapsed(QModelIndex))); connect(newModel, SIGNAL(expandItem(QModelIndex)), ui->modList, SLOT(expand(QModelIndex))); - ui->modList->setModel(newModel); +// ui->modList->setModel(newModel); } else { - ui->modList->setModel(m_ModListSortProxy); + m_ModListSortProxy->setSourceModel(&m_ModList); +// ui->modList->setModel(m_ModListSortProxy); } +// ui->modList->setModel(m_ModListSortProxy); // ui->modList->setSelectionMode(QAbstractItemView::ExtendedSelection); } |
