summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt10
-rw-r--r--src/dlls.manifest.qt5 (renamed from src/dlls.manifest)58
-rw-r--r--src/mainwindow.cpp69
-rw-r--r--src/mainwindow.h2
-rw-r--r--src/modinfowithconflictinfo.cpp4
-rw-r--r--src/modinfowithconflictinfo.h12
-rw-r--r--src/plugincontainer.cpp22
-rw-r--r--src/plugincontainer.h4
-rw-r--r--src/qt.conf6
-rw-r--r--src/settingsdialoggeneral.cpp6
-rw-r--r--src/shared/appconfig.inc3
-rw-r--r--src/thread_utils.h45
-rw-r--r--src/transfersavesdialog.cpp105
-rw-r--r--src/transfersavesdialog.h7
-rw-r--r--src/tutorials/TutorialOverlay.qml4
15 files changed, 99 insertions, 258 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ffaf3c0c..a53d845d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -232,17 +232,15 @@ target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
)
-install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest
+install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/dlls.manifest.qt5
DESTINATION bin/dlls
RENAME dlls.manifest)
-install(FILES ${qm_files} DESTINATION bin/resources/translations)
+install(FILES ${qm_files} DESTINATION bin/translations)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/stylesheets
- DESTINATION bin)
-
-install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/tutorials
- DESTINATION bin/resources)
+ ${CMAKE_CURRENT_SOURCE_DIR}/tutorials
+ DESTINATION bin)
deploy_qt(BINARIES ModOrganizer.exe uibase.dll plugins/bsa_packer.dll)
diff --git a/src/dlls.manifest b/src/dlls.manifest.qt5
index 846a02ae..cae74df1 100644
--- a/src/dlls.manifest
+++ b/src/dlls.manifest.qt5
@@ -1,29 +1,29 @@
-<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
-<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
- <assemblyIdentity type="win32" name="dlls" version="1.0.0.0" processorArchitecture="x86"/>
- <file name="7z.dll"/>
- <file name="archive.dll"/>
- <file name="d3dcompiler_47.dll"/>
- <file name="libEGL.dll"/>
- <file name="libGLESV2.dll"/>
- <file name="liblz4.dll"/>
- <file name="opengl32sw.dll"/>
- <file name="Qt5Core.dll"/>
- <file name="Qt5Gui.dll"/>
- <file name="Qt5Network.dll"/>
- <file name="Qt5Positioning.dll"/>
- <file name="Qt5PrintSupport.dll"/>
- <file name="Qt5Qml.dll"/>
- <file name="Qt5QmlModels.dll"/>
- <file name="Qt5QmlWorkerScript.dll"/>
- <file name="Qt5Quick.dll"/>
- <file name="Qt5QuickWidgets.dll"/>
- <file name="Qt5SerialPort.dll"/>
- <file name="Qt5Svg.dll"/>
- <file name="Qt5WebChannel.dll"/>
- <file name="Qt5WebEngineCore.dll"/>
- <file name="Qt5WebEngineWidgets.dll"/>
- <file name="Qt5WebSockets.dll"/>
- <file name="Qt5Widgets.dll"/>
- <file name="Qt5WinExtras.dll"/>
-</assembly>
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+ <assemblyIdentity type="win32" name="dlls" version="1.0.0.0" processorArchitecture="x86"/>
+ <file name="7z.dll"/>
+ <file name="archive.dll"/>
+ <file name="d3dcompiler_47.dll"/>
+ <file name="libEGL.dll"/>
+ <file name="libGLESV2.dll"/>
+ <file name="liblz4.dll"/>
+ <file name="opengl32sw.dll"/>
+ <file name="Qt5Core.dll"/>
+ <file name="Qt5Gui.dll"/>
+ <file name="Qt5Network.dll"/>
+ <file name="Qt5Positioning.dll"/>
+ <file name="Qt5PrintSupport.dll"/>
+ <file name="Qt5Qml.dll"/>
+ <file name="Qt5QmlModels.dll"/>
+ <file name="Qt5QmlWorkerScript.dll"/>
+ <file name="Qt5Quick.dll"/>
+ <file name="Qt5QuickWidgets.dll"/>
+ <file name="Qt5SerialPort.dll"/>
+ <file name="Qt5Svg.dll"/>
+ <file name="Qt5WebChannel.dll"/>
+ <file name="Qt5WebEngineCore.dll"/>
+ <file name="Qt5WebEngineWidgets.dll"/>
+ <file name="Qt5WebSockets.dll"/>
+ <file name="Qt5Widgets.dll"/>
+ <file name="Qt5WinExtras.dll"/>
+</assembly>
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp
index c2aefdd2..69f90ce4 100644
--- a/src/mainwindow.cpp
+++ b/src/mainwindow.cpp
@@ -430,7 +430,10 @@ MainWindow::MainWindow(Settings &settings
this, &MainWindow::refresherProgress);
connect(m_OrganizerCore.directoryRefresher(), SIGNAL(error(QString)), this, SLOT(showError(QString)));
- connect(&m_SavesWatcher, SIGNAL(directoryChanged(QString)), this, SLOT(refreshSavesIfOpen()));
+ m_SavesWatcherTimer.setSingleShot(true);
+ m_SavesWatcherTimer.setInterval(500);
+ connect(&m_SavesWatcher, &QFileSystemWatcher::directoryChanged, [this]() { m_SavesWatcherTimer.start(); });
+ connect(&m_SavesWatcherTimer, &QTimer::timeout, this, &MainWindow::refreshSavesIfOpen);
connect(&m_OrganizerCore.settings(), SIGNAL(languageChanged(QString)), this, SLOT(languageChange(QString)));
connect(&m_OrganizerCore.settings(), SIGNAL(styleChanged(QString)), this, SIGNAL(styleChanged(QString)));
@@ -508,6 +511,7 @@ MainWindow::MainWindow(Settings &settings
m_Tutorial.expose("espList", m_OrganizerCore.pluginList());
m_OrganizerCore.setUserInterface(this);
+ m_PluginContainer.setUserInterface(this);
connect(this, &MainWindow::userInterfaceInitialized, &m_OrganizerCore, &OrganizerCore::userInterfaceInitialized);
for (const QString &fileName : m_PluginContainer.pluginFileNames()) {
installTranslator(QFileInfo(fileName).baseName());
@@ -700,7 +704,7 @@ MainWindow::~MainWindow()
try {
cleanup();
- m_PluginContainer.setUserInterface(nullptr, nullptr);
+ m_PluginContainer.setUserInterface(nullptr);
m_OrganizerCore.setUserInterface(nullptr);
if (m_IntegratedBrowser) {
@@ -1206,9 +1210,7 @@ void MainWindow::createHelpMenu()
ActionList tutorials;
- QString tutorialPath = QApplication::applicationDirPath()
- + "/" + QString::fromStdWString(AppConfig::tutorialsPath()) + "/";
- QDirIterator dirIter(tutorialPath, QStringList("*.js"), QDir::Files);
+ QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
while (dirIter.hasNext()) {
dirIter.next();
QString fileName = dirIter.fileName();
@@ -1320,8 +1322,7 @@ bool MainWindow::addProfile()
void MainWindow::hookUpWindowTutorials()
{
- QString tutorialPath = QApplication::applicationDirPath() + "/" + QString::fromStdWString(AppConfig::tutorialsPath()) + "/";
- QDirIterator dirIter(tutorialPath, QStringList("*.js"), QDir::Files);
+ QDirIterator dirIter(QApplication::applicationDirPath() + "/tutorials", QStringList("*.js"), QDir::Files);
while (dirIter.hasNext()) {
dirIter.next();
QString fileName = dirIter.fileName();
@@ -1532,7 +1533,6 @@ void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem)
return;
}
- QString const &save = newItem->data(Qt::UserRole).toString();
if (m_CurrentSaveView == nullptr) {
IPluginGame const *game = m_OrganizerCore.managedGame();
SaveGameInfo const *info = game->feature<SaveGameInfo>();
@@ -1543,7 +1543,7 @@ void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem)
return;
}
}
- m_CurrentSaveView->setSave(save);
+ m_CurrentSaveView->setSave(*m_SaveGames[ui->savegameList->row(newItem)]);
QWindow *window = m_CurrentSaveView->window()->windowHandle();
QRect screenRect;
@@ -1677,7 +1677,6 @@ void MainWindow::updateToolMenu()
void MainWindow::registerModPage(IPluginModPage *modPage)
{
QAction *action = new QAction(modPage->icon(), modPage->displayName(), this);
- modPage->setParentWidget(this);
connect(action, &QAction::triggered, this, [this, modPage]() {
if (modPage->useIntegratedBrowser()) {
@@ -1964,36 +1963,23 @@ void MainWindow::stopMonitorSaves()
void MainWindow::refreshSaveList()
{
- ui->savegameList->clear();
+ TimeThis tt("MainWindow::refreshSaveList()");
startMonitorSaves(); // re-starts monitoring
- QStringList filters;
- filters << QString("*.") + m_OrganizerCore.managedGame()->savegameExtension();
-
QDir savesDir = currentSavesDir();
- savesDir.setNameFilters(filters);
- savesDir.setFilter(QDir::Files);
- QDirIterator it(savesDir, QDirIterator::Subdirectories);
- log::debug("reading save games from {}", savesDir.absolutePath());
-
- QFileInfoList files;
- while (it.hasNext()) {
- it.next();
- files.append(it.fileInfo());
- }
- std::sort(files.begin(), files.end(), [](auto const& lhs, auto const& rhs) {
- return lhs.fileTime(QFileDevice::FileModificationTime) > rhs.fileTime(QFileDevice::FileModificationTime);
+ MOBase::log::debug("reading save games from {}", savesDir.absolutePath());
+ m_SaveGames = m_OrganizerCore.managedGame()->listSaves(savesDir);
+ std::sort(m_SaveGames.begin(), m_SaveGames.end(), [](auto const& lhs, auto const& rhs) {
+ return lhs->getCreationTime() > rhs->getCreationTime();
});
- for (const QFileInfo &file : files) {
- QListWidgetItem *item = new QListWidgetItem(savesDir.relativeFilePath(file.absoluteFilePath()));
- item->setData(Qt::UserRole, file.absoluteFilePath());
- ui->savegameList->addItem(item);
+ ui->savegameList->clear();
+ for (auto& save: m_SaveGames) {
+ ui->savegameList->addItem(savesDir.relativeFilePath(save->getFilepath()));
}
}
-
static bool BySortValue(const std::pair<UINT32, QTreeWidgetItem*> &LHS, const std::pair<UINT32, QTreeWidgetItem*> &RHS)
{
return LHS.first < RHS.first;
@@ -4960,20 +4946,15 @@ void MainWindow::deleteSavegame_clicked()
int count = 0;
for (const QModelIndex &idx : ui->savegameList->selectionModel()->selectedIndexes()) {
- QString name = idx.data(Qt::UserRole).toString();
+
+ auto& saveGame = m_SaveGames[idx.row()];
if (count < 10) {
- savesMsgLabel += "<li>" + QFileInfo(name).completeBaseName() + "</li>";
+ savesMsgLabel += "<li>" + QFileInfo(saveGame->getFilepath()).completeBaseName() + "</li>";
}
++count;
- if (info == nullptr) {
- deleteFiles.push_back(name);
- } else {
- ISaveGame const *save = info->getSaveGameInfo(name);
- deleteFiles += save->allFiles();
- delete save;
- }
+ deleteFiles += saveGame->allFiles();
}
if (count > 10) {
@@ -5032,8 +5013,8 @@ void MainWindow::on_savegameList_customContextMenuRequested(const QPoint& pos)
QAction* action = menu.addAction(tr("Enable Mods..."));
action->setEnabled(false);
if (selection->selectedIndexes().count() == 1) {
- QString save = ui->savegameList->currentItem()->data(Qt::UserRole).toString();
- SaveGameInfo::MissingAssets missing = info->getMissingAssets(save);
+ auto& save = m_SaveGames[selection->selectedIndexes()[0].row()];
+ SaveGameInfo::MissingAssets missing = info->getMissingAssets(*save);
if (missing.size() != 0) {
connect(action, &QAction::triggered, this, [this, missing] { fixMods_clicked(missing); });
action->setEnabled(true);
@@ -5229,9 +5210,7 @@ void MainWindow::installTranslator(const QString &name)
{
QTranslator *translator = new QTranslator(this);
QString fileName = name + "_" + m_CurrentLanguage;
- QString translationsPath = qApp->applicationDirPath()
- + "/" + QString::fromStdWString(AppConfig::translationsPath());
- if (!translator->load(fileName, translationsPath)) {
+ if (!translator->load(fileName, qApp->applicationDirPath() + "/translations")) {
if (m_CurrentLanguage.contains(QRegularExpression("^.*_(EN|en)(-.*)?$"))) {
log::debug("localization file %s not found", fileName);
} // we don't actually expect localization files for English (en, en-us, en-uk, and any variation thereof)
diff --git a/src/mainwindow.h b/src/mainwindow.h
index e2805b25..da7bb6ee 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -334,6 +334,7 @@ private:
QTime m_StartTime;
//SaveGameInfoWidget *m_CurrentSaveView;
+ std::vector<std::shared_ptr<const MOBase::ISaveGame>> m_SaveGames;
MOBase::ISaveGameInfoWidget *m_CurrentSaveView;
OrganizerCore &m_OrganizerCore;
@@ -344,6 +345,7 @@ private:
std::unique_ptr<BrowserDialog> m_IntegratedBrowser;
+ QTimer m_SavesWatcherTimer;
QFileSystemWatcher m_SavesWatcher;
QByteArray m_ArchiveListHash;
diff --git a/src/modinfowithconflictinfo.cpp b/src/modinfowithconflictinfo.cpp
index 6e3f751e..ad7eda3f 100644
--- a/src/modinfowithconflictinfo.cpp
+++ b/src/modinfowithconflictinfo.cpp
@@ -15,7 +15,7 @@ namespace fs = std::filesystem;
ModInfoWithConflictInfo::ModInfoWithConflictInfo(
PluginContainer *pluginContainer, const MOBase::IPluginGame* gamePlugin, DirectoryEntry **directoryStructure)
- : ModInfo(pluginContainer), m_GamePlugin(gamePlugin),
+ : ModInfo(pluginContainer), m_GamePlugin(gamePlugin),
m_FileTree([this]() { return QDirFileTree::makeTree(absolutePath()); }),
m_Valid([this]() { return doIsValid(); }),
m_Contents([this]() { return doGetContents(); }),
@@ -27,7 +27,7 @@ void ModInfoWithConflictInfo::clearCaches()
}
std::vector<ModInfo::EFlag> ModInfoWithConflictInfo::getFlags() const
-{
+{
std::vector<ModInfo::EFlag> result = std::vector<ModInfo::EFlag>();
if (hasHiddenFiles()) {
result.push_back(ModInfo::FLAG_HIDDEN_FILES);
diff --git a/src/modinfowithconflictinfo.h b/src/modinfowithconflictinfo.h
index feded99b..0d11fcb1 100644
--- a/src/modinfowithconflictinfo.h
+++ b/src/modinfowithconflictinfo.h
@@ -3,7 +3,7 @@
#include <ifiletree.h>
-#include "thread_utils.h"
+#include "memoizedlock.h"
#include "modinfo.h"
#include <set>
@@ -34,7 +34,9 @@ public:
*
* @return true if the content is there, false otherwise.
*/
- virtual bool hasContent(int content) const override; /**
+ virtual bool hasContent(int content) const override;
+
+ /**
* @brief Retrieve a file tree corresponding to the underlying disk content
* of this mod.
*
@@ -145,9 +147,9 @@ protected:
private:
- MOShared::MemoizedLocked<std::shared_ptr<const MOBase::IFileTree>> m_FileTree;
- MOShared::MemoizedLocked<bool> m_Valid;
- MOShared::MemoizedLocked<std::set<int>> m_Contents;
+ MOBase::MemoizedLocked<std::shared_ptr<const MOBase::IFileTree>> m_FileTree;
+ MOBase::MemoizedLocked<bool> m_Valid;
+ MOBase::MemoizedLocked<std::set<int>> m_Contents;
MOShared::DirectoryEntry **m_DirectoryStructure;
diff --git a/src/plugincontainer.cpp b/src/plugincontainer.cpp
index f7a556e0..44c9a651 100644
--- a/src/plugincontainer.cpp
+++ b/src/plugincontainer.cpp
@@ -119,9 +119,7 @@ PluginRequirements::PluginRequirements(
}
void PluginRequirements::fetchRequirements() {
- for (auto* requirement : m_Plugin->requirements()) {
- m_Requirements.emplace_back(requirement);
- }
+ m_Requirements = m_Plugin->requirements();
}
IPluginProxy* PluginRequirements::proxy() const
@@ -291,15 +289,17 @@ PluginContainer::~PluginContainer() {
unloadPlugins();
}
-void PluginContainer::setUserInterface(IUserInterface *userInterface, QWidget *widget)
+void PluginContainer::setUserInterface(IUserInterface *userInterface)
{
- for (IPluginProxy *proxy : bf::at_key<IPluginProxy>(m_Plugins)) {
- proxy->setParentWidget(widget);
- }
-
- if (userInterface != nullptr) {
- for (IPluginModPage *modPage : bf::at_key<IPluginModPage>(m_Plugins)) {
- userInterface->registerModPage(modPage);
+ if (userInterface) {
+ for (IPluginProxy* proxy : bf::at_key<IPluginProxy>(m_Plugins)) {
+ proxy->setParentWidget(userInterface->mainWindow());
+ }
+ for (IPluginModPage* modPage : bf::at_key<IPluginModPage>(m_Plugins)) {
+ modPage->setParentWidget(userInterface->mainWindow());
+ }
+ for (IPluginTool* tool : bf::at_key<IPluginTool>(m_Plugins)) {
+ tool->setParentWidget(userInterface->mainWindow());
}
}
diff --git a/src/plugincontainer.h b/src/plugincontainer.h
index 36edfad9..26e12659 100644
--- a/src/plugincontainer.h
+++ b/src/plugincontainer.h
@@ -109,7 +109,7 @@ private:
MOBase::IPlugin* m_Plugin;
MOBase::IPluginProxy* m_PluginProxy;
MOBase::IPlugin* m_Master;
- std::vector<std::unique_ptr<const MOBase::IPluginRequirement>> m_Requirements;
+ std::vector<std::shared_ptr<const MOBase::IPluginRequirement>> m_Requirements;
MOBase::IOrganizer* m_Organizer;
std::vector<MOBase::IPlugin*> m_RequiredFor;
@@ -188,7 +188,7 @@ public:
PluginContainer(OrganizerCore *organizer);
virtual ~PluginContainer();
- void setUserInterface(IUserInterface *userInterface, QWidget *widget);
+ void setUserInterface(IUserInterface *userInterface);
void loadPlugins();
void unloadPlugins();
diff --git a/src/qt.conf b/src/qt.conf
index 5e070fa3..f834a22a 100644
--- a/src/qt.conf
+++ b/src/qt.conf
@@ -1,7 +1,3 @@
[Paths]
-Libraries=dlls
-LibraryExecutables=resources
+Prefix=.
Plugins=dlls
-Imports=dlls
-Qml2Imports=dlls
-Translations=resources/translations \ No newline at end of file
diff --git a/src/settingsdialoggeneral.cpp b/src/settingsdialoggeneral.cpp
index 9eae2ba1..f29e1d24 100644
--- a/src/settingsdialoggeneral.cpp
+++ b/src/settingsdialoggeneral.cpp
@@ -81,9 +81,9 @@ void GeneralSettingsTab::addLanguages()
const QRegExp exp(pattern);
- QString translationsPath = qApp->applicationDirPath()
- + "/" + QString::fromStdWString(AppConfig::translationsPath());
- QDirIterator iter(translationsPath, QDir::Files);
+ QDirIterator iter(
+ QCoreApplication::applicationDirPath() + "/translations",
+ QDir::Files);
std::vector<std::pair<QString, QString>> languages;
diff --git a/src/shared/appconfig.inc b/src/shared/appconfig.inc
index 8d4125cf..5839c2f4 100644
--- a/src/shared/appconfig.inc
+++ b/src/shared/appconfig.inc
@@ -6,8 +6,7 @@ APPPARAM(std::wstring, downloadPath, L"downloads")
APPPARAM(std::wstring, overwritePath, L"overwrite")
APPPARAM(std::wstring, stylesheetsPath, L"stylesheets")
APPPARAM(std::wstring, cachePath, L"webcache")
-APPPARAM(std::wstring, tutorialsPath, L"resources/tutorials")
-APPPARAM(std::wstring, translationsPath, L"resources/translations")
+APPPARAM(std::wstring, tutorialsPath, L"tutorials")
APPPARAM(std::wstring, logPath, L"logs")
APPPARAM(std::wstring, dumpsDir, L"crashDumps")
APPPARAM(std::wstring, defaultProfileName, L"Default")
diff --git a/src/thread_utils.h b/src/thread_utils.h
index f64dd601..e816a4e2 100644
--- a/src/thread_utils.h
+++ b/src/thread_utils.h
@@ -24,51 +24,6 @@ std::thread startSafeThread(F&& f)
});
}
-
-/**
- * Class that can be used to perform thread-safe memoization.
- *
- * Each instance hold a flag indicating if the current value is up-to-date
- * or not. This flag can be reset using `invalidate()`. When the value is queried,
- * the flag is checked, and if it is not up-to-date, the given callback is used
- * to compute the value.
- *
- * The computation and update of the value is locked to avoid concurrent modifications.
- *
- * @tparam T Type of value ot memoized.
- * @tparam Fn Type of the callback.
- */
-template <class T, class Fn = std::function<T()>>
-struct MemoizedLocked {
-
- template <class Callable>
- MemoizedLocked(Callable &&callable, T value = {}) :
- m_Fn{ std::forward<Callable>(callable) }, m_Value{ std::move(value) } { }
-
- template <class... Args>
- T& value(Args&&... args) const {
- if (m_NeedUpdating) {
- std::scoped_lock lock(m_Mutex);
- if (m_NeedUpdating) {
- m_Value = std::invoke(m_Fn, std::forward<Args>(args)... );
- m_NeedUpdating = false;
- }
- }
- return m_Value;
- }
-
- void invalidate() {
- m_NeedUpdating = true;
- }
-
-private:
- mutable std::mutex m_Mutex;
- mutable std::atomic<bool> m_NeedUpdating{ true };
-
- Fn m_Fn;
- mutable T m_Value;
-};
-
/**
* @brief Apply the given callable to each element between the two given iterators
* in a parallel way.
diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp
index f8ebbb9d..5288d408 100644
--- a/src/transfersavesdialog.cpp
+++ b/src/transfersavesdialog.cpp
@@ -42,74 +42,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
using namespace MOBase;
using namespace MOShared;
-//These two classes give the save-transfer box a smidgin of useful info even
-//if save game isn't supported yet.
-namespace {
-
-class DummySave : public ISaveGame
-{
-public:
- DummySave(QString const &filename) :
- m_File(filename)
- {}
-
- ~DummySave() {}
-
- virtual QString getFilename() const override
- {
- return m_File;
- }
-
- virtual QDateTime getCreationTime() const override
- {
- return QFileInfo(m_File).birthTime();
- }
-
- virtual QString getSaveGroupIdentifier() const override
- {
- return m_File;
- }
-
- virtual QStringList allFiles() const override
- {
- return { m_File };
- }
-
- virtual bool hasScriptExtenderFile() const override
- {
- return false;
- }
-
-private:
- QString m_File;
-};
-
-class DummyInfo : public SaveGameInfo
-{
-public:
- virtual MOBase::ISaveGame const *getSaveGameInfo(QString const &file) const override
- {
- return new DummySave(file);
- }
-
- virtual MissingAssets getMissingAssets(QString const &) const override
- {
- return {};
- }
-
- MOBase::ISaveGameInfoWidget *getSaveGameWidget(QWidget *) const override
- {
- return nullptr;
- }
-
- virtual bool hasScriptExtenderSave(QString const &file) const override
- {
- return false;
- }
-};
-
-} //end anonymous namespace
-
TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame const *gamePlugin, QWidget *parent)
: TutorableDialog("TransferSaves", parent)
, ui(new Ui::TransferSavesDialog)
@@ -263,7 +195,7 @@ void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QStrin
SaveCollection::const_iterator saveList = m_GlobalSaves.find(currentText);
if (saveList != m_GlobalSaves.end()) {
for (SaveListItem const &save : saveList->second) {
- ui->globalSavesList->addItem(QFileInfo(save->getFilename()).fileName());
+ ui->globalSavesList->addItem(QFileInfo(save->getFilepath()).fileName());
}
}
}
@@ -276,7 +208,7 @@ void TransferSavesDialog::on_localCharacterList_currentTextChanged(const QString
SaveCollection::const_iterator saveList = m_LocalSaves.find(currentText);
if (saveList != m_LocalSaves.end()) {
for (SaveListItem const &save : saveList->second) {
- ui->localSavesList->addItem(QFileInfo(save->getFilename()).fileName());
+ ui->localSavesList->addItem(QFileInfo(save->getFilepath()).fileName());
}
}
}
@@ -285,34 +217,13 @@ void TransferSavesDialog::refreshSaves(SaveCollection &saveCollection, QString c
{
saveCollection.clear();
- SaveGameInfo const *info = m_GamePlugin->feature<SaveGameInfo>();
- if (info == nullptr) {
- static DummyInfo dummyInfo;
- info = &dummyInfo;
- }
-
- QStringList filters;
- filters << QString("*.") + m_GamePlugin->savegameExtension();
-
- QDir savesDir(savedir);
- savesDir.setNameFilters(QStringList() << QString("*.") + m_GamePlugin->savegameExtension());
- savesDir.setFilter(QDir::Files);
- QDirIterator it(savesDir, QDirIterator::Subdirectories);
- log::debug("reading save games from {}", savesDir.absolutePath());
-
- QFileInfoList files;
- while (it.hasNext()) {
- it.next();
- files.append(it.fileInfo());
- }
- std::sort(files.begin(), files.end(), [](auto const& lhs, auto const& rhs) {
- return lhs.fileTime(QFileDevice::FileModificationTime) < rhs.fileTime(QFileDevice::FileModificationTime);
+ auto saves = m_GamePlugin->listSaves(savedir);
+ std::sort(saves.begin(), saves.end(), [](auto const& lhs, auto const& rhs) {
+ return lhs->getCreationTime() > rhs->getCreationTime();
});
- for (const QFileInfo &file: files) {
- MOBase::ISaveGame const *save = info->getSaveGameInfo(file.absoluteFilePath());
- saveCollection[save->getSaveGroupIdentifier()].push_back(
- std::unique_ptr<MOBase::ISaveGame const>(save));
+ for (auto& save: saves) {
+ saveCollection[save->getSaveGroupIdentifier()].push_back(save);
}
}
@@ -334,7 +245,7 @@ void TransferSavesDialog::refreshCharacters(const SaveCollection &saveCollection
}
bool TransferSavesDialog::transferCharacters(
- QString const &character, char const *message,
+ QString const &character, char const *message,
QDir const& sourceDirectory,
SaveList &saves,
QDir const& destination,
diff --git a/src/transfersavesdialog.h b/src/transfersavesdialog.h
index b983ad9e..fe78aa83 100644
--- a/src/transfersavesdialog.h
+++ b/src/transfersavesdialog.h
@@ -80,9 +80,10 @@ private:
MOBase::IPluginGame const *m_GamePlugin;
- typedef std::unique_ptr<MOBase::ISaveGame const> SaveListItem;
- typedef std::vector<SaveListItem> SaveList;
- typedef std::map<QString, SaveList> SaveCollection;
+ using SaveListItem = std::shared_ptr<const MOBase::ISaveGame>;
+ using SaveList = std::vector<SaveListItem>;
+ using SaveCollection = std::map<QString, SaveList>;
+
SaveCollection m_GlobalSaves;
SaveCollection m_LocalSaves;
diff --git a/src/tutorials/TutorialOverlay.qml b/src/tutorials/TutorialOverlay.qml
index 0a31ef0e..47e5065d 100644
--- a/src/tutorials/TutorialOverlay.qml
+++ b/src/tutorials/TutorialOverlay.qml
@@ -55,9 +55,7 @@ Rectangle {
Connections {
target: manager
- function onTabChanged() {
- tabChanged(index)
- }
+ onTabChanged: tabChanged(index)
}
Tooltip {