diff options
| author | Tannin <devnull@localhost> | 2015-03-01 11:28:49 +0100 |
|---|---|---|
| committer | Tannin <devnull@localhost> | 2015-03-01 11:28:49 +0100 |
| commit | d08e0ebab09b0a71c3042cd20b8994ec1c10a525 (patch) | |
| tree | 326a75bae849f2e2ed42cba0914933437bb92f89 /src | |
| parent | 6479f972dccaabb3afadb570583a4269e8a785e4 (diff) | |
- some fixes to how file changes are signaled and delayed
Diffstat (limited to 'src')
| -rw-r--r-- | src/iuserinterface.h | 4 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 31 | ||||
| -rw-r--r-- | src/mainwindow.h | 8 | ||||
| -rw-r--r-- | src/modlist.cpp | 153 | ||||
| -rw-r--r-- | src/modlist.h | 8 | ||||
| -rw-r--r-- | src/modlistview.cpp | 1 | ||||
| -rw-r--r-- | src/modlistview.h | 1 | ||||
| -rw-r--r-- | src/organizercore.cpp | 26 | ||||
| -rw-r--r-- | src/organizercore.h | 5 | ||||
| -rw-r--r-- | src/plugincontainer.cpp | 3 | ||||
| -rw-r--r-- | src/pluginlist.cpp | 42 | ||||
| -rw-r--r-- | src/pluginlist.h | 10 | ||||
| -rw-r--r-- | src/profile.cpp | 51 | ||||
| -rw-r--r-- | src/profile.h | 17 | ||||
| -rw-r--r-- | src/version.rc | 4 |
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 ¤t, const QModelIndex&)
@@ -2150,10 +2144,10 @@ void MainWindow::modlistSelectionChanged(const QModelIndex ¤t, 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
|
