summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTannin <devnull@localhost>2014-06-16 21:49:57 +0200
committerTannin <devnull@localhost>2014-06-16 21:49:57 +0200
commit484749e612489336e5bfbe50ddc3cbe307069d4c (patch)
tree296dc49d05a82c4b331f734ef1caa906a0dc5162 /src
parent6d3f88b330f680459146ff1304c4752ffdbd1263 (diff)
- added pseudo-categories to filter for mo-managed vs. unmanaged mods
- deleted mods are now moved to the recycle bin instead of being deleted permanently - reduced modinfo dialog for foreign mods - foreign mods are now displayed with a pseudo-category - added a signal when a plugin is moved - bugfix: refreshing of directory structure for mods with bsas didn't work correctly when enabling a mod and on changing display of foreign mods - bugfix: one mod in the list was assigned the same priority on the directory structure as the data directory - bugfix: conflicts tab in the mod info dialog offered the hide option for files in bsas
Diffstat (limited to 'src')
-rw-r--r--src/categories.h2
-rw-r--r--src/directoryrefresher.cpp53
-rw-r--r--src/directoryrefresher.h26
-rw-r--r--src/mainwindow.cpp149
-rw-r--r--src/mainwindow.h20
-rw-r--r--src/modinfo.cpp2
-rw-r--r--src/modinfodialog.cpp231
-rw-r--r--src/modinfodialog.h7
-rw-r--r--src/modlist.cpp37
-rw-r--r--src/modlistsortproxy.cpp12
-rw-r--r--src/pluginlist.cpp13
-rw-r--r--src/pluginlist.h7
-rw-r--r--src/profile.cpp1
-rw-r--r--src/shared/directoryentry.cpp2
-rw-r--r--src/shared/skyriminfo.cpp2
-rw-r--r--src/version.rc4
16 files changed, 327 insertions, 241 deletions
diff --git a/src/categories.h b/src/categories.h
index 31fccd6d..bfebe1cb 100644
--- a/src/categories.h
+++ b/src/categories.h
@@ -47,6 +47,8 @@ public:
static const int CATEGORY_SPECIAL_NOCATEGORY = 10003;
static const int CATEGORY_SPECIAL_CONFLICT = 10004;
static const int CATEGORY_SPECIAL_NOTENDORSED = 10005;
+ static const int CATEGORY_SPECIAL_MANAGED = 10006;
+ static const int CATEGORY_SPECIAL_UNMANAGED = 10007;
public:
diff --git a/src/directoryrefresher.cpp b/src/directoryrefresher.cpp
index 33bde469..a00907a1 100644
--- a/src/directoryrefresher.cpp
+++ b/src/directoryrefresher.cpp
@@ -63,7 +63,6 @@ void DirectoryRefresher::setMods(const std::vector<std::tuple<QString, QString,
m_EnabledArchives = managedArchives;
}
-
void DirectoryRefresher::cleanStructure(DirectoryEntry *structure)
{
static wchar_t *files[] = { L"meta.ini", L"readme.txt" };
@@ -77,21 +76,27 @@ void DirectoryRefresher::cleanStructure(DirectoryEntry *structure)
}
}
-void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
- , const QString &modName
- , int priority
- , const QString &directory
- , const QStringList &stealFiles
- , const QStringList &archives)
+void DirectoryRefresher::addModBSAToStructure(DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &archives)
{
std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
- std::wstring modNameW = ToWString(modName);
+ foreach (const QString &archive, archives) {
+ QFileInfo fileInfo(archive);
+ if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
+ directoryStructure->addFromBSA(ToWString(modName), directoryW,
+ ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority);
+ }
+ }
+}
+
+void DirectoryRefresher::addModFilesToStructure(DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &stealFiles)
+{
+ std::wstring directoryW = ToWString(QDir::toNativeSeparators(directory));
if (stealFiles.length() > 0) {
// instead of adding all the files of the target directory, we just change the root of the specified
// files to this mod
- directoryStructure->createOrigin(modNameW, directoryW, priority);
+ FilesOrigin origin = directoryStructure->createOrigin(ToWString(modName), directoryW, priority);
foreach (const QString &filename, stealFiles) {
QFileInfo fileInfo(filename);
FileEntry::Ptr file = directoryStructure->findFile(ToWString(fileInfo.fileName()));
@@ -99,30 +104,24 @@ void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
if (file->getOrigin() == 0) {
// replace data as the origin on this bsa
file->removeOrigin(0);
- file->addOrigin(directoryStructure->getOriginByName(modNameW).getID(),
- file->getFileTime(), L"");
+ file->addOrigin(origin.getID(), file->getFileTime(), L"");
}
}
}
} else {
- directoryStructure->addFromOrigin(modNameW, directoryW, priority);
+ directoryStructure->addFromOrigin(ToWString(modName), directoryW, priority);
}
-/* QDir dir(directory);
- QFileInfoList bsaFiles = dir.entryInfoList(QStringList("*.bsa"), QDir::Files);
- foreach (QFileInfo file, bsaFiles) {
- if (m_EnabledArchives.find(file.fileName()) != m_EnabledArchives.end()) {
- directoryStructure->addFromBSA(ToWString(modName), directoryW,
- ToWString(QDir::toNativeSeparators(file.absoluteFilePath())), priority);
- }
- }*/
+}
- foreach (const QString &archive, archives) {
- QFileInfo fileInfo(archive);
- if (m_EnabledArchives.find(fileInfo.fileName()) != m_EnabledArchives.end()) {
- directoryStructure->addFromBSA(modNameW, directoryW,
- ToWString(QDir::toNativeSeparators(fileInfo.absoluteFilePath())), priority);
- }
- }
+void DirectoryRefresher::addModToStructure(DirectoryEntry *directoryStructure
+ , const QString &modName
+ , int priority
+ , const QString &directory
+ , const QStringList &stealFiles
+ , const QStringList &archives)
+{
+ addModFilesToStructure(directoryStructure, modName, priority, directory, stealFiles);
+ addModBSAToStructure(directoryStructure, modName, priority, directory, archives);
}
void DirectoryRefresher::refresh()
diff --git a/src/directoryrefresher.h b/src/directoryrefresher.h
index f828d793..66e85465 100644
--- a/src/directoryrefresher.h
+++ b/src/directoryrefresher.h
@@ -79,13 +79,35 @@ public:
/**
* @brief add files for a mod to the directory structure, including bsas
+ * @param directoryStructure
* @param modName
- * @param priorityBSA
+ * @param priority
* @param directory
- * @param priorityDir
+ * @param stealFiles
+ * @param archives
*/
void addModToStructure(MOShared::DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &stealFiles, const QStringList &archives);
+ /**
+ * @brief add only the bsas of a mod to the directory structure
+ * @param directoryStructure
+ * @param modName
+ * @param priority
+ * @param directory
+ * @param archives
+ */
+ void addModBSAToStructure(MOShared::DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &archives);
+
+ /**
+ * @brief add only regular files ofr a mod to the directory structure
+ * @param directoryStructure
+ * @param modName
+ * @param priority
+ * @param directory
+ * @param stealFiles
+ */
+ void addModFilesToStructure(MOShared::DirectoryEntry *directoryStructure, const QString &modName, int priority, const QString &directory, const QStringList &stealFiles);
+
public slots:
/**
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index b12f0706..c6413fc1 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -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()
@@ -1148,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
@@ -1418,10 +1431,8 @@ void MainWindow::setExecutableIndex(int index)
} else {
executableBox->setCurrentIndex(1);
}
-
}
-
void MainWindow::activateSelectedProfile()
{
QString profileName = ui->profileBox->currentText();
@@ -1440,7 +1451,6 @@ void MainWindow::activateSelectedProfile()
refreshModList();
}
-
void MainWindow::on_profileBox_currentIndexChanged(int index)
{
if (ui->profileBox->isEnabled()) {
@@ -1646,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()) {
@@ -1658,7 +1666,6 @@ std::set<QString> MainWindow::enabledArchives()
return result;
}
-
void MainWindow::refreshDirectoryStructure()
{
m_DirectoryUpdate = true;
@@ -1672,7 +1679,6 @@ void MainWindow::refreshDirectoryStructure()
QTimer::singleShot(0, &m_DirectoryRefresher, SLOT(refresh()));
}
-
#if QT_VERSION >= 0x050000
extern QPixmap qt_pixmapFromWinHICON(HICON icon);
#else
@@ -1692,7 +1698,6 @@ QIcon MainWindow::iconForExecutable(const QString &filePath)
}
}
-
void MainWindow::refreshExecutablesList()
{
QComboBox* executablesList = findChild<QComboBox*>("executablesListBox");
@@ -1806,6 +1811,7 @@ void MainWindow::refreshModList(bool saveChanges)
m_CurrentProfile->writeModlistNow(true);
}
ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign());
+
m_CurrentProfile->refreshModStatus();
m_ModList.notifyChange(-1);
@@ -1969,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;
- }*/
}
}
}
@@ -2632,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
@@ -2645,7 +2641,6 @@ void MainWindow::directory_refreshed()
statusBar()->hide();
}
-
void MainWindow::externalMessage(const QString &message)
{
if (message.left(6).toLower() == "nxm://") {
@@ -2654,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();
@@ -2704,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();
@@ -2723,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
@@ -2911,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);
@@ -2975,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()
{
@@ -3162,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);
@@ -4091,8 +4106,7 @@ void MainWindow::on_actionSettings_triggered()
if ((m_Settings.getModDirectory() != oldModDirectory)
|| (m_Settings.displayForeign() != oldDisplayForeign)) {
- refreshModList();
- refreshLists();
+ profileRefresh();
}
if (m_Settings.getCacheDirectory() != oldCacheDirectory) {
@@ -4244,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));
diff --git a/src/mainwindow.h b/src/mainwindow.h
index da6f4330..ddbb7d6a 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -99,7 +99,6 @@ public:
void readSettings();
bool addProfile();
- void refreshLists();
void refreshBSAList();
void refreshDataTree();
void refreshSaveList();
@@ -127,7 +126,7 @@ public:
void addPrimaryCategoryCandidates(QMenu *primaryCategoryMenu, ModInfo::Ptr info);
- void saveArchiveList();
+ bool saveArchiveList();
void createStdoutPipe(HANDLE *stdOutRead, HANDLE *stdOutWrite);
std::string readFromPipe(HANDLE stdOutRead);
@@ -135,8 +134,12 @@ public:
HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "");
+ void updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo);
+
public slots:
+ void refreshLists();
+
void displayColumnSelection(const QPoint &pos);
void externalMessage(const QString &message);
@@ -260,8 +263,6 @@ private:
void setCategoryListVisible(bool visible);
- void updateProblemsButton();
-
SaveGameGamebryo *getSaveGame(const QString &name);
SaveGameGamebryo *getSaveGame(QListWidgetItem *item);
@@ -287,6 +288,10 @@ private:
std::set<QString> enabledArchives();
+ void scheduleUpdateButton();
+
+ void updateModActiveState(int index, bool active);
+
private:
static const unsigned int PROBLEM_PLUGINSNOTLOADED = 1;
@@ -356,6 +361,7 @@ private:
bool m_ArchivesInit;
QTimer m_CheckBSATimer;
QTimer m_SaveMetaTimer;
+ QTimer m_UpdateProblemsTimer;
QTime m_StartTime;
SaveGameInfoWidget *m_CurrentSaveView;
@@ -478,7 +484,6 @@ private slots:
void modlistChanged(int row);
void nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant userData, QVariant resultData, int requestID);
-// void nxmEndorsementToggled(int, QVariant, QVariant resultData, int);
void nxmDownloadURLs(int modID, int fileID, QVariant userData, QVariant resultData, int requestID);
void nxmRequestFailed(int modID, int fileID, QVariant userData, int requestID, const QString &errorString);
@@ -510,6 +515,9 @@ private slots:
void startExeAction();
void checkBSAList();
+
+ void updateProblemsButton();
+
void saveModMetas();
void updateStyle(const QString &style);
@@ -551,9 +559,9 @@ private slots:
void delayedRemove();
void requestDownload(const QUrl &url, QNetworkReply *reply);
- void profileRefresh();
private slots: // ui slots
+ void profileRefresh();
// actions
void on_actionAdd_Profile_triggered();
void on_actionInstallMod_triggered();
diff --git a/src/modinfo.cpp b/src/modinfo.cpp
index d58e83b2..2dadf2c6 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -756,7 +756,7 @@ void ModInfoRegular::setNeverEndorse()
bool ModInfoRegular::remove()
{
m_MetaInfoChanged = false;
- return shellDelete(QStringList(absolutePath()));
+ return shellDelete(QStringList(absolutePath()), true);
}
void ModInfoRegular::endorse(bool doEndorse)
diff --git a/src/modinfodialog.cpp b/src/modinfodialog.cpp
index dae4cc18..fa8a9a77 100644
--- a/src/modinfodialog.cpp
+++ b/src/modinfodialog.cpp
@@ -60,7 +60,7 @@ bool operator<(const ModFileListWidget &LHS, const ModFileListWidget &RHS)
}
-ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, QWidget *parent)
+ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directory, bool unmanaged, QWidget *parent)
: TutorableDialog("ModInfoDialog", parent), ui(new Ui::ModInfoDialog), m_ModInfo(modInfo),
m_ThumbnailMapper(this), m_RequestStarted(false),
m_DeleteAction(NULL), m_RenameAction(NULL), m_OpenAction(NULL),
@@ -69,54 +69,19 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
ui->setupUi(this);
this->setWindowTitle(modInfo->name());
this->setWindowModality(Qt::WindowModal);
- m_UTF8Codec = QTextCodec::codecForName("utf-8");
-
- QListWidget *textFileList = findChild<QListWidget*>("textFileList");
- QListWidget *iniTweaksList = findChild<QListWidget*>("iniTweaksList");
- QListWidget *activeESPList = findChild<QListWidget*>("activeESPList");
- QListWidget *inactiveESPList = findChild<QListWidget*>("inactiveESPList");
- QTreeWidget *categoriesTree = findChild<QTreeWidget*>("categoriesTree");
- QHBoxLayout *thumbnailArea = findChild<QHBoxLayout*>("thumbnailArea");
-
- m_FileTree = findChild<QTreeView*>("fileTree");
-
- m_RootPath = modInfo->absolutePath();
QString metaFileName = m_RootPath.mid(0).append("/meta.ini");
m_Settings = new QSettings(metaFileName, QSettings::IniFormat);
QLineEdit *modIDEdit = findChild<QLineEdit*>("modIDEdit");
- modIDEdit->setValidator(new QIntValidator(modIDEdit));
- modIDEdit->setText(QString("%1").arg(modInfo->getNexusID()));
+ ui->modIDEdit->setValidator(new QIntValidator(modIDEdit));
+ ui->modIDEdit->setText(QString("%1").arg(modInfo->getNexusID()));
ui->notesEdit->setText(modInfo->notes());
- m_FileSystemModel = new QFileSystemModel(this);
- m_FileSystemModel->setReadOnly(false);
- m_FileSystemModel->setRootPath(m_RootPath);
- m_FileTree->setModel(m_FileSystemModel);
- m_FileTree->setRootIndex(m_FileSystemModel->index(m_RootPath));
- m_FileTree->setColumnWidth(0, 300);
-
connect(&m_ThumbnailMapper, SIGNAL(mapped(const QString&)), this, SIGNAL(thumbnailClickedSignal(const QString&)));
connect(this, SIGNAL(thumbnailClickedSignal(const QString&)), this, SLOT(thumbnailClicked(const QString&)));
-
- m_DeleteAction = new QAction(tr("&Delete"), m_FileTree);
- m_RenameAction = new QAction(tr("&Rename"), m_FileTree);
- m_HideAction = new QAction(tr("&Hide"), m_FileTree);
- m_UnhideAction = new QAction(tr("&Unhide"), m_FileTree);
- m_OpenAction = new QAction(tr("&Open"), m_FileTree);
- m_NewFolderAction = new QAction(tr("&New Folder"), m_FileTree);
- QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
- QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
- QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
- QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
- QObject::connect(m_HideAction, SIGNAL(triggered()), this, SLOT(hideTriggered()));
- connect(m_UnhideAction, SIGNAL(triggered()), this, SLOT(unhideTriggered()));
connect(m_ModInfo.data(), SIGNAL(modDetailsUpdated(bool)), this, SLOT(modDetailsUpdated(bool)));
-
-// ui->descriptionView->setLinkDelegationPolicy(QWebPage::DelegateAllLinks);
-// QObject::connect(ui->descriptionView, SIGNAL(linkClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
connect(ui->descriptionView, SIGNAL(anchorClicked(QUrl)), this, SLOT(linkClicked(QUrl)));
if (directory->originExists(ToWString(modInfo->name()))) {
@@ -126,32 +91,39 @@ ModInfoDialog::ModInfoDialog(ModInfo::Ptr modInfo, const DirectoryEntry *directo
}
}
- addCategories(CategoryFactory::instance(), modInfo->getCategories(), categoriesTree->invisibleRootItem(), 0);
- refreshPrimaryCategoriesBox();
- refreshLists();
-
- int numTweaks = m_Settings->beginReadArray("INI Tweaks");
- for (int i = 0; i < numTweaks; ++i) {
- m_Settings->setArrayIndex(i);
- QList<QListWidgetItem*> items = iniTweaksList->findItems(m_Settings->value("name").toString(), Qt::MatchFixedString);
- if (items.size() != 0) {
- items.at(0)->setCheckState(Qt::Checked);
- }
+ if (unmanaged) {
+ ui->tabWidget->setTabEnabled(TAB_INIFILES, false);
+ ui->tabWidget->setTabEnabled(TAB_CATEGORIES, false);
+ ui->tabWidget->setTabEnabled(TAB_NEXUS, false);
+ ui->tabWidget->setTabEnabled(TAB_FILETREE, false);
+ ui->tabWidget->setTabEnabled(TAB_NOTES, false);
+ } else {
+ initFiletree(modInfo);
+ initINITweaks();
+ addCategories(CategoryFactory::instance(), modInfo->getCategories(), ui->categoriesTree->invisibleRootItem(), 0);
+ refreshPrimaryCategoriesBox();
}
- m_Settings->endArray();
+ refreshLists();
- QTabWidget *tabWidget = findChild<QTabWidget*>("tabWidget");
- tabWidget->setTabEnabled(TAB_TEXTFILES, textFileList->count() != 0);
- tabWidget->setTabEnabled(TAB_IMAGES, thumbnailArea->count() != 0);
- tabWidget->setTabEnabled(TAB_ESPS, (inactiveESPList->count() != 0) || (activeESPList->count() != 0));
- tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != NULL);
+ ui->tabWidget->setTabEnabled(TAB_TEXTFILES, ui->textFileList->count() != 0);
+ ui->tabWidget->setTabEnabled(TAB_IMAGES, ui->thumbnailArea->count() != 0);
+ ui->tabWidget->setTabEnabled(TAB_ESPS, (ui->inactiveESPList->count() != 0) || (ui->activeESPList->count() != 0));
+ ui->tabWidget->setTabEnabled(TAB_CONFLICTS, m_Origin != NULL);
- if (tabWidget->currentIndex() == TAB_NEXUS) {
+ if (ui->tabWidget->currentIndex() == TAB_NEXUS) {
activateNexusTab();
}
ui->endorseBtn->setEnabled((m_ModInfo->endorsedState() == ModInfo::ENDORSED_FALSE) ||
(m_ModInfo->endorsedState() == ModInfo::ENDORSED_NEVER));
+
+ // activate first enabled tab
+ for (int i = 0; i < ui->tabWidget->count(); ++i) {
+ if (ui->tabWidget->isTabEnabled(i)) {
+ ui->tabWidget->setCurrentIndex(i);
+ break;
+ }
+ }
}
@@ -165,6 +137,46 @@ ModInfoDialog::~ModInfoDialog()
}
+void ModInfoDialog::initINITweaks()
+{
+ int numTweaks = m_Settings->beginReadArray("INI Tweaks");
+ for (int i = 0; i < numTweaks; ++i) {
+ m_Settings->setArrayIndex(i);
+ QList<QListWidgetItem*> items = ui->iniTweaksList->findItems(m_Settings->value("name").toString(), Qt::MatchFixedString);
+ if (items.size() != 0) {
+ items.at(0)->setCheckState(Qt::Checked);
+ }
+ }
+ m_Settings->endArray();
+}
+
+void ModInfoDialog::initFiletree(ModInfo::Ptr modInfo)
+{
+ m_RootPath = modInfo->absolutePath();
+ ui->fileTree = findChild<QTreeView*>("fileTree");
+
+ m_FileSystemModel = new QFileSystemModel(this);
+ m_FileSystemModel->setReadOnly(false);
+ m_FileSystemModel->setRootPath(m_RootPath);
+ ui->fileTree->setModel(m_FileSystemModel);
+ ui->fileTree->setRootIndex(m_FileSystemModel->index(m_RootPath));
+ ui->fileTree->setColumnWidth(0, 300);
+
+ m_DeleteAction = new QAction(tr("&Delete"), ui->fileTree);
+ m_RenameAction = new QAction(tr("&Rename"), ui->fileTree);
+ m_HideAction = new QAction(tr("&Hide"), ui->fileTree);
+ m_UnhideAction = new QAction(tr("&Unhide"), ui->fileTree);
+ m_OpenAction = new QAction(tr("&Open"), ui->fileTree);
+ m_NewFolderAction = new QAction(tr("&New Folder"), ui->fileTree);
+ QObject::connect(m_DeleteAction, SIGNAL(triggered()), this, SLOT(deleteTriggered()));
+ QObject::connect(m_RenameAction, SIGNAL(triggered()), this, SLOT(renameTriggered()));
+ QObject::connect(m_OpenAction, SIGNAL(triggered()), this, SLOT(openTriggered()));
+ QObject::connect(m_NewFolderAction, SIGNAL(triggered()), this, SLOT(createDirectoryTriggered()));
+ QObject::connect(m_HideAction, SIGNAL(triggered()), this, SLOT(hideTriggered()));
+ connect(m_UnhideAction, SIGNAL(triggered()), this, SLOT(unhideTriggered()));
+}
+
+
int ModInfoDialog::tabIndex(const QString &tabId)
{
for (int i = 0; i < ui->tabWidget->count(); ++i) {
@@ -271,51 +283,52 @@ void ModInfoDialog::refreshLists()
}
}
+ if (m_RootPath.length() > 0) {
+ QDirIterator dirIterator(m_RootPath, QDir::Files, QDirIterator::Subdirectories);
+ while (dirIterator.hasNext()) {
+ QString fileName = dirIterator.next();
- QDirIterator dirIterator(m_RootPath, QDir::Files, QDirIterator::Subdirectories);
- while (dirIterator.hasNext()) {
- QString fileName = dirIterator.next();
-
- if (fileName.endsWith(".txt", Qt::CaseInsensitive)) {
- ui->textFileList->addItem(fileName.mid(m_RootPath.length() + 1));
- } else if ((fileName.endsWith(".ini", Qt::CaseInsensitive) || fileName.endsWith(".cfg", Qt::CaseInsensitive)) &&
- !fileName.endsWith("meta.ini")) {
- QString namePart = fileName.mid(m_RootPath.length() + 1);
- if (namePart.startsWith("INI Tweaks", Qt::CaseInsensitive)) {
- QListWidgetItem *newItem = new QListWidgetItem(namePart.mid(11), ui->iniTweaksList);
- newItem->setData(Qt::UserRole, namePart);
- newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable);
- newItem->setCheckState(Qt::Unchecked);
- ui->iniTweaksList->addItem(newItem);
- } else {
- ui->iniFileList->addItem(namePart);
- }
- } else if (fileName.endsWith(".esp", Qt::CaseInsensitive) ||
- fileName.endsWith(".esm", Qt::CaseInsensitive)) {
- QString relativePath = fileName.mid(m_RootPath.length() + 1);
- if (relativePath.contains('/')) {
- QFileInfo fileInfo(fileName);
- QListWidgetItem *newItem = new QListWidgetItem(fileInfo.fileName());
- newItem->setData(Qt::UserRole, relativePath);
- ui->inactiveESPList->addItem(newItem);
- } else {
- ui->activeESPList->addItem(relativePath);
- }
- } else if ((fileName.endsWith(".png", Qt::CaseInsensitive)) ||
- (fileName.endsWith(".jpg", Qt::CaseInsensitive))) {
- QImage image = QImage(fileName);
- if (!image.isNull()) {
- if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
- image = image.scaledToWidth(128);
+ if (fileName.endsWith(".txt", Qt::CaseInsensitive)) {
+ ui->textFileList->addItem(fileName.mid(m_RootPath.length() + 1));
+ } else if ((fileName.endsWith(".ini", Qt::CaseInsensitive) || fileName.endsWith(".cfg", Qt::CaseInsensitive)) &&
+ !fileName.endsWith("meta.ini")) {
+ QString namePart = fileName.mid(m_RootPath.length() + 1);
+ if (namePart.startsWith("INI Tweaks", Qt::CaseInsensitive)) {
+ QListWidgetItem *newItem = new QListWidgetItem(namePart.mid(11), ui->iniTweaksList);
+ newItem->setData(Qt::UserRole, namePart);
+ newItem->setFlags(newItem->flags() | Qt::ItemIsUserCheckable);
+ newItem->setCheckState(Qt::Unchecked);
+ ui->iniTweaksList->addItem(newItem);
+ } else {
+ ui->iniFileList->addItem(namePart);
+ }
+ } else if (fileName.endsWith(".esp", Qt::CaseInsensitive) ||
+ fileName.endsWith(".esm", Qt::CaseInsensitive)) {
+ QString relativePath = fileName.mid(m_RootPath.length() + 1);
+ if (relativePath.contains('/')) {
+ QFileInfo fileInfo(fileName);
+ QListWidgetItem *newItem = new QListWidgetItem(fileInfo.fileName());
+ newItem->setData(Qt::UserRole, relativePath);
+ ui->inactiveESPList->addItem(newItem);
} else {
- image = image.scaledToHeight(96);
+ ui->activeESPList->addItem(relativePath);
}
+ } else if ((fileName.endsWith(".png", Qt::CaseInsensitive)) ||
+ (fileName.endsWith(".jpg", Qt::CaseInsensitive))) {
+ QImage image = QImage(fileName);
+ if (!image.isNull()) {
+ if (static_cast<float>(image.width()) / static_cast<float>(image.height()) > 1.34) {
+ image = image.scaledToWidth(128);
+ } else {
+ image = image.scaledToHeight(96);
+ }
- QPushButton *thumbnailButton = new QPushButton(QPixmap::fromImage(image), "");
- thumbnailButton->setIconSize(QSize(image.width(), image.height()));
- connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map()));
- m_ThumbnailMapper.setMapping(thumbnailButton, fileName);
- ui->thumbnailArea->addWidget(thumbnailButton);
+ QPushButton *thumbnailButton = new QPushButton(QPixmap::fromImage(image), "");
+ thumbnailButton->setIconSize(QSize(image.width(), image.height()));
+ connect(thumbnailButton, SIGNAL(clicked()), &m_ThumbnailMapper, SLOT(map()));
+ m_ThumbnailMapper.setMapping(thumbnailButton, fileName);
+ ui->thumbnailArea->addWidget(thumbnailButton);
+ }
}
}
}
@@ -460,7 +473,8 @@ void ModInfoDialog::openIniFile(const QString &fileName)
QFile iniFile(fileName);
iniFile.open(QIODevice::ReadOnly);
QByteArray buffer = iniFile.readAll();
- QTextCodec *codec = QTextCodec::codecForUtfText(buffer, m_UTF8Codec);
+
+ QTextCodec *codec = QTextCodec::codecForUtfText(buffer, QTextCodec::codecForName("utf-8"));
QTextEdit *iniFileView = findChild<QTextEdit*>("iniFileView");
iniFileView->setText(codec->toUnicode(buffer));
iniFileView->setProperty("currentFile", fileName);
@@ -929,7 +943,7 @@ void ModInfoDialog::renameTriggered()
return;
}
- m_FileTree->edit(index);
+ ui->fileTree->edit(index);
}
@@ -999,18 +1013,18 @@ void ModInfoDialog::createDirectoryTriggered()
return;
}
- m_FileTree->setCurrentIndex(newIndex);
- m_FileTree->edit(newIndex);
+ ui->fileTree->setCurrentIndex(newIndex);
+ ui->fileTree->edit(newIndex);
}
void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
{
- QItemSelectionModel *selectionModel = m_FileTree->selectionModel();
+ QItemSelectionModel *selectionModel = ui->fileTree->selectionModel();
m_FileSelection = selectionModel->selectedRows(0);
-// m_FileSelection = m_FileTree->indexAt(pos);
- QMenu menu(m_FileTree);
+// m_FileSelection = ui->fileTree->indexAt(pos);
+ QMenu menu(ui->fileTree);
menu.addAction(m_NewFolderAction);
@@ -1038,7 +1052,7 @@ void ModInfoDialog::on_fileTree_customContextMenuRequested(const QPoint &pos)
m_FileSelection.clear();
m_FileSelection.append(m_FileSystemModel->index(m_FileSystemModel->rootPath(), 0));
}
- menu.exec(m_FileTree->mapToGlobal(pos));
+ menu.exec(ui->fileTree->mapToGlobal(pos));
}
@@ -1164,18 +1178,17 @@ void ModInfoDialog::on_overwriteTree_customContextMenuRequested(const QPoint &po
{
m_ConflictsContextItem = ui->overwriteTree->itemAt(pos.x(), pos.y());
- QMenu menu;
if (m_ConflictsContextItem != NULL) {
// offer to hide/unhide file, but not for files from archives
-// if (!m_ConflictsContextItem->data(0, Qt::UserRole + 1).toBool()) {
- if (!m_ConflictsContextItem->data(0, Qt::UserRole + 2).toBool()) {
+ if (!m_ConflictsContextItem->data(1, Qt::UserRole + 2).toBool()) {
+ QMenu menu;
if (m_ConflictsContextItem->text(0).endsWith(ModInfo::s_HiddenExt)) {
menu.addAction(tr("Un-Hide"), this, SLOT(unhideConflictFile()));
} else {
menu.addAction(tr("Hide"), this, SLOT(hideConflictFile()));
}
+ menu.exec(ui->overwriteTree->mapToGlobal(pos));
}
- menu.exec(ui->overwriteTree->mapToGlobal(pos));
}
}
diff --git a/src/modinfodialog.h b/src/modinfodialog.h
index edfe59cf..63875b70 100644
--- a/src/modinfodialog.h
+++ b/src/modinfodialog.h
@@ -65,6 +65,7 @@ public:
TAB_CONFLICTS,
TAB_CATEGORIES,
TAB_NEXUS,
+ TAB_NOTES,
TAB_FILETREE
};
@@ -76,7 +77,7 @@ public:
* @param modInfo info structure about the mod to display
* @param parent parend widget
**/
- explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, QWidget *parent = 0);
+ explicit ModInfoDialog(ModInfo::Ptr modInfo, const MOShared::DirectoryEntry *directory, bool unmanaged, QWidget *parent = 0);
~ModInfoDialog();
/**
@@ -121,6 +122,9 @@ public slots:
private:
+ void initFiletree(ModInfo::Ptr modInfo);
+ void initINITweaks();
+
void refreshLists();
void addCategories(const CategoryFactory &factory, const std::set<int> &enabledCategories, QTreeWidgetItem *root, int rootLevel);
@@ -225,7 +229,6 @@ private:
const MOShared::DirectoryEntry *m_Directory;
MOShared::FilesOrigin *m_Origin;
- QTextCodec *m_UTF8Codec;
std::map<int, int> m_RealTabPos;
diff --git a/src/modlist.cpp b/src/modlist.cpp
index e4728618..3f46b85f 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -166,25 +166,29 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
return QVariant();
}
} else if (column == COL_CATEGORY) {
- int category = modInfo->getPrimaryCategory();
- if (category != -1) {
- CategoryFactory &categoryFactory = CategoryFactory::instance();
- if (categoryFactory.categoryExists(category)) {
- try {
- int categoryIdx = categoryFactory.getCategoryIndex(category);
- return categoryFactory.getCategoryName(categoryIdx);
- } catch (const std::exception &e) {
- qCritical("failed to retrieve category name: %s", e.what());
+ if (modInfo->hasFlag(ModInfo::FLAG_FOREIGN)) {
+ return tr("Non-MO");
+ } else {
+ int category = modInfo->getPrimaryCategory();
+ if (category != -1) {
+ CategoryFactory &categoryFactory = CategoryFactory::instance();
+ if (categoryFactory.categoryExists(category)) {
+ try {
+ int categoryIdx = categoryFactory.getCategoryIndex(category);
+ return categoryFactory.getCategoryName(categoryIdx);
+ } catch (const std::exception &e) {
+ qCritical("failed to retrieve category name: %s", e.what());
+ return QString();
+ }
+ } else {
+ qWarning("category %d doesn't exist (may have been removed)", category);
+ modInfo->setCategory(category, false);
return QString();
}
} else {
- qWarning("category %d doesn't exist (may have been removed)", category);
- modInfo->setCategory(category, false);
- return QString();
+ //return tr("None");
+ return QVariant();
}
- } else {
- //return tr("None");
- return QVariant();
}
} else if (column == COL_INSTALLTIME) {
// display installation time for mods that can be updated
@@ -253,6 +257,8 @@ QVariant ModList::data(const QModelIndex &modelIndex, int role) const
if (modInfo->getHighlight() & ModInfo::HIGHLIGHT_INVALID) {
result.setItalic(true);
}
+ } else if ((column == COL_CATEGORY) && (modInfo->hasFlag(ModInfo::FLAG_FOREIGN))) {
+ result.setItalic(true);
} else if (column == COL_VERSION) {
if (modInfo->updateAvailable() || modInfo->downgradeAvailable()) {
result.setWeight(QFont::Bold);
@@ -650,7 +656,6 @@ bool ModList::setPriority(const QString &name, int newPriority)
}
}
-
bool ModList::onModStateChanged(const std::function<void (const QString &, IModList::ModStates)> &func)
{
auto conn = m_ModStateChanged.connect(func);
diff --git a/src/modlistsortproxy.cpp b/src/modlistsortproxy.cpp
index 3aadaa53..88b7bef0 100644
--- a/src/modlistsortproxy.cpp
+++ b/src/modlistsortproxy.cpp
@@ -248,6 +248,12 @@ bool ModListSortProxy::filterMatchesModAnd(ModInfo::Ptr info, bool enabled) cons
ModInfo::EEndorsedState state = info->endorsedState();
if (state != ModInfo::ENDORSED_FALSE) return false;
} break;
+ case CategoryFactory::CATEGORY_SPECIAL_MANAGED: {
+ if (info->hasFlag(ModInfo::FLAG_FOREIGN)) return false;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UNMANAGED: {
+ if (!info->hasFlag(ModInfo::FLAG_FOREIGN)) return false;
+ } break;
default: {
if (!info->categorySet(*iter)) return false;
} break;
@@ -279,6 +285,12 @@ bool ModListSortProxy::filterMatchesModOr(ModInfo::Ptr info, bool enabled) const
ModInfo::EEndorsedState state = info->endorsedState();
if ((state == ModInfo::ENDORSED_FALSE) && (state != ModInfo::ENDORSED_NEVER)) return true;
} break;
+ case CategoryFactory::CATEGORY_SPECIAL_MANAGED: {
+ if (!info->hasFlag(ModInfo::FLAG_FOREIGN)) return true;
+ } break;
+ case CategoryFactory::CATEGORY_SPECIAL_UNMANAGED: {
+ if (info->hasFlag(ModInfo::FLAG_FOREIGN)) return true;
+ } break;
default: {
if (info->categorySet(*iter)) return true;
} break;
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index 79df08ae..4f363900 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -216,12 +216,12 @@ void PluginList::refresh(const QString &profileName, const DirectoryEntry &baseD
}
-void PluginList::enableESP(const QString &name)
+void PluginList::enableESP(const QString &name, bool enable)
{
std::map<QString, int>::iterator iter = m_ESPsByName.find(name.toLower());
if (iter != m_ESPsByName.end()) {
- m_ESPs[iter->second].m_Enabled = true;
+ m_ESPs[iter->second].m_Enabled = enable;
startSaveTime();
} else {
reportError(tr("esp not found: %1").arg(name));
@@ -677,6 +677,14 @@ bool PluginList::onRefreshed(const std::function<void ()> &callback)
return conn.connected();
}
+
+bool PluginList::onPluginMoved(const std::function<void (const QString &, int, int)> &func)
+{
+ auto conn = m_PluginMoved.connect(func);
+ return conn.connected();
+}
+
+
void PluginList::updateIndices()
{
m_ESPsByName.clear();
@@ -947,6 +955,7 @@ void PluginList::setPluginPriority(int row, int &newPriority)
m_ESPs.at(row).m_Priority = newPriorityTemp;
emit dataChanged(index(row, 0), index(row, columnCount()));
+ m_PluginMoved(m_ESPs[row].m_Name, oldPriority, newPriorityTemp);
} catch (const std::out_of_range&) {
reportError(tr("failed to restore load order for %1").arg(m_ESPs[row].m_Name));
}
diff --git a/src/pluginlist.h b/src/pluginlist.h
index 9421d894..57b78a12 100644
--- a/src/pluginlist.h
+++ b/src/pluginlist.h
@@ -86,6 +86,7 @@ public:
};
typedef boost::signals2::signal<void ()> SignalRefreshed;
+ typedef boost::signals2::signal<void (const QString &, int, int)> SignalPluginMoved;
public:
@@ -118,8 +119,9 @@ public:
* @brief enable a plugin based on its name
*
* @param name name of the plugin to enable
+ * @param enable set to true to enable the esp, false to disable it
**/
- void enableESP(const QString &name);
+ void enableESP(const QString &name, bool enable = true);
/**
* @brief test if a plugin is enabled
@@ -218,6 +220,7 @@ public:
virtual bool isMaster(const QString &name) const;
virtual QString origin(const QString &name) const;
virtual bool onRefreshed(const std::function<void()> &callback);
+ virtual bool onPluginMoved(const std::function<void (const QString &, int, int)> &func);
public: // implementation of the QAbstractTableModel interface
@@ -332,6 +335,8 @@ private:
QTemporaryFile m_TempFile;
+ SignalPluginMoved m_PluginMoved;
+
};
diff --git a/src/profile.cpp b/src/profile.cpp
index c3d9a0c4..50e6c3b2 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -419,7 +419,6 @@ void Profile::setModEnabled(unsigned int index, bool enabled)
// overwrite is always enabled
return;
}
-
if (enabled != m_ModStatus[index].m_Enabled) {
m_ModStatus[index].m_Enabled = enabled;
emit modStatusChanged(index);
diff --git a/src/shared/directoryentry.cpp b/src/shared/directoryentry.cpp
index b7863284..5172346b 100644
--- a/src/shared/directoryentry.cpp
+++ b/src/shared/directoryentry.cpp
@@ -219,7 +219,6 @@ void FilesOrigin::setName(const std::wstring &name)
std::vector<FileEntry::Ptr> FilesOrigin::getFiles() const
{
std::vector<FileEntry::Ptr> result;
-
for (auto iter = m_Files.begin(); iter != m_Files.end(); ++iter) {
result.push_back(m_FileRegister.lock()->getFile(*iter));
}
@@ -228,7 +227,6 @@ std::vector<FileEntry::Ptr> FilesOrigin::getFiles() const
}
-
//
// FileEntry
//
diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp
index 00cdd4d0..5711e2fd 100644
--- a/src/shared/skyriminfo.cpp
+++ b/src/shared/skyriminfo.cpp
@@ -221,9 +221,7 @@ void SkyrimInfo::createProfile(const std::wstring &directory, bool useDefaults)
if (!FileExists(target)) {
std::wostringstream source;
source << getLocalAppFolder() << "\\Skyrim\\plugins.txt";
-printf("copy %ls -> %ls\n", source.str().c_str(), target.c_str());
if (!::CopyFileW(source.str().c_str(), target.c_str(), true)) {
-printf("failed to copy plugins.txt!");
HANDLE file = ::CreateFileW(target.c_str(), GENERIC_WRITE, 0, NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL);
::CloseHandle(file);
}
diff --git a/src/version.rc b/src/version.rc
index 82484925..f589769d 100644
--- a/src/version.rc
+++ b/src/version.rc
@@ -1,7 +1,7 @@
#include "Winver.h"
-#define VER_FILEVERSION 1,2,3,0
-#define VER_FILEVERSION_STR "1,2,3,0\0"
+#define VER_FILEVERSION 1,2,5,0
+#define VER_FILEVERSION_STR "1,2,5,0\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION