summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTannin <devnull@localhost>2015-03-01 11:28:49 +0100
committerTannin <devnull@localhost>2015-03-01 11:28:49 +0100
commitd08e0ebab09b0a71c3042cd20b8994ec1c10a525 (patch)
tree326a75bae849f2e2ed42cba0914933437bb92f89 /src
parent6479f972dccaabb3afadb570583a4269e8a785e4 (diff)
- some fixes to how file changes are signaled and delayed
Diffstat (limited to 'src')
-rw-r--r--src/iuserinterface.h4
-rw-r--r--src/mainwindow.cpp31
-rw-r--r--src/mainwindow.h8
-rw-r--r--src/modlist.cpp153
-rw-r--r--src/modlist.h8
-rw-r--r--src/modlistview.cpp1
-rw-r--r--src/modlistview.h1
-rw-r--r--src/organizercore.cpp26
-rw-r--r--src/organizercore.h5
-rw-r--r--src/plugincontainer.cpp3
-rw-r--r--src/pluginlist.cpp42
-rw-r--r--src/pluginlist.h10
-rw-r--r--src/profile.cpp51
-rw-r--r--src/profile.h17
-rw-r--r--src/version.rc4
15 files changed, 162 insertions, 202 deletions
diff --git a/src/iuserinterface.h b/src/iuserinterface.h
index ff683bce..bcf800b7 100644
--- a/src/iuserinterface.h
+++ b/src/iuserinterface.h
@@ -5,6 +5,7 @@
#include "modinfo.h"
#include <iplugintool.h>
#include <ipluginmodpage.h>
+#include <delayedfilewriter.h>
class IUserInterface
@@ -27,12 +28,13 @@ public:
virtual void updateBSAList(const QStringList &defaultArchives, const QStringList &activeArchives) = 0;
- virtual bool saveArchiveList() = 0;
+ virtual MOBase::DelayedFileWriterBase &archivesWriter() = 0;
virtual void lock() = 0;
virtual void unlock() = 0;
virtual bool unlockClicked() = 0;
+
};
#endif // IUSERINTERFACE_H
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index af654e2f..9aa26db6 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -160,6 +160,7 @@ MainWindow::MainWindow(const QString &exeName
, m_OrganizerCore(organizerCore)
, m_PluginContainer(pluginContainer)
, m_DidUpdateMasterList(false)
+ , m_ArchiveListWriter(std::bind(&MainWindow::saveArchiveList, this))
{
ui->setupUi(this);
this->setWindowTitle(ToQString(GameInfo::instance().getGameName()) + " Mod Organizer v" + m_OrganizerCore.getVersion().displayString());
@@ -1846,8 +1847,8 @@ void MainWindow::modorder_changed()
}
}
m_OrganizerCore.refreshBSAList();
- m_OrganizerCore.currentProfile()->writeModlist();
- saveArchiveList();
+ m_OrganizerCore.currentProfile()->modlistWriter().write();
+ m_ArchiveListWriter.write();
m_OrganizerCore.directoryStructure()->getFileRegister()->sortOrigins();
{ // refresh selection
@@ -1981,13 +1982,6 @@ void MainWindow::modRenamed(const QString &oldName, const QString &newName)
}
}
-
-void MainWindow::modlistChanged(int)
-{
- m_ModListSortProxy->invalidate();
-}
-
-
void MainWindow::fileMoved(const QString &filePath, const QString &oldOriginName, const QString &newOriginName)
{
const FileEntry::Ptr filePtr = m_OrganizerCore.directoryStructure()->findFile(ToWString(filePath));
@@ -2139,7 +2133,7 @@ void MainWindow::restoreBackup_clicked()
void MainWindow::modlistChanged(const QModelIndex&, int)
{
- m_OrganizerCore.currentProfile()->writeModlist();
+ m_OrganizerCore.currentProfile()->modlistWriter().write();
}
void MainWindow::modlistSelectionChanged(const QModelIndex &current, const QModelIndex&)
@@ -2150,10 +2144,10 @@ void MainWindow::modlistSelectionChanged(const QModelIndex &current, const QMode
} else {
m_OrganizerCore.modList()->setOverwriteMarkers(std::set<unsigned int>(), std::set<unsigned int>());
}
- if ((m_ModListSortProxy != nullptr)
+/* if ((m_ModListSortProxy != nullptr)
&& !m_ModListSortProxy->beingInvalidated()) {
m_ModListSortProxy->invalidate();
- }
+ }*/
ui->modList->verticalScrollBar()->repaint();
}
@@ -2727,7 +2721,7 @@ void MainWindow::savePrimaryCategory()
}
}
-bool MainWindow::saveArchiveList()
+void MainWindow::saveArchiveList()
{
if (m_OrganizerCore.isArchivesInit()) {
SafeWriteFile archiveFile(m_OrganizerCore.currentProfile()->getArchivesFileName());
@@ -2746,12 +2740,10 @@ bool MainWindow::saveArchiveList()
}
if (archiveFile.commitIfDifferent(m_ArchiveListHash)) {
qDebug("%s saved", qPrintable(QDir::toNativeSeparators(m_OrganizerCore.currentProfile()->getArchivesFileName())));
- return true;
}
} else {
qWarning("archive list not initialised");
}
- return false;
}
void MainWindow::checkModsForUpdates()
@@ -3191,7 +3183,7 @@ void MainWindow::fixMods_clicked()
}
}
- m_OrganizerCore.currentProfile()->writeModlist();
+ m_OrganizerCore.currentProfile()->modlistWriter().write();
m_OrganizerCore.refreshLists();
std::set<QString> espsToActivate = dialog.getESPsToActivate();
@@ -4005,14 +3997,14 @@ void MainWindow::on_bsaList_customContextMenuRequested(const QPoint &pos)
void MainWindow::bsaList_itemMoved()
{
- saveArchiveList();
+ m_ArchiveListWriter.write();
m_CheckBSATimer.start(500);
}
void MainWindow::on_bsaList_itemChanged(QTreeWidgetItem*, int)
{
- saveArchiveList();
+ m_ArchiveListWriter.write();
m_CheckBSATimer.start(500);
}
@@ -4528,12 +4520,13 @@ void MainWindow::on_restoreButton_clicked()
void MainWindow::on_saveModsButton_clicked()
{
- m_OrganizerCore.currentProfile()->writeModlistNow(true);
+ m_OrganizerCore.currentProfile()->modlistWriter().writeImmediately(true);
QDateTime now = QDateTime::currentDateTime();
if (createBackup(m_OrganizerCore.currentProfile()->getModlistFileName(), now)) {
MessageDialog::showMessage(tr("Backup of modlist created"), this);
}
}
+
void MainWindow::on_restoreModsButton_clicked()
{
QString modlistName = m_OrganizerCore.currentProfile()->getModlistFileName();
diff --git a/src/mainwindow.h b/src/mainwindow.h
index d0e3aaf5..88419594 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -53,6 +53,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "iuserinterface.h"
#include <guessedvalue.h>
#include <directoryentry.h>
+#include <delayedfilewriter.h>
#ifndef Q_MOC_RUN
#include <boost/signals2.hpp>
#endif
@@ -97,7 +98,7 @@ public:
void setModListSorting(int index);
void setESPListSorting(int index);
- bool saveArchiveList();
+ void saveArchiveList();
void registerPluginTool(MOBase::IPluginTool *tool);
void registerModPage(MOBase::IPluginModPage *modPage);
@@ -121,6 +122,8 @@ public:
virtual bool closeWindow();
virtual void setWindowEnabled(bool enabled);
+ virtual MOBase::DelayedFileWriterBase &archivesWriter() override { return m_ArchiveListWriter; }
+
public slots:
void displayColumnSelection(const QPoint &pos);
@@ -315,6 +318,8 @@ private:
LockedDialog *m_LockDialog { nullptr };
+ MOBase::DelayedFileWriter m_ArchiveListWriter;
+
private slots:
void showMessage(const QString &message);
@@ -389,7 +394,6 @@ private slots:
void addPrimaryCategoryCandidates();
void modDetailsUpdated(bool success);
- void modlistChanged(int row);
void modInstalled(const QString &modName);
diff --git a/src/modlist.cpp b/src/modlist.cpp
index 250b5caf..c6beee8b 100644
--- a/src/modlist.cpp
+++ b/src/modlist.cpp
@@ -458,6 +458,7 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
emit modlist_changed(index, role);
}
result = true;
+ emit dataChanged(index, index);
} else if (role == Qt::EditRole) {
switch (index.column()) {
case COL_NAME: {
@@ -469,7 +470,7 @@ bool ModList::setData(const QModelIndex &index, const QVariant &value, int role)
if (ok) {
m_Profile->setModPriority(modID, newPriority);
- emit modlist_changed(index, role);
+ emit modorder_changed();
result = true;
} else {
result = false;
@@ -859,13 +860,14 @@ void ModList::removeRowForce(int row, const QModelIndex &parent)
bool wasEnabled = m_Profile->modEnabled(row);
- beginRemoveRows(parent, row, row);
m_Profile->setModEnabled(row, false);
- m_Profile->cancelWriteModlist(); // don't write modlist while we're changing it
+
+ m_Profile->modlistWriter().cancel();
+ beginRemoveRows(parent, row, row);
ModInfo::removeMod(row);
- m_Profile->refreshModStatus(); // removes the mod from the status list
endRemoveRows();
- m_Profile->writeModlist(); // this ensures the modified list gets written back before new mods can be installed
+ m_Profile->refreshModStatus(); // removes the mod from the status list
+ m_Profile->modlistWriter().write(); // this ensures the modified list gets written back before new mods can be installed
if (wasEnabled) {
emit removeOrigin(modInfo->name());
@@ -874,7 +876,6 @@ void ModList::removeRowForce(int row, const QModelIndex &parent)
emit modUninstalled(modInfo->getInstallationFile());
}
-
bool ModList::removeRows(int row, int count, const QModelIndex &parent)
{
if (static_cast<unsigned int>(row) >= ModInfo::getNumMods()) {
@@ -903,6 +904,7 @@ bool ModList::removeRows(int row, int count, const QModelIndex &parent)
removeRowForce(row + i, parent);
}
}
+
return success;
}
@@ -997,6 +999,76 @@ QString ModList::getColumnToolTip(int column)
}
+bool ModList::moveSelection(QAbstractItemView *itemView, int direction)
+{
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
+
+ const QAbstractProxyModel *proxyModel = qobject_cast<const QAbstractProxyModel*>(selectionModel->model());
+ const QSortFilterProxyModel *filterModel = nullptr;
+
+ while ((filterModel == nullptr) && (proxyModel != nullptr)) {
+ filterModel = qobject_cast<const QSortFilterProxyModel*>(proxyModel);
+ if (filterModel == nullptr) {
+ proxyModel = qobject_cast<const QAbstractProxyModel*>(proxyModel->sourceModel());
+ }
+ }
+ if (filterModel == nullptr) {
+ return true;
+ }
+
+ int offset = -1;
+ if (((direction < 0) && (filterModel->sortOrder() == Qt::DescendingOrder)) ||
+ ((direction > 0) && (filterModel->sortOrder() == Qt::AscendingOrder))) {
+ offset = 1;
+ }
+
+ QModelIndexList rows = selectionModel->selectedRows();
+ if (direction > 0) {
+ for (int i = 0; i < rows.size() / 2; ++i) {
+ rows.swap(i, rows.size() - i - 1);
+ }
+ }
+ for (QModelIndex idx : rows) {
+ if (filterModel != nullptr) {
+ idx = filterModel->mapToSource(idx);
+ }
+ int newPriority = m_Profile->getModPriority(idx.row()) + offset;
+ if ((newPriority >= 0) && (newPriority < static_cast<int>(m_Profile->numRegularMods()))) {
+ m_Profile->setModPriority(idx.row(), newPriority);
+ notifyChange(idx.row());
+ }
+ }
+ emit modorder_changed();
+ return true;
+}
+
+bool ModList::deleteSelection(QAbstractItemView *itemView)
+{
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
+
+ QModelIndexList rows = selectionModel->selectedRows();
+ if (rows.count() > 1) {
+ emit removeSelectedMods();
+ } else if (rows.count() == 1) {
+ removeRow(rows[0].data(Qt::UserRole + 1).toInt(), QModelIndex());
+ }
+ return true;
+}
+
+bool ModList::toggleSelection(QAbstractItemView *itemView)
+{
+ QAbstractItemModel *model = itemView->model();
+ QItemSelectionModel *selectionModel = itemView->selectionModel();
+
+ for (QModelIndex idx : selectionModel->selectedRows()) {
+ int oldState = idx.data(Qt::CheckStateRole).toInt();
+ model->setData(idx, oldState == Qt::Unchecked ? Qt::Checked
+ : Qt::Unchecked,
+ Qt::CheckStateRole);
+ }
+ return true;
+}
+
bool ModList::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::ContextMenu) {
@@ -1010,74 +1082,15 @@ bool ModList::eventFilter(QObject *obj, QEvent *event)
} else if ((event->type() == QEvent::KeyPress) && (m_Profile != nullptr)) {
QAbstractItemView *itemView = qobject_cast<QAbstractItemView*>(obj);
QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
+
if ((itemView != nullptr)
&& (keyEvent->modifiers() == Qt::ControlModifier)
- && ((keyEvent->key() == Qt::Key_Up)
- || (keyEvent->key() == Qt::Key_Down))) {
- QItemSelectionModel *selectionModel = itemView->selectionModel();
- const QAbstractProxyModel *proxyModel = qobject_cast<const QAbstractProxyModel*>(selectionModel->model());
- const QSortFilterProxyModel *filterModel = nullptr;
- while ((filterModel == nullptr) && (proxyModel != nullptr)) {
- filterModel = qobject_cast<const QSortFilterProxyModel*>(proxyModel);
- if (filterModel == nullptr) {
- proxyModel = qobject_cast<const QAbstractProxyModel*>(proxyModel->sourceModel());
- }
- }
- if (filterModel == nullptr) {
- return true;
- }
- int diff = -1;
- if (((keyEvent->key() == Qt::Key_Up) && (filterModel->sortOrder() == Qt::DescendingOrder)) ||
- ((keyEvent->key() == Qt::Key_Down) && (filterModel->sortOrder() == Qt::AscendingOrder))) {
- diff = 1;
- }
- QModelIndexList rows = selectionModel->selectedRows();
- if (keyEvent->key() == Qt::Key_Down) {
- for (int i = 0; i < rows.size() / 2; ++i) {
- rows.swap(i, rows.size() - i - 1);
- }
- }
- foreach (QModelIndex idx, rows) {
- if (filterModel != nullptr) {
- idx = filterModel->mapToSource(idx);
- }
- int newPriority = m_Profile->getModPriority(idx.row()) + diff;
- if ((newPriority >= 0) && (newPriority < static_cast<int>(m_Profile->numRegularMods()))) {
- m_Profile->setModPriority(idx.row(), newPriority);
- notifyChange(idx.row());
- }
- }
- emit modorder_changed();
- return true;
+ && ((keyEvent->key() == Qt::Key_Up) || (keyEvent->key() == Qt::Key_Down))) {
+ return moveSelection(itemView, keyEvent->key() == Qt::Key_Up ? -1 : 1);
} else if (keyEvent->key() == Qt::Key_Delete) {
- QItemSelectionModel *selectionModel = itemView->selectionModel();
- QModelIndexList rows = selectionModel->selectedRows();
- if (rows.count() > 1) {
- emit removeSelectedMods();
- } else if (rows.count() == 1) {
- removeRow(rows[0].data(Qt::UserRole + 1).toInt(), QModelIndex());
- }
- return true;
+ return deleteSelection(itemView);
} else if (keyEvent->key() == Qt::Key_Space) {
- QItemSelectionModel *selectionModel = itemView->selectionModel();
- const QSortFilterProxyModel *proxyModel = qobject_cast<const QSortFilterProxyModel*>(selectionModel->model());
-
- QModelIndex minRow, maxRow;
- foreach (QModelIndex idx, selectionModel->selectedRows()) {
- if (proxyModel != nullptr) {
- idx = proxyModel->mapToSource(idx);
- }
- if (!minRow.isValid() || (idx.row() < minRow.row())) {
- minRow = idx;
- }
- if (!maxRow.isValid() || (idx.row() > maxRow.row())) {
- maxRow = idx;
- }
- int oldState = idx.data(Qt::CheckStateRole).toInt();
- setData(idx, oldState == Qt::Unchecked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
- }
- emit dataChanged(minRow, maxRow);
- return true;
+ return toggleSelection(itemView);
}
}
return QObject::eventFilter(obj, event);
diff --git a/src/modlist.h b/src/modlist.h
index 73a49745..6a10cb3e 100644
--- a/src/modlist.h
+++ b/src/modlist.h
@@ -40,6 +40,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QVector>
+class QSortFilterProxyModel;
+
/**
* Model presenting an overview of the installed mod
* This is used in a view in the main window of MO. It combines general information about
@@ -261,6 +263,12 @@ private:
ModStates state(unsigned int modIndex) const;
+ bool moveSelection(QAbstractItemView *itemView, int direction);
+
+ bool deleteSelection(QAbstractItemView *itemView);
+
+ bool toggleSelection(QAbstractItemView *itemView);
+
private slots:
private:
diff --git a/src/modlistview.cpp b/src/modlistview.cpp
index 50a13a8c..fe2d3e57 100644
--- a/src/modlistview.cpp
+++ b/src/modlistview.cpp
@@ -53,3 +53,4 @@ void ModListView::setModel(QAbstractItemModel *model)
QTreeView::setModel(model);
setVerticalScrollBar(new ViewMarkingScrollBar(model, this));
}
+
diff --git a/src/modlistview.h b/src/modlistview.h
index 4907225f..6cd114b0 100644
--- a/src/modlistview.h
+++ b/src/modlistview.h
@@ -19,7 +19,6 @@ public slots:
private:
ViewMarkingScrollBar *m_Scrollbar;
-
};
#endif // MODLISTVIEW_H
diff --git a/src/organizercore.cpp b/src/organizercore.cpp
index 0ea3ccb1..6a5e08d0 100644
--- a/src/organizercore.cpp
+++ b/src/organizercore.cpp
@@ -24,6 +24,7 @@
#include <QDialogButtonBox>
#include <QApplication>
#include <Psapi.h>
+#include <functional>
using namespace MOShared;
@@ -126,6 +127,7 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings)
, m_AskForNexusPW(false)
, m_DirectoryUpdate(false)
, m_ArchivesInit(false)
+ , m_PluginListsWriter(std::bind(&OrganizerCore::savePluginList, this))
{
m_DownloadManager.setOutputDirectory(m_Settings.getDownloadDirectory());
m_DownloadManager.setPreferredServers(m_Settings.getPreferredServers());
@@ -140,13 +142,14 @@ OrganizerCore::OrganizerCore(const QSettings &initSettings)
connect(&m_DirectoryRefresher, SIGNAL(refreshed()), this, SLOT(directory_refreshed()));
connect(&m_ModList, SIGNAL(removeOrigin(QString)), this, SLOT(removeOrigin(QString)));
- connect(&m_PluginList, SIGNAL(saveTimer()), this, SLOT(savePluginList()));
connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginSuccessful(bool)), this, SLOT(loginSuccessful(bool)));
connect(NexusInterface::instance()->getAccessManager(), SIGNAL(loginFailed(QString)), this, SLOT(loginFailed(QString)));
connect(this, SIGNAL(managedGameChanged(MOBase::IPluginGame*)), &m_Settings, SLOT(managedGameChanged(MOBase::IPluginGame*)));
+ connect(&m_PluginList, &PluginList::writePluginsList, &m_PluginListsWriter, &DelayedFileWriterBase::write);
+
// make directory refresher run in a separate thread
m_RefresherThread.start();
m_DirectoryRefresher.moveToThread(&m_RefresherThread);
@@ -319,11 +322,11 @@ void OrganizerCore::setUserInterface(IUserInterface *userInterface, QWidget *wid
m_UserInterface = userInterface;
if (widget != nullptr) {
- connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex,int)), widget, SLOT(modorder_changed()));
+// connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), widget, SLOT(modorder_changed()));
+ connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), widget, SLOT(modlistChanged(QModelIndex, int)));
connect(&m_ModList, SIGNAL(showMessage(QString)), widget, SLOT(showMessage(QString)));
connect(&m_ModList, SIGNAL(modRenamed(QString,QString)), widget, SLOT(modRenamed(QString,QString)));
connect(&m_ModList, SIGNAL(modUninstalled(QString)), widget, SLOT(modRemoved(QString)));
- connect(&m_ModList, SIGNAL(modlist_changed(QModelIndex, int)), widget, SLOT(modlistChanged(QModelIndex, int)));
connect(&m_ModList, SIGNAL(removeSelectedMods()), widget, SLOT(removeMod_clicked()));
connect(&m_ModList, SIGNAL(requestColumnSelect(QPoint)), widget, SLOT(displayColumnSelection(QPoint)));
connect(&m_ModList, SIGNAL(fileMoved(QString, QString, QString)), widget, SLOT(fileMoved(QString, QString, QString)));
@@ -920,7 +923,7 @@ HANDLE OrganizerCore::spawnBinaryDirect(const QFileInfo &binary, const QString &
// need to make sure all data is saved before we start the application
if (m_CurrentProfile != nullptr) {
- m_CurrentProfile->writeModlistNow(true);
+ m_CurrentProfile->modlistWriter().writeImmediately(true);
}
// TODO: should also pass arguments
@@ -1066,7 +1069,7 @@ void OrganizerCore::refreshModList(bool saveChanges)
{
// don't lose changes!
if (saveChanges) {
- m_CurrentProfile->writeModlistNow(true);
+ m_CurrentProfile->modlistWriter().writeImmediately(true);
}
ModInfo::updateFromDisc(m_Settings.getModDirectory(), &m_DirectoryStructure, m_Settings.displayForeign());
@@ -1079,7 +1082,7 @@ void OrganizerCore::refreshModList(bool saveChanges)
void OrganizerCore::refreshESPList()
{
- m_CurrentProfile->writeModlist();
+ m_CurrentProfile->modlistWriter().write();
// clear list
try {
@@ -1151,8 +1154,7 @@ void OrganizerCore::updateModActiveState(int index, bool active)
}
m_PluginList.refreshLoadOrder();
// immediately save affected lists
- savePluginList();
-// refreshBSAList();
+ m_PluginListsWriter.writeImmediately(false);
}
void OrganizerCore::updateModInDirectoryStructure(unsigned int index, ModInfo::Ptr modInfo)
@@ -1172,7 +1174,7 @@ void OrganizerCore::updateModInDirectoryStructure(unsigned int index, ModInfo::P
// now we need to refresh the bsa list and save it so there is no confusion about what archives are avaiable and active
refreshBSAList();
if (m_UserInterface != nullptr) {
- m_UserInterface->saveArchiveList();
+ m_UserInterface->archivesWriter().write();
}
m_DirectoryRefresher.setMods(m_CurrentProfile->getActiveMods(), enabledArchives());
@@ -1257,7 +1259,7 @@ std::set<QString> OrganizerCore::enabledArchives()
void OrganizerCore::refreshDirectoryStructure()
{
if (!m_DirectoryUpdate) {
- m_CurrentProfile->writeModlistNow(true);
+ m_CurrentProfile->modlistWriter().writeImmediately(true);
m_DirectoryUpdate = true;
std::vector<std::tuple<QString, QString, int> > activeModList = m_CurrentProfile->getActiveMods();
@@ -1447,7 +1449,7 @@ bool OrganizerCore::saveCurrentLists()
try {
savePluginList();
if (m_UserInterface != nullptr) {
- m_UserInterface->saveArchiveList();
+ m_UserInterface->archivesWriter().write();
}
} catch (const std::exception &e) {
reportError(tr("failed to save load order: %1").arg(e.what()));
@@ -1470,7 +1472,7 @@ void OrganizerCore::prepareStart() {
if (m_CurrentProfile == nullptr) {
return;
}
- m_CurrentProfile->writeModlist();
+ m_CurrentProfile->modlistWriter().write();
m_CurrentProfile->createTweakedIniFile();
saveCurrentLists();
m_Settings.setupLoadMechanism();
diff --git a/src/organizercore.h b/src/organizercore.h
index 3191e2a9..d8a3e232 100644
--- a/src/organizercore.h
+++ b/src/organizercore.h
@@ -20,6 +20,7 @@
#include <iplugingame.h>
#include <versioninfo.h>
#include <guessedvalue.h>
+#include <delayedfilewriter.h>
#include <boost/signals2.hpp>
#include <QSettings>
#include <QString>
@@ -124,6 +125,8 @@ public:
void createDefaultProfile();
+ MOBase::DelayedFileWriter &pluginsWriter() { return m_PluginListsWriter; }
+
public:
MOBase::IGameInfo &gameInfo() const;
MOBase::IModRepositoryBridge *createNexusBridge() const;
@@ -255,6 +258,8 @@ private:
bool m_DirectoryUpdate;
bool m_ArchivesInit;
+ MOBase::DelayedFileWriter m_PluginListsWriter;
+
};
#endif // ORGANIZERCORE_H
diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp
index 1b06d1a6..6bc9d12b 100644
--- a/src/plugincontainer.cpp
+++ b/src/plugincontainer.cpp
@@ -317,7 +317,8 @@ QString PluginContainer::fullDescription(unsigned int key) const
{
switch (key) {
case PROBLEM_PLUGINSNOTLOADED: {
- QString result = tr("The following plugins could not be loaded. The reason may be missing dependencies (i.e. python) or an outdated version:") + "<ul>";
+ QString result = tr("The following plugins could not be loaded. The reason may be missing "
+ "dependencies (i.e. python) or an outdated version:") + "<ul>";
for (const QString &plugin : m_FailedPlugins) {
result += "<li>" + plugin + "</li>";
}
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index f72ab690..f8a27ef4 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -69,23 +69,12 @@ static bool ByPriority(const PluginList::ESPInfo& LHS, const PluginList::ESPInfo
static bool ByDate(const PluginList::ESPInfo& LHS, const PluginList::ESPInfo& RHS) {
return QFileInfo(LHS.m_FullPath).lastModified() < QFileInfo(RHS.m_FullPath).lastModified();
-/* QString lhsExtension = LHS.m_Name.right(3).toLower();
- QString rhsExtension = RHS.m_Name.right(3).toLower();
- if (lhsExtension != rhsExtension) {
- return lhsExtension == "esm";
- }
-
- return ::CompareFileTime(&LHS.m_Time, &RHS.m_Time) < 0;*/
}
PluginList::PluginList(QObject *parent)
: QAbstractItemModel(parent)
, m_FontMetrics(QFont())
- , m_SaveTimer(this)
{
- m_SaveTimer.setSingleShot(true);
- connect(&m_SaveTimer, SIGNAL(timeout()), this, SIGNAL(saveTimer()));
-
m_Utf8Codec = QTextCodec::codecForName("utf-8");
m_LocalCodec = QTextCodec::codecForName("Windows-1252");
@@ -238,7 +227,8 @@ void PluginList::enableESP(const QString &name, bool enable)
if (iter != m_ESPsByName.end()) {
m_ESPs[iter->second].m_Enabled = enable;
- startSaveTime();
+
+ emit writePluginsList();
} else {
reportError(tr("esp not found: %1").arg(name));
}
@@ -252,7 +242,7 @@ void PluginList::enableAll()
for (std::vector<ESPInfo>::iterator iter = m_ESPs.begin(); iter != m_ESPs.end(); ++iter) {
iter->m_Enabled = true;
}
- startSaveTime();
+ emit writePluginsList();
}
}
@@ -266,7 +256,7 @@ void PluginList::disableAll()
iter->m_Enabled = false;
}
}
- startSaveTime();
+ emit writePluginsList();
}
}
@@ -382,7 +372,7 @@ void PluginList::readEnabledFrom(const QString &fileName)
m_ESPs[iter->second].m_Enabled = true;
} else {
qWarning("plugin %s not found", modName.toUtf8().constData());
- startSaveTime();
+ emit writePluginsList();
}
}
}
@@ -503,8 +493,6 @@ void PluginList::saveTo(const QString &pluginFileName
} else if (QFile::exists(deleterFileName)) {
shellDelete(QStringList() << deleterFileName);
}
-
- m_SaveTimer.stop();
}
@@ -581,7 +569,8 @@ void PluginList::lockESPIndex(int index, bool lock)
m_LockedOrder.erase(iter);
}
}
- startSaveTime();
+qDebug(__FUNCTION__);
+ emit writePluginsList();
}
@@ -631,7 +620,7 @@ void PluginList::refreshLoadOrder()
setPluginPriority(index, temp);
m_ESPs[index].m_LoadOrder = iter->first;
syncLoadOrder();
- startSaveTime();
+ emit writePluginsList();
}
}
}
@@ -897,7 +886,7 @@ bool PluginList::setData(const QModelIndex &modIndex, const QVariant &value, int
emit dataChanged(modIndex, modIndex);
refreshLoadOrder();
- startSaveTime();
+ emit writePluginsList();
result = true;
} else if (role == Qt::EditRole) {
@@ -1034,21 +1023,8 @@ void PluginList::changePluginPriority(std::vector<int> rows, int newPriority)
layoutChange.finish();
refreshLoadOrder();
-
- startSaveTime();
-}
-
-
-void PluginList::startSaveTime()
-{
- testMasters();
-
- if (!m_SaveTimer.isActive()) {
- m_SaveTimer.start(2000);
- }
}
-
bool PluginList::dropMimeData(const QMimeData *mimeData, Qt::DropAction action, int row, int, const QModelIndex &parent)
{
if (action == Qt::IgnoreAction) {
diff --git a/src/pluginlist.h b/src/pluginlist.h
index e0913840..80fcc25b 100644
--- a/src/pluginlist.h
+++ b/src/pluginlist.h
@@ -262,10 +262,7 @@ signals:
**/
void esplist_changed();
- /**
- * @brief emitted when the plugin list should be saved
- */
- void saveTimer();
+ void writePluginsList();
private:
@@ -310,8 +307,6 @@ private:
void setPluginPriority(int row, int &newPriority);
void changePluginPriority(std::vector<int> rows, int newPriority);
- void startSaveTime();
-
void testMasters();
private:
@@ -336,14 +331,11 @@ private:
QTextCodec *m_Utf8Codec;
QTextCodec *m_LocalCodec;
- mutable QTimer m_SaveTimer;
-
SignalRefreshed m_Refreshed;
SignalPluginMoved m_PluginMoved;
QTemporaryFile m_TempFile;
-
};
#endif // PLUGINLIST_H
diff --git a/src/profile.cpp b/src/profile.cpp
index 5d31533a..c1e6e5fc 100644
--- a/src/profile.cpp
+++ b/src/profile.cpp
@@ -34,6 +34,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <QApplication>
#include <QSettings>
#include <QTemporaryFile>
+#include <functional>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
@@ -43,10 +44,10 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
+
Profile::Profile()
- : m_SaveTimer(nullptr)
+ : m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
{
- initTimer();
}
void Profile::touchFile(QString fileName)
@@ -58,10 +59,9 @@ void Profile::touchFile(QString fileName)
}
Profile::Profile(const QString &name, IPluginGame *gamePlugin, bool useDefaultSettings)
- : m_SaveTimer(nullptr)
+ : m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
, m_GamePlugin(gamePlugin)
{
- initTimer();
QString profilesDir = qApp->property("dataPath").toString() + "/" + ToQString(AppConfig::profilesPath());
QDir profileBase(profilesDir);
@@ -100,10 +100,10 @@ Profile::Profile(const QString &name, IPluginGame *gamePlugin, bool useDefaultSe
Profile::Profile(const QDir &directory, IPluginGame *gamePlugin)
- : m_Directory(directory), m_SaveTimer(nullptr)
+ : m_Directory(directory)
+ , m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
{
assert(gamePlugin != nullptr);
- initTimer();
if (!QFile::exists(m_Directory.filePath("modlist.txt"))) {
qWarning("missing modlist.txt in %s", qPrintable(directory.path()));
@@ -124,52 +124,24 @@ Profile::Profile(const QDir &directory, IPluginGame *gamePlugin)
Profile::Profile(const Profile &reference)
: m_Directory(reference.m_Directory)
- , m_SaveTimer(nullptr)
+ , m_ModListWriter(std::bind(&Profile::writeModlistNow, this))
{
- initTimer();
refreshModStatus();
}
Profile::~Profile()
{
- writeModlistNow();
-}
-
-
-void Profile::initTimer()
-{
- m_SaveTimer = new QTimer(this);
- m_SaveTimer->setSingleShot(true);
- connect(m_SaveTimer, SIGNAL(timeout()), this, SLOT(writeModlistNow()));
+ m_ModListWriter.writeImmediately(true);
}
-
bool Profile::exists() const
{
return m_Directory.exists();
}
-
-void Profile::writeModlist() const
-{
- if (!m_SaveTimer->isActive()) {
- m_SaveTimer->start(2000);
- }
-}
-
-
-void Profile::cancelWriteModlist() const
+void Profile::writeModlistNow()
{
- m_SaveTimer->stop();
-}
-
-
-void Profile::writeModlistNow(bool onlyOnTimer) const
-{
- if (onlyOnTimer && !m_SaveTimer->isActive()) return;
-
- m_SaveTimer->stop();
if (!m_Directory.exists()) return;
try {
@@ -366,7 +338,7 @@ void Profile::refreshModStatus()
file.close();
updateIndices();
if (modStatusModified) {
- writeModlist();
+ m_ModListWriter.write();
}
}
@@ -456,7 +428,6 @@ void Profile::setModEnabled(unsigned int index, bool enabled)
}
}
-
bool Profile::modEnabled(unsigned int index) const
{
if (index >= m_ModStatus.size()) {
@@ -508,7 +479,7 @@ void Profile::setModPriority(unsigned int index, int &newPriority)
m_ModStatus.at(index).m_Priority = newPriorityTemp;
updateIndices();
- writeModlist();
+ m_ModListWriter.write();
}
Profile *Profile::createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame *gamePlugin)
diff --git a/src/profile.h b/src/profile.h
index 5eaa1ea1..342b6fa0 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -23,6 +23,7 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "modinfo.h"
#include <iprofile.h>
+#include <delayedfilewriter.h>
#include <QString>
#include <QDir>
#include <QMetaType>
@@ -89,16 +90,7 @@ public:
**/
static Profile *createPtrFrom(const QString &name, const Profile &reference, MOBase::IPluginGame *gamePlugin);
- /**
- * @brief write out the modlist.txt
- **/
- void writeModlist() const;
-
- /**
- * cancel any potential request to write modlist.txt. This is used to ensure no invalid modlist is
- * saved while it's being modified
- */
- void cancelWriteModlist() const;
+ MOBase::DelayedFileWriter &modlistWriter() { return m_ModListWriter; }
/**
* @brief test if this profile uses archive invalidation
@@ -283,7 +275,7 @@ signals:
public slots:
- void writeModlistNow(bool onlyOnTimer = false) const;
+ void writeModlistNow();
private:
@@ -310,6 +302,7 @@ private:
void mergeTweak(const QString &tweakName, const QString &tweakedIni) const;
void mergeTweaks(ModInfo::Ptr modInfo, const QString &tweakedIni) const;
void touchFile(QString fileName);
+ void finishChangeStatus() const;
private:
@@ -322,7 +315,7 @@ private:
std::vector<unsigned int> m_ModIndexByPriority;
unsigned int m_NumRegularMods;
- QTimer *m_SaveTimer;
+ MOBase::DelayedFileWriter m_ModListWriter;
};
diff --git a/src/version.rc b/src/version.rc
index 68d7cd23..d6fe2f85 100644
--- a/src/version.rc
+++ b/src/version.rc
@@ -1,7 +1,7 @@
#include "Winver.h"
-#define VER_FILEVERSION 1,3,0,0
-#define VER_FILEVERSION_STR "1,3,0,0\0"
+#define VER_FILEVERSION 1,3,1,0
+#define VER_FILEVERSION_STR "1,3,1,0\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION VER_FILEVERSION