diff options
Diffstat (limited to 'src/mainwindow.cpp')
| -rw-r--r-- | src/mainwindow.cpp | 226 |
1 files changed, 131 insertions, 95 deletions
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8fcd4024..c6413fc1 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -164,7 +164,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget m_Updater(NexusInterface::instance(), this), m_CategoryFactory(CategoryFactory::instance()), m_CurrentProfile(NULL), m_AskForNexusPW(false), m_ArchivesInit(false), m_ContextItem(NULL), m_ContextAction(NULL), m_CurrentSaveView(NULL), - m_GameInfo(new GameInfoImpl()), m_AboutToRun(), m_ModInstalled() + m_GameInfo(new GameInfoImpl()), m_AboutToRun(), m_ModInstalled(), m_DidUpdateMasterList(false) { ui->setupUi(this); this->setWindowTitle(ToQString(GameInfo::instance().getGameName()) + " Mod Organizer v" + m_Updater.getVersion().displayString()); @@ -193,7 +193,7 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget updateToolBar(); - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure); + ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); // set up mod list m_ModListSortProxy = new ModListSortProxy(m_CurrentProfile, this); @@ -320,6 +320,9 @@ MainWindow::MainWindow(const QString &exeName, QSettings &initSettings, QWidget m_CheckBSATimer.setSingleShot(true); connect(&m_CheckBSATimer, SIGNAL(timeout()), this, SLOT(checkBSAList())); + m_UpdateProblemsTimer.setSingleShot(true); + connect(&m_UpdateProblemsTimer, SIGNAL(timeout()), this, SLOT(updateProblemsButton())); + m_SaveMetaTimer.setSingleShot(false); connect(&m_SaveMetaTimer, SIGNAL(timeout()), this, SLOT(saveModMetas())); m_SaveMetaTimer.start(5000); @@ -530,6 +533,14 @@ void MainWindow::updateToolBar() } +void MainWindow::scheduleUpdateButton() +{ + if (!m_UpdateProblemsTimer.isActive()) { + m_UpdateProblemsTimer.start(1000); + } +} + + void MainWindow::updateProblemsButton() { int numProblems = checkForProblems(); @@ -661,7 +672,7 @@ void MainWindow::createHelpWidget() } -void MainWindow::saveArchiveList() +bool MainWindow::saveArchiveList() { if (m_ArchivesInit) { SafeWriteFile archiveFile(m_CurrentProfile->getArchivesFileName()); @@ -680,10 +691,12 @@ void MainWindow::saveArchiveList() } if (archiveFile.commitIfDifferent(m_ArchiveListHash)) { qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_CurrentProfile->getArchivesFileName()))); + return true; } } else { qWarning("archive list not initialised"); } + return false; } void MainWindow::savePluginList() @@ -1034,31 +1047,48 @@ void MainWindow::toolPluginInvoke() void MainWindow::requestDownload(const QUrl &url, QNetworkReply *reply) { QToolButton *browserBtn = qobject_cast<QToolButton*>(ui->toolBar->widgetForAction(ui->actionNexus)); - - QList<QAction*> browserActions = browserBtn->menu()->actions(); - foreach (QAction *action, browserActions) { - // the nexus action doesn't have a plugin connected currently - if (action->data().isValid()) { - IPluginModPage *plugin = qobject_cast<IPluginModPage*>(qvariant_cast<QObject*>(action->data())); - if (plugin == NULL) { - qCritical("invalid mod page. This is a bug"); - continue; - } - ModRepositoryFileInfo *fileInfo = new ModRepositoryFileInfo(); - if (plugin->handlesDownload(url, reply->url(), *fileInfo)) { - fileInfo->repository = plugin->name(); - m_DownloadManager.addDownload(reply, fileInfo); - return; + if (browserBtn->menu() != NULL) { + // go through modpage plugins, find one to handle the download. + QList<QAction*> browserActions = browserBtn->menu()->actions(); + foreach (QAction *action, browserActions) { + // the nexus action doesn't have a plugin connected currently + if (action->data().isValid()) { + IPluginModPage *plugin = qobject_cast<IPluginModPage*>(qvariant_cast<QObject*>(action->data())); + if (plugin == NULL) { + qCritical("invalid mod page. This is a bug"); + continue; + } + ModRepositoryFileInfo *fileInfo = new ModRepositoryFileInfo(); + if (plugin->handlesDownload(url, reply->url(), *fileInfo)) { + fileInfo->repository = plugin->name(); + m_DownloadManager.addDownload(reply, fileInfo); + return; + } } } } - if (QMessageBox::question(this, tr("Download?"), - tr("A download has been started but no installed page plugin recognizes it.\n" - "If you download anyway no information (i.e. version) will be associated with the download.\n" - "Continue?"), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo()); + // no mod found that could handle the download. Is it a nexus mod? + if (url.host() == "www.nexusmods.com") { + int modID = 0; + int fileID = 0; + QRegExp modExp("mods/(\\d+)"); + if (modExp.indexIn(url.toString()) != -1) { + modID = modExp.cap(1).toInt(); + } + QRegExp fileExp("fid=(\\d+)"); + if (fileExp.indexIn(reply->url().toString()) != -1) { + fileID = fileExp.cap(1).toInt(); + } + m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo(modID, fileID)); + } else { + if (QMessageBox::question(this, tr("Download?"), + tr("A download has been started but no installed page plugin recognizes it.\n" + "If you download anyway no information (i.e. version) will be associated with the download.\n" + "Continue?"), + QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { + m_DownloadManager.addDownload(reply, new ModRepositoryFileInfo()); + } } } @@ -1131,7 +1161,7 @@ bool MainWindow::registerPlugin(QObject *plugin, const QString &fileName) IPluginDiagnose *diagnose = qobject_cast<IPluginDiagnose*>(plugin); if (diagnose != NULL) { m_DiagnosisPlugins.push_back(diagnose); - diagnose->onInvalidated([&] () { this->updateProblemsButton(); }); + diagnose->onInvalidated([&] () { this->scheduleUpdateButton(); }); } } { // mod page plugin @@ -1401,10 +1431,8 @@ void MainWindow::setExecutableIndex(int index) } else { executableBox->setCurrentIndex(1); } - } - void MainWindow::activateSelectedProfile() { QString profileName = ui->profileBox->currentText(); @@ -1423,7 +1451,6 @@ void MainWindow::activateSelectedProfile() refreshModList(); } - void MainWindow::on_profileBox_currentIndexChanged(int index) { if (ui->profileBox->isEnabled()) { @@ -1629,8 +1656,6 @@ bool MainWindow::refreshProfiles(bool selectProfile) std::set<QString> MainWindow::enabledArchives() { std::set<QString> result; - - QFile archiveFile(m_CurrentProfile->getArchivesFileName()); if (archiveFile.open(QIODevice::ReadOnly)) { while (!archiveFile.atEnd()) { @@ -1641,7 +1666,6 @@ std::set<QString> MainWindow::enabledArchives() return result; } - void MainWindow::refreshDirectoryStructure() { m_DirectoryUpdate = true; @@ -1655,7 +1679,6 @@ void MainWindow::refreshDirectoryStructure() QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh())); } - #if QT_VERSION >= 0x050000 extern QPixmap qt_pixmapFromWinHICON(HICON icon); #else @@ -1675,7 +1698,6 @@ QIcon MainWindow::iconForExecutable(const QString &filePath) } } - void MainWindow::refreshExecutablesList() { QComboBox* executablesList = findChild<QComboBox*>("executablesListBox"); @@ -1788,7 +1810,8 @@ void MainWindow::refreshModList(bool saveChanges) if (saveChanges) { m_CurrentProfile->writeModlistNow(true); } - ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure); + ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); + m_CurrentProfile->refreshModStatus(); m_ModList.notifyChange(-1); @@ -1952,15 +1975,6 @@ void MainWindow::checkBSAList() item->setIcon(0, QIcon(":/MO/gui/warning")); item->setToolTip(0, tr("This bsa is enabled in the ini file so it may be required!")); modWarning = true; -/* } else { - QString espName = filename.mid(0, filename.length() - 3).append("esp").toLower(); - QString esmName = filename.mid(0, filename.length() - 3).append("esm").toLower(); - if (m_PluginList.isEnabled(espName) || m_PluginList.isEnabled(esmName)) { - item->setIcon(0, QIcon(":/MO/gui/warning")); - item->setToolTip(0, tr("This archive will still be loaded since there is a plugin of the same name but " - "its files will not follow installation order!")); - modWarning = true; - }*/ } } } @@ -2615,7 +2629,6 @@ void MainWindow::directory_refreshed() if (m_CurrentProfile != NULL) { refreshLists(); } -// m_RefreshProgress->setVisible(false); // some problem-reports may rely on the virtual directory tree so they need to be updated // now @@ -2628,7 +2641,6 @@ void MainWindow::directory_refreshed() statusBar()->hide(); } - void MainWindow::externalMessage(const QString &message) { if (message.left(6).toLower() == "nxm://") { @@ -2637,31 +2649,54 @@ void MainWindow::externalMessage(const QString &message) } } +void MainWindow::updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo) +{ + // add files of the bsa to the directory structure + m_DirectoryRefresher.addModFilesToStructure(m_DirectoryStructure + , modInfo->name() + , m_CurrentProfile->getModPriority(index) + , modInfo->absolutePath() + , modInfo->stealFiles() + ); + DirectoryRefresher::cleanStructure(m_DirectoryStructure); + // need to refresh plugin list now so we can activate esps + refreshESPList(); + // activate all esps of the specified mod so the bsas get activated along with it + updateModActiveState(index, true); + // now we need to refresh the bsa list and save it so there is no confusion about what archives are avaiable and active + refreshBSAList(); + saveArchiveList(); + m_DirectoryRefresher.setMods(m_CurrentProfile->getActiveMods(), enabledArchives()); + + // finally also add files from bsas to the directory structure + m_DirectoryRefresher.addModBSAToStructure(m_DirectoryStructure + , modInfo->name() + , m_CurrentProfile->getModPriority(index) + , modInfo->absolutePath() + , modInfo->archives() + ); +} void MainWindow::modStatusChanged(unsigned int index) { try { ModInfo::Ptr modInfo = ModInfo::getByIndex(index); if (m_CurrentProfile->modEnabled(index)) { - m_DirectoryRefresher.addModToStructure(m_DirectoryStructure - , modInfo->name() - , m_CurrentProfile->getModPriority(index) - , modInfo->absolutePath() - , modInfo->stealFiles() - , modInfo->archives()); - DirectoryRefresher::cleanStructure(m_DirectoryStructure); + updateModInDirectoryStructure(index, modInfo); } else { if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) { FilesOrigin &origin = m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())); origin.enable(false); } } + modInfo->clearCaches(); for (unsigned int i = 0; i < m_CurrentProfile->numMods(); ++i) { ModInfo::Ptr modInfo = ModInfo::getByIndex(i); int priority = m_CurrentProfile->getModPriority(i); if (m_DirectoryStructure->originExists(ToWString(modInfo->name()))) { - m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority); + // priorities in the directory structure are one higher because data is 0 + m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority + 1); } } m_DirectoryStructure->getFileRegister()->sortOrigins(); @@ -2687,7 +2722,8 @@ void MainWindow::modorder_changed() int priority = m_CurrentProfile->getModPriority(i); if (m_CurrentProfile->modEnabled(i)) { ModInfo::Ptr modInfo = ModInfo::getByIndex(i); - m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority); + // priorities in the directory structure are one higher because data is 0 + m_DirectoryStructure->getOriginByName(ToWString(modInfo->name())).setPriority(priority + 1); } } refreshBSAList(); @@ -2706,33 +2742,30 @@ void MainWindow::procFinished(int, QProcess::ExitStatus) this->sender()->deleteLater(); } - void MainWindow::profileRefresh() { - m_CurrentProfile->writeModlist(); + // have to refresh mods twice (again in refreshModList), otherwise the refresh isn't complete. Not sure why + ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign()); + m_CurrentProfile->refreshModStatus(); refreshModList(); } - void MainWindow::showMessage(const QString &message) { MessageDialog::showMessage(message, this); } - void MainWindow::showError(const QString &message) { reportError(message); } - void MainWindow::installMod_clicked() { installMod(); } - void MainWindow::renameModInList(QFile &modList, const QString &oldName, const QString &newName) { //TODO this code needs to be merged with ModList::readFrom @@ -2894,6 +2927,8 @@ void MainWindow::refreshFilters() addFilterItem(NULL, tr("<Checked>"), CategoryFactory::CATEGORY_SPECIAL_CHECKED); addFilterItem(NULL, tr("<Unchecked>"), CategoryFactory::CATEGORY_SPECIAL_UNCHECKED); addFilterItem(NULL, tr("<Update>"), CategoryFactory::CATEGORY_SPECIAL_UPDATEAVAILABLE); + addFilterItem(NULL, tr("<Managed by MO>"), CategoryFactory::CATEGORY_SPECIAL_MANAGED); + addFilterItem(NULL, tr("<Managed outside MO>"), CategoryFactory::CATEGORY_SPECIAL_UNMANAGED); addFilterItem(NULL, tr("<No category>"), CategoryFactory::CATEGORY_SPECIAL_NOCATEGORY); addFilterItem(NULL, tr("<Conflicted>"), CategoryFactory::CATEGORY_SPECIAL_CONFLICT); addFilterItem(NULL, tr("<Not Endorsed>"), CategoryFactory::CATEGORY_SPECIAL_NOTENDORSED); @@ -2958,37 +2993,37 @@ void MainWindow::restoreBackup_clicked() } } - -void MainWindow::modlistChanged(const QModelIndex &index, int role) +void MainWindow::updateModActiveState(int index, bool active) { - if (role == Qt::CheckStateRole) { - if (index.data(Qt::CheckStateRole).toBool()) { - ModInfo::Ptr modInfo = ModInfo::getByIndex(index.row()); - - QDir dir(modInfo->absolutePath()); - foreach (const QString &esm, dir.entryList(QStringList("*.esm"), QDir::Files)) { - m_PluginList.enableESP(esm); - } + ModInfo::Ptr modInfo = ModInfo::getByIndex(index); - int enabled = 0; - QStringList esps = dir.entryList(QStringList("*.esp"), QDir::Files); - foreach (const QString &esp, esps) { - if (!m_PluginList.isEnabled(esp)) { - m_PluginList.enableESP(esp); - ++enabled; - } - } - if (enabled > 1) { - MessageDialog::showMessage(tr("Multiple esps activated, please check that they don't conflict."), this); - } - m_PluginList.refreshLoadOrder(); - // immediately save affected lists - savePluginList(); - saveArchiveList(); + QDir dir(modInfo->absolutePath()); + foreach (const QString &esm, dir.entryList(QStringList("*.esm"), QDir::Files)) { + m_PluginList.enableESP(esm, active); + } + int enabled = 0; + QStringList esps = dir.entryList(QStringList("*.esp"), QDir::Files); + foreach (const QString &esp, esps) { + if (active && !m_PluginList.isEnabled(esp)) { + m_PluginList.enableESP(esp, active); + ++enabled; } } + if (active && (enabled > 1)) { + MessageDialog::showMessage(tr("Multiple esps activated, please check that they don't conflict."), this); + } + m_PluginList.refreshLoadOrder(); + // immediately save affected lists + savePluginList(); +// refreshBSAList(); } +void MainWindow::modlistChanged(const QModelIndex&, int) +{ +/* if (role == Qt::CheckStateRole) { + updateModActiveState(index.row(), index.data(Qt::CheckStateRole).toBool()); + }*/ +} void MainWindow::removeMod_clicked() { @@ -3145,12 +3180,9 @@ void MainWindow::displayModInformation(ModInfo::Ptr modInfo, unsigned int index, dialog->raise(); dialog->activateWindow(); connect(dialog, SIGNAL(finished(int)), this, SLOT(overwriteClosed(int))); - } else if (std::find(flags.begin(), flags.end(), ModInfo::FLAG_FOREIGN) != flags.end()) { - // nop - no menu for this file type - return; } else { modInfo->saveMeta(); - ModInfoDialog dialog(modInfo, m_DirectoryStructure, this); + ModInfoDialog dialog(modInfo, m_DirectoryStructure, modInfo->hasFlag(ModInfo::FLAG_FOREIGN), this); connect(&dialog, SIGNAL(nexusLinkActivated(QString)), this, SLOT(nexusLinkActivated(QString))); connect(&dialog, SIGNAL(downloadRequest(QString)), this, SLOT(downloadRequestedNXM(QString))); connect(&dialog, SIGNAL(modOpen(QString, int)), this, SLOT(displayModInformation(QString, int)), Qt::QueuedConnection); @@ -3707,7 +3739,7 @@ void addMenuAsPushButton(QMenu *menu, QMenu *subMenu) QMenu *MainWindow::modListContextMenu() { - QMenu *menu = new QMenu(); + QMenu *menu = new QMenu(this); menu->addAction(tr("Install Mod..."), this, SLOT(installMod_clicked())); menu->addAction(tr("Enable all visible"), this, SLOT(enableVisibleMods())); @@ -3734,7 +3766,6 @@ void MainWindow::on_modList_customContextMenuRequested(const QPoint &pos) if (m_ContextRow == -1) { // no selection menu = allMods; - menu->setParent(this); } else { menu = new QMenu(this); allMods->setTitle(tr("All Mods")); @@ -4057,6 +4088,7 @@ void MainWindow::on_actionSettings_triggered() { QString oldModDirectory(m_Settings.getModDirectory()); QString oldCacheDirectory(m_Settings.getCacheDirectory()); + bool oldDisplayForeign(m_Settings.displayForeign()); bool proxy = m_Settings.useProxy(); m_Settings.query(this); m_InstallationManager.setModsDirectory(m_Settings.getModDirectory()); @@ -4072,9 +4104,9 @@ void MainWindow::on_actionSettings_triggered() } m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers()); - if (m_Settings.getModDirectory() != oldModDirectory) { - refreshModList(); - refreshLists(); + if ((m_Settings.getModDirectory() != oldModDirectory) + || (m_Settings.displayForeign() != oldDisplayForeign)) { + profileRefresh(); } if (m_Settings.getCacheDirectory() != oldCacheDirectory) { @@ -4226,7 +4258,6 @@ void MainWindow::installDownload(int index) MessageDialog::showMessage(tr("Installation successful"), this); refreshModList(); - QModelIndexList posList = m_ModList.match(m_ModList.index(0, 0), Qt::DisplayRole, static_cast<const QString&>(modName)); if (posList.count() == 1) { ui->modList->scrollTo(posList.at(0)); @@ -5254,6 +5285,11 @@ void MainWindow::on_bossButton_clicked() parameters << "--game" << ToQString(GameInfo::instance().getGameShortName()) << "--gamePath" << QString("\"%1\"").arg(ToQString(GameInfo::instance().getGameDirectory())); + if (!m_DidUpdateMasterList) { + parameters << "--updateMasterlist"; + m_DidUpdateMasterList = true; + } + HANDLE stdOutWrite = INVALID_HANDLE_VALUE; HANDLE stdOutRead = INVALID_HANDLE_VALUE; createStdoutPipe(&stdOutRead, &stdOutWrite); |
