From ba176e5e9b639ac0770192987833a3b40e71409a Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sun, 13 Dec 2015 18:30:40 +0000 Subject: Remove dependency of TransferSave on SaveGameBryo, part of fix for #418 Added a method to Profile class to get location of save games for the profile. I haven't added this to IProfile as am in two minds. Aside from this have done cleanups of issues suggested by include-what-you-use, and some OCD sorting of #includes --- src/transfersavesdialog.cpp | 409 ++++++++++++++++++++++---------------------- 1 file changed, 206 insertions(+), 203 deletions(-) (limited to 'src/transfersavesdialog.cpp') diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index 48fc4548..710a33b9 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -21,19 +21,70 @@ along with Mod Organizer. If not, see . #include "ui_transfersavesdialog.h" #include "iplugingame.h" -#include "savegamegamebyro.h" -#include "utility.h" +#include "isavegame.h" +#include "savegameinfo.h" +#include "scriptextender.h" +#include +#include #include +#include +#include +#include +#include +#include +#include #include +#include +#include -#include -#include - +class QWidget; //Do we /really/ need this? 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).created(); + } + + virtual QString getIdentifier() const override + { + return m_File; + } + +private: + QString m_File; +}; + +class DummyInfo : public SaveGameInfo +{ +public: + virtual MOBase::ISaveGame const *getSaveGameInfo(QString const &file) const override + { + return new DummySave(file); + } +}; + +} //end anonymous namespace TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame const *gamePlugin, QWidget *parent) : TutorableDialog("TransferSaves", parent) @@ -42,6 +93,7 @@ TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame con , m_GamePlugin(gamePlugin) { ui->setupUi(this); + ui->label_2->setText(tr("Characters for profile %1").arg(m_Profile.name())); refreshGlobalSaves(); refreshLocalSaves(); refreshGlobalCharacters(); @@ -53,84 +105,27 @@ TransferSavesDialog::~TransferSavesDialog() delete ui; } - void TransferSavesDialog::refreshGlobalSaves() { - m_GlobalSaves.clear(); - QDir savesDir(m_GamePlugin->savesDirectory()); - savesDir.setNameFilters(QStringList() << QString("*.%1").arg(m_GamePlugin->savegameExtension())); - - QStringList files = savesDir.entryList(QDir::Files, QDir::Time); - - for (const QString &filename : files) { - SaveGameGamebryo *save = new SaveGameGamebryo(this, savesDir.absoluteFilePath(filename), m_GamePlugin); - save->setParent(this); - m_GlobalSaves.push_back(save); - } + refreshSaves(m_GlobalSaves, m_GamePlugin->savesDirectory().absolutePath()); } void TransferSavesDialog::refreshLocalSaves() { - m_LocalSaves.clear(); - - QDir savesDir(m_Profile.absolutePath() + "/saves"); - - savesDir.setNameFilters(QStringList() << QString("*.%1").arg(m_GamePlugin->savegameExtension())); - - QStringList files = savesDir.entryList(QDir::Files, QDir::Time); - - foreach (const QString &filename, files) { - SaveGameGamebryo *save = new SaveGameGamebryo(this, savesDir.absoluteFilePath(filename), m_GamePlugin); - save->setParent(this); - m_LocalSaves.push_back(save); - } + refreshSaves(m_LocalSaves, m_Profile.savePath()); } void TransferSavesDialog::refreshGlobalCharacters() { - std::set characters; - for (std::vector::const_iterator iter = m_GlobalSaves.begin(); - iter != m_GlobalSaves.end(); ++iter) { - characters.insert((*iter)->pcName()); - } - ui->globalCharacterList->clear(); - for (std::set::const_iterator iter = characters.begin(); - iter != characters.end(); ++iter) { - ui->globalCharacterList->addItem(*iter); - } - if (ui->globalCharacterList->count() > 0) { - ui->globalCharacterList->setCurrentRow(0); - ui->copyToLocalBtn->setEnabled(true); - ui->moveToLocalBtn->setEnabled(true); - } else { - ui->copyToLocalBtn->setEnabled(false); - ui->moveToLocalBtn->setEnabled(false); - } + refreshCharacters(m_GlobalSaves, ui->globalCharacterList, ui->copyToLocalBtn, ui->moveToLocalBtn); } void TransferSavesDialog::refreshLocalCharacters() { - std::set characters; - for (std::vector::const_iterator iter = m_LocalSaves.begin(); - iter != m_LocalSaves.end(); ++iter) { - characters.insert((*iter)->pcName()); - } - ui->localCharacterList->clear(); - for (std::set::const_iterator iter = characters.begin(); - iter != characters.end(); ++iter) { - ui->localCharacterList->addItem(*iter); - } - if (ui->localCharacterList->count() > 0) { - ui->localCharacterList->setCurrentRow(0); - ui->copyToGlobalBtn->setEnabled(true); - ui->moveToGlobalBtn->setEnabled(true); - } else { - ui->copyToGlobalBtn->setEnabled(false); - ui->moveToGlobalBtn->setEnabled(false); - } + refreshCharacters(m_LocalSaves, ui->localCharacterList, ui->copyToGlobalBtn, ui->moveToGlobalBtn); } @@ -152,153 +147,71 @@ bool TransferSavesDialog::testOverwrite(OverwriteMode &overwriteMode, const QStr return res == QMessageBox::Yes; } +#define MOVE_SAVES "Move all save games of character \"%1\"" +#define COPY_SAVES "Copy all save games of character \"%1\"" + +#define TO_PROFILE "to the profile?" +#define TO_GLOBAL "to the global location? Please be aware that this will mess up the running number of save games." + void TransferSavesDialog::on_moveToLocalBtn_clicked() { - QString selectedCharacter = ui->globalCharacterList->currentItem()->text(); - if (QMessageBox::question(this, tr("Confirm"), - tr("Copy all save games of character \"%1\" to the profile?").arg(selectedCharacter), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - QString destination = m_Profile.absolutePath() + "/saves"; - OverwriteMode overwriteMode = OVERWRITE_ASK; - - for (std::vector::const_iterator iter = m_GlobalSaves.begin(); - iter != m_GlobalSaves.end(); ++iter) { - if ((*iter)->pcName() == selectedCharacter) { - QStringList files = (*iter)->saveFiles(); - foreach (const QString &file, files) { - QFileInfo fileInfo(file); - QString destinationFile = destination + "/" + fileInfo.fileName(); - if (QFile::exists(destinationFile)) { - if (testOverwrite(overwriteMode, destinationFile)) { - QFile::remove(destinationFile); - } else { - continue; - } - } - if (!QFile::rename(fileInfo.absoluteFilePath(), destinationFile)) { - qCritical("failed to move %s to %s", - fileInfo.absoluteFilePath().toUtf8().constData(), - destinationFile.toUtf8().constData()); - } - } - } - } + QString character = ui->globalCharacterList->currentItem()->text(); + if (transferCharacters(character, + MOVE_SAVES TO_PROFILE, + m_GlobalSaves[character], + m_Profile.savePath(), + QFile::rename, + "Failed to move %s to %s")) + { + refreshGlobalSaves(); + refreshGlobalCharacters(); + refreshLocalSaves(); + refreshLocalCharacters(); } - refreshGlobalSaves(); - refreshGlobalCharacters(); - refreshLocalSaves(); - refreshLocalCharacters(); } void TransferSavesDialog::on_copyToLocalBtn_clicked() { - QString selectedCharacter = ui->globalCharacterList->currentItem()->text(); - if (QMessageBox::question(this, tr("Confirm"), - tr("Copy all save games of character \"%1\" to the profile?").arg(selectedCharacter), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - QString destination = m_Profile.absolutePath() + "/saves"; - OverwriteMode overwriteMode = OVERWRITE_ASK; - for (std::vector::const_iterator iter = m_GlobalSaves.begin(); - iter != m_GlobalSaves.end(); ++iter) { - if ((*iter)->pcName() == selectedCharacter) { - QStringList files = (*iter)->saveFiles(); - foreach (const QString &file, files) { - QFileInfo fileInfo(file); - QString destinationFile = destination + "/" + fileInfo.fileName(); - if (QFile::exists(destinationFile)) { - if (testOverwrite(overwriteMode, destinationFile)) { - QFile::remove(destinationFile); - } else { - continue; - } - } - if (!QFile::copy(fileInfo.absoluteFilePath(), destinationFile)) { - qCritical("failed to copy %s to %s", - fileInfo.absoluteFilePath().toUtf8().constData(), - destinationFile.toUtf8().constData()); - } - } - } - } + QString character = ui->globalCharacterList->currentItem()->text(); + if (transferCharacters(character, + COPY_SAVES TO_PROFILE, + m_GlobalSaves[character], + m_Profile.savePath(), + QFile::copy, + "Failed to copy %s to %s")) { + refreshLocalSaves(); + refreshLocalCharacters(); } - refreshLocalSaves(); - refreshLocalCharacters(); } void TransferSavesDialog::on_moveToGlobalBtn_clicked() { - QString selectedCharacter = ui->localCharacterList->currentItem()->text(); - if (QMessageBox::question(this, tr("Confirm"), - tr("Move all save games of character \"%1\" to the global location? Please be aware " - "that this will mess up the running number of save games.").arg(selectedCharacter), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - - QDir destination = m_GamePlugin->savesDirectory(); - OverwriteMode overwriteMode = OVERWRITE_ASK; - for (std::vector::const_iterator iter = m_LocalSaves.begin(); - iter != m_LocalSaves.end(); ++iter) { - if ((*iter)->pcName() == selectedCharacter) { - QStringList files = (*iter)->saveFiles(); - foreach (const QString &file, files) { - QFileInfo fileInfo(file); - QString destinationFile = destination.filePath(fileInfo.fileName()); - if (QFile::exists(destinationFile)) { - if (testOverwrite(overwriteMode, destinationFile)) { - QFile::remove(destinationFile); - } else { - continue; - } - } - if (!QFile::rename(fileInfo.absoluteFilePath(), destinationFile)) { - qCritical("failed to move %s to %s", - fileInfo.absoluteFilePath().toUtf8().constData(), - destinationFile.toUtf8().constData()); - } - } - } - } + QString character = ui->localCharacterList->currentItem()->text(); + if (transferCharacters(character, + MOVE_SAVES TO_GLOBAL, + m_LocalSaves[character], + m_GamePlugin->savesDirectory().absolutePath(), + QFile::rename, + "Failed to move %s to %s")) { + refreshGlobalSaves(); + refreshGlobalCharacters(); + refreshLocalSaves(); + refreshLocalCharacters(); } - refreshGlobalSaves(); - refreshGlobalCharacters(); - refreshLocalSaves(); - refreshLocalCharacters(); } void TransferSavesDialog::on_copyToGlobalBtn_clicked() { - QString selectedCharacter = ui->localCharacterList->currentItem()->text(); - if (QMessageBox::question(this, tr("Confirm"), - tr("Copy all save games of character \"%1\" to the global location? Please be aware " - "that this will mess up the running number of save games.").arg(selectedCharacter), - QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { - - QDir destination = m_GamePlugin->savesDirectory(); - OverwriteMode overwriteMode = OVERWRITE_ASK; - for (std::vector::const_iterator iter = m_LocalSaves.begin(); - iter != m_LocalSaves.end(); ++iter) { - if ((*iter)->pcName() == selectedCharacter) { - QStringList files = (*iter)->saveFiles(); - foreach (const QString &file, files) { - QFileInfo fileInfo(file); - QString destinationFile = destination.filePath(fileInfo.fileName()); - if (QFile::exists(destinationFile)) { - if (testOverwrite(overwriteMode, destinationFile)) { - QFile::remove(destinationFile); - } else { - continue; - } - } - if (!QFile::copy(fileInfo.absoluteFilePath(), destinationFile)) { - qCritical("failed to copy %s to %s", - fileInfo.absoluteFilePath().toUtf8().constData(), - destinationFile.toUtf8().constData()); - } - } - } - } + QString character = ui->localCharacterList->currentItem()->text(); + if (transferCharacters(character, + COPY_SAVES TO_GLOBAL, + m_LocalSaves[character], + m_GamePlugin->savesDirectory().absolutePath(), + QFile::copy, + "Failed to copy %s to %s")) { + refreshGlobalSaves(); + refreshGlobalCharacters(); } - refreshGlobalSaves(); - refreshGlobalCharacters(); } void TransferSavesDialog::on_doneButton_clicked() @@ -309,10 +222,12 @@ void TransferSavesDialog::on_doneButton_clicked() void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QString ¤tText) { ui->globalSavesList->clear(); - for (std::vector::const_iterator iter = m_GlobalSaves.begin(); - iter != m_GlobalSaves.end(); ++iter) { - if ((*iter)->pcName() == currentText) { - ui->globalSavesList->addItem(QFileInfo((*iter)->fileName()).fileName()); + //sadly this can get called while we're resetting the list, with an invalid + //name, so we have to check. + 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()); } } } @@ -320,10 +235,98 @@ void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QStrin void TransferSavesDialog::on_localCharacterList_currentTextChanged(const QString ¤tText) { ui->localSavesList->clear(); - for (std::vector::const_iterator iter = m_LocalSaves.begin(); - iter != m_LocalSaves.end(); ++iter) { - if ((*iter)->pcName() == currentText) { - ui->localSavesList->addItem(QFileInfo((*iter)->fileName()).fileName()); + //sadly this can get called while we're resetting the list, with an invalid + //name, so we have to check. + 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()); + } + } +} + +void TransferSavesDialog::refreshSaves(SaveCollection &saveCollection, QString const &savedir) +{ + saveCollection.clear(); + QDir savesDir(savedir); + savesDir.setNameFilters(QStringList() << QString("*.%1").arg(m_GamePlugin->savegameExtension())); + + SaveGameInfo const *info = m_GamePlugin->feature(); + if (info == nullptr) { + static DummyInfo dummyInfo; + info = &dummyInfo; + } + + QStringList files = savesDir.entryList(QDir::Files, QDir::Time); + for (const QString &filename : files) { + QString file = savesDir.absoluteFilePath(filename); + MOBase::ISaveGame const *save = info->getSaveGameInfo(file); + saveCollection[save->getIdentifier()].push_back( + std::unique_ptr(save)); + } +} + +void TransferSavesDialog::refreshCharacters(const SaveCollection &saveCollection, + QListWidget *charList, QPushButton *copy, QPushButton *move) +{ + charList->clear(); + for (SaveCollection::value_type const &val : saveCollection) { + charList->addItem(val.first); + } + if (charList->count() > 0) { + charList->setCurrentRow(0); + copy->setEnabled(true); + move->setEnabled(true); + } else { + copy->setEnabled(false); + move->setEnabled(false); + } +} + +bool TransferSavesDialog::transferCharacters(QString const &character, + char const *message, + SaveList &saves, + QString const &dest, + bool (method)(QString const &, QString const &), + char const *errmsg) +{ + if (QMessageBox::question(this, tr("Confirm"), + tr(message).arg(character), + QMessageBox::Yes | QMessageBox::No) != QMessageBox::Yes) { + return false; + } + + OverwriteMode overwriteMode = OVERWRITE_ASK; + + QStringList extensions = { m_GamePlugin->savegameExtension() }; + { + ScriptExtender *ext = m_GamePlugin->feature(); + if (ext != nullptr) { + extensions += ext->saveGameAttachmentExtensions(); + } + } + QDir destination(dest); + for (SaveListItem const &save : saves) { + QFileInfo const saveFile = save->getFilename(); + for (QString const &ext : extensions) { + QFileInfo sourceFile(saveFile.absoluteDir().absoluteFilePath(saveFile.completeBaseName() + "." + ext)); + QString destinationFile = destination.absoluteFilePath(sourceFile.fileName()); + + //If the file is already there, let them skip (or not). + if (QFile::exists(destinationFile)) { + if (! testOverwrite(overwriteMode, destinationFile)) { + continue; + } + //OK, they want to remove it. + QFile::remove(destinationFile); + } + + if (! method(sourceFile.absoluteFilePath(), destinationFile)) { + qCritical(errmsg, + sourceFile.absoluteFilePath().toUtf8().constData(), + destinationFile.toUtf8().constData()); + } } } + return true; } -- cgit v1.3.1 From 0c536a4c12e37caec2c3107875a97d5343c2a0a0 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Tue, 15 Dec 2015 15:58:01 +0000 Subject: Makes iSaveGame responsible for returning all files involved in savegame. Cleans up save deletion and save transfer dialogue somewhat --- src/mainwindow.cpp | 86 +++++++++++++++++++++------------------------ src/transfersavesdialog.cpp | 19 +++++----- 2 files changed, 48 insertions(+), 57 deletions(-) (limited to 'src/transfersavesdialog.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8c292f08..03233398 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -28,9 +28,11 @@ along with Mod Organizer. If not, see . #include "imodinterface.h" #include "iplugingame.h" #include "iplugindiagnose.h" +#include "isavegame.h" #include "nexusinterface.h" #include "organizercore.h" #include "previewgenerator.h" +#include "savegameinfo.h" #include "spawn.h" #include "versioninfo.h" @@ -70,7 +72,6 @@ along with Mod Organizer. If not, see . #include "safewritefile.h" #include "savegameinfowidget.h" #include "savegameinfowidgetgamebryo.h" -#include "scriptextender.h" #include "nxmaccessmanager.h" #include "appconfig.h" #include @@ -83,61 +84,63 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include +#include #include +#include #include +#include +#include #include +#include #include #include #include +#include #include #include #include #include #include +#include #include +#include +#include +#include +#include #include #include +#include +#include +#include #include #include #include #include #include +#include +#include #include +#include #include #include +#include #include #include #include #include +#include +#include +#include +#include #include #include -#include -#include - -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include + +#include +#include #if QT_VERSION >= QT_VERSION_CHECK(5,0,0) @@ -146,9 +149,6 @@ along with Mod Organizer. If not, see . #include #endif -#include -#include - #ifndef Q_MOC_RUN #include #include @@ -3220,34 +3220,26 @@ void MainWindow::on_categoriesList_itemSelectionChanged() void MainWindow::deleteSavegame_clicked() { - QModelIndexList selectedIndexes = ui->savegameList->selectionModel()->selectedIndexes(); - - //This feels wrong and should be part of savegame interface - QStringList extensions; - { - ScriptExtender *extender = m_OrganizerCore.managedGame()->feature(); - if (extender != nullptr) { - extensions += extender->saveGameAttachmentExtensions(); - } - } + SaveGameInfo const *info = m_OrganizerCore.managedGame()->feature(); QString savesMsgLabel; QStringList deleteFiles; int count = 0; - for (const QModelIndex &idx : selectedIndexes) { - //QString name = idx.data().toString(); - QFileInfo fileName(idx.data(Qt::UserRole).toString()); + for (const QModelIndex &idx : ui->savegameList->selectionModel()->selectedIndexes()) { + QString name = idx.data(Qt::UserRole).toString(); if (count < 10) { - savesMsgLabel += "
  • " + fileName.completeBaseName() + "
  • "; + savesMsgLabel += "
  • " + QFileInfo(name).completeBaseName() + "
  • "; } ++count; - deleteFiles << fileName.absoluteFilePath(); - for (QString const &ext : extensions) { - deleteFiles << fileName.absoluteDir().absoluteFilePath(fileName.completeBaseName() + "." + ext); + if (info == nullptr) { + deleteFiles.push_back(name); + } else { + ISaveGame const *save = info->getSaveGameInfo(name); + deleteFiles += save->allFiles(); } } @@ -3256,7 +3248,9 @@ void MainWindow::deleteSavegame_clicked() } if (QMessageBox::question(this, tr("Confirm"), - tr("Are you sure you want to remove the following %n save(s)?
      %1

    Removed saves will be sent to the Recycle Bin.", "", selectedIndexes.count()) + tr("Are you sure you want to remove the following %n save(s)?
    " + "
      %1

    " + "Removed saves will be sent to the Recycle Bin.", "", count) .arg(savesMsgLabel), QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) { shellDelete(deleteFiles, true); // recycle bin delete. diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index 710a33b9..b07a9510 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -71,6 +71,11 @@ public: return m_File; } + virtual QStringList allFiles() const override + { + return { m_File }; + } + private: QString m_File; }; @@ -298,19 +303,11 @@ bool TransferSavesDialog::transferCharacters(QString const &character, OverwriteMode overwriteMode = OVERWRITE_ASK; - QStringList extensions = { m_GamePlugin->savegameExtension() }; - { - ScriptExtender *ext = m_GamePlugin->feature(); - if (ext != nullptr) { - extensions += ext->saveGameAttachmentExtensions(); - } - } QDir destination(dest); for (SaveListItem const &save : saves) { - QFileInfo const saveFile = save->getFilename(); - for (QString const &ext : extensions) { - QFileInfo sourceFile(saveFile.absoluteDir().absoluteFilePath(saveFile.completeBaseName() + "." + ext)); - QString destinationFile = destination.absoluteFilePath(sourceFile.fileName()); + for (QString source : save->allFiles()) { + QFileInfo sourceFile(source); + QString destinationFile(destination.absoluteFilePath(sourceFile.fileName())); //If the file is already there, let them skip (or not). if (QFile::exists(destinationFile)) { -- cgit v1.3.1 From 30b29635f67d6ab1cd00b6787ab58bf36934da55 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Tue, 15 Dec 2015 16:00:15 +0000 Subject: unsaved edits... --- src/transfersavesdialog.cpp | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/transfersavesdialog.cpp') diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index b07a9510..a2201a69 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -23,7 +23,6 @@ along with Mod Organizer. If not, see . #include "iplugingame.h" #include "isavegame.h" #include "savegameinfo.h" -#include "scriptextender.h" #include #include @@ -38,8 +37,6 @@ along with Mod Organizer. If not, see . #include #include -class QWidget; //Do we /really/ need this? - using namespace MOBase; using namespace MOShared; -- cgit v1.3.1 From 5f5184ebfe9a6b7102654863cbb390a610ab1563 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sat, 19 Dec 2015 20:49:54 +0000 Subject: Changes to support getting list of mods / esps to activate from game plugin --- src/activatemodsdialog.cpp | 22 +++++----- src/activatemodsdialog.h | 10 ++++- src/mainwindow.cpp | 97 ++++++++++----------------------------------- src/mainwindow.h | 3 +- src/modinfo.h | 1 - src/organizercore.cpp | 35 +++++++++++++--- src/organizercore.h | 29 ++++++++++---- src/organizerproxy.cpp | 8 +++- src/organizerproxy.h | 5 ++- src/transfersavesdialog.cpp | 6 +++ 10 files changed, 112 insertions(+), 104 deletions(-) (limited to 'src/transfersavesdialog.cpp') diff --git a/src/activatemodsdialog.cpp b/src/activatemodsdialog.cpp index fd56ae3e..5ef0a4e5 100644 --- a/src/activatemodsdialog.cpp +++ b/src/activatemodsdialog.cpp @@ -21,9 +21,14 @@ along with Mod Organizer. If not, see . #include "ui_activatemodsdialog.h" #include +#include #include +#include +#include -ActivateModsDialog::ActivateModsDialog(const std::map > &missingPlugins, QWidget *parent) +#include + +ActivateModsDialog::ActivateModsDialog(SaveGameInfo::MissingAssets const &missingAssets, QWidget *parent) : TutorableDialog("ActivateMods", parent), ui(new Ui::ActivateModsDialog) { ui->setupUi(this); @@ -40,18 +45,17 @@ ActivateModsDialog::ActivateModsDialog(const std::mapsetRowCount(missingPlugins.size()); + modsTable->setRowCount(missingAssets.size()); - for (std::map >::const_iterator espIter = missingPlugins.begin(); - espIter != missingPlugins.end(); ++espIter, ++row) { - modsTable->setCellWidget(row, 0, new QLabel(espIter->first)); - if (espIter->second.size() == 0) { + for (SaveGameInfo::MissingAssets::const_iterator espIter = missingAssets.begin(); + espIter != missingAssets.end(); ++espIter, ++row) { + modsTable->setCellWidget(row, 0, new QLabel(espIter.key())); + if (espIter->size() == 0) { modsTable->setCellWidget(row, 1, new QLabel(tr("not found"))); } else { QComboBox* combo = new QComboBox(); - for (std::vector::const_iterator modIter = espIter->second.begin(); - modIter != espIter->second.end(); ++modIter) { - combo->addItem(*modIter); + for (QString const &mod : espIter.value()) { + combo->addItem(mod); } modsTable->setCellWidget(row, 1, combo); } diff --git a/src/activatemodsdialog.h b/src/activatemodsdialog.h index 08dbad8d..f36b5fde 100644 --- a/src/activatemodsdialog.h +++ b/src/activatemodsdialog.h @@ -20,8 +20,14 @@ along with Mod Organizer. If not, see . #ifndef ACTIVATEMODSDIALOG_H #define ACTIVATEMODSDIALOG_H +#include "savegameinfo.h" #include "tutorabledialog.h" -#include + +#include + +class QString; +class QWidget; + #include namespace Ui { @@ -42,7 +48,7 @@ public: * @param missingPlugins a map containing missing plugins that need to be activated * @param parent ... Defaults to 0. **/ - explicit ActivateModsDialog(const std::map > &missingPlugins, QWidget *parent = 0); + explicit ActivateModsDialog(SaveGameInfo::MissingAssets const &missingAssets, QWidget *parent = 0); ~ActivateModsDialog(); /** diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 03233398..0b551c5b 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -31,6 +31,7 @@ along with Mod Organizer. If not, see . #include "isavegame.h" #include "nexusinterface.h" #include "organizercore.h" +#include "pluginlistsortproxy.h" #include "previewgenerator.h" #include "savegameinfo.h" #include "spawn.h" @@ -104,6 +105,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include @@ -124,6 +126,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include @@ -134,6 +137,7 @@ along with Mod Organizer. If not, see . #include #include #include +#include #include #include #include @@ -3258,78 +3262,9 @@ void MainWindow::deleteSavegame_clicked() } -void MainWindow::fixMods_clicked() +void MainWindow::fixMods_clicked(SaveGameInfo::MissingAssets const &missingAssets) { - QListWidgetItem *selectedItem = ui->savegameList->currentItem(); - - if (selectedItem == nullptr) - return; - - // if required, parse the save game - if (selectedItem->data(Qt::UserRole).isNull()) { - QVariant temp; - SaveGameGamebryo *save = getSaveGame(selectedItem->data(Qt::UserRole).toString()); - save->setParent(selectedItem->listWidget()); - temp.setValue(save); - selectedItem->setData(Qt::UserRole, temp); - } - - const SaveGameGamebryo *save = getSaveGame(selectedItem); - - // collect the list of missing plugins - std::map > missingPlugins; - - for (int i = 0; i < save->numPlugins(); ++i) { - const QString &pluginName = save->plugin(i); - if (!m_OrganizerCore.pluginList()->isEnabled(pluginName)) { - missingPlugins[pluginName] = std::vector(); - } - } - - // figure out, for each esp/esm, which mod, if any, contains it - QStringList espFilter("*.esp"); - espFilter.append("*.esm"); - - // search in data - { - QDir dataDir(m_OrganizerCore.managedGame()->dataDirectory()); - QStringList esps = dataDir.entryList(espFilter); - for (const QString &esp : esps) { - std::map >::iterator iter = missingPlugins.find(esp); - if (iter != missingPlugins.end()) { - iter->second.push_back(""); - } - } - } - - // search in mods - for (unsigned int i = 0; i < m_OrganizerCore.currentProfile()->numRegularMods(); ++i) { - int modIndex = m_OrganizerCore.currentProfile()->modIndexByPriority(i); - ModInfo::Ptr modInfo = ModInfo::getByIndex(modIndex); - - QStringList esps = QDir(modInfo->absolutePath()).entryList(espFilter); - for (const QString &esp : esps) { - std::map >::iterator iter = missingPlugins.find(esp); - if (iter != missingPlugins.end()) { - iter->second.push_back(modInfo->name()); - } - } - } - - // search in overwrite - { - QDir overwriteDir(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::overwritePath())); - QStringList esps = overwriteDir.entryList(espFilter); - for (const QString &esp : esps) { - std::map >::iterator iter = missingPlugins.find(esp); - if (iter != missingPlugins.end()) { - iter->second.push_back(""); - } - } - } - - - ActivateModsDialog dialog(missingPlugins, this); + ActivateModsDialog dialog(missingAssets, this); if (dialog.exec() == QDialog::Accepted) { // activate the required mods, then enable all esps std::set modsToActivate = dialog.getModsToActivate(); @@ -3356,13 +3291,25 @@ void MainWindow::on_savegameList_customContextMenuRequested(const QPoint &pos) { QItemSelectionModel *selection = ui->savegameList->selectionModel(); - if (!selection->hasSelection()) + if (!selection->hasSelection()) { return; + } QMenu menu; - - if (!(selection->selectedIndexes().count() > 1)) - menu.addAction(tr("Fix Mods..."), this, SLOT(fixMods_clicked())); + QAction *action = menu.addAction(tr("Enable Mods...")); + action->setEnabled(false); + + if (selection->selectedIndexes().count() == 1) { + SaveGameInfo const *info = this->m_OrganizerCore.managedGame()->feature(); + if (info != nullptr) { + QString save = ui->savegameList->currentItem()->data(Qt::UserRole).toString(); + SaveGameInfo::MissingAssets missing = info->getMissingAssets(save); + if (missing.size() != 0) { + connect(action, &QAction::triggered, this, [this, missing]{ fixMods_clicked(missing); }); + action->setEnabled(true); + } + } + } QString deleteMenuLabel = tr("Delete %n save(s)", "", selection->selectedIndexes().count()); diff --git a/src/mainwindow.h b/src/mainwindow.h index 04e9f221..a8c3ec0e 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -28,6 +28,7 @@ along with Mod Organizer. If not, see . #include "iuserinterface.h" #include "modinfo.h" #include "modlistsortproxy.h" +#include "savegameinfo.h" #include "tutorialcontrol.h" //Note the commented headers here can be replaced with forward references, @@ -393,7 +394,7 @@ private slots: void information_clicked(); // savegame context menu void deleteSavegame_clicked(); - void fixMods_clicked(); + void fixMods_clicked(SaveGameInfo::MissingAssets const &missingAssets); // data-tree context menu void writeDataToFile(); void openDataFile(); diff --git a/src/modinfo.h b/src/modinfo.h index ae22ccd8..c10232da 100644 --- a/src/modinfo.h +++ b/src/modinfo.h @@ -22,7 +22,6 @@ along with Mod Organizer. If not, see . #include "imodinterface.h" #include "versioninfo.h" -//#include class QDateTime; class QDir; diff --git a/src/organizercore.cpp b/src/organizercore.cpp index 06a6dba4..e92ecb97 100644 --- a/src/organizercore.cpp +++ b/src/organizercore.cpp @@ -1,15 +1,19 @@ #include "organizercore.h" +#include "imodinterface.h" #include "iplugingame.h" -#include "mainwindow.h" +#include "iuserinterface.h" +#include "loadmechanism.h" #include "messagedialog.h" +#include "modlistsortproxy.h" +#include "plugincontainer.h" +#include "pluginlistsortproxy.h" #include "logbuffer.h" #include "credentialsdialog.h" #include "filedialogmemory.h" #include "lockeddialog.h" #include "modinfodialog.h" #include "spawn.h" -#include "safewritefile.h" #include "syncoverwritedialog.h" #include "nxmaccessmanager.h" #include @@ -17,18 +21,27 @@ #include #include #include -#include +#include "appconfig.h" #include #include -#include -#include -#include #include +#include +#include +#include +#include +#include +#include + +#include #include +#include #include +#include +#include +#include using namespace MOShared; @@ -867,6 +880,16 @@ ModList *OrganizerCore::modList() return &m_ModList; } +QStringList OrganizerCore::modsSortedByProfilePriority() const +{ + QStringList res; + for (unsigned int i = 0; i < currentProfile()->numRegularMods(); ++i) { + int modIndex = currentProfile()->modIndexByPriority(i); + res.push_back(ModInfo::getByIndex(modIndex)->name()); + } + return res; +} + void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &arguments, const QDir ¤tDirectory, bool closeAfterStart, const QString &steamAppID) { LockedDialog *dialog = new LockedDialog(qApp->activeWindow()); diff --git a/src/organizercore.h b/src/organizercore.h index 5cfbaca4..b50b3e9f 100644 --- a/src/organizercore.h +++ b/src/organizercore.h @@ -2,30 +2,42 @@ #define ORGANIZERCORE_H -#include "profile.h" #include "selfupdater.h" -#include "iuserinterface.h" +#include "iuserinterface.h" //should be class IUserInterface; #include "settings.h" #include "modlist.h" +#include "modinfo.h" #include "pluginlist.h" #include "directoryrefresher.h" #include "installationmanager.h" #include "downloadmanager.h" -#include "modlistsortproxy.h" -#include "pluginlistsortproxy.h" #include "executableslist.h" -#include #include #include -#include #include -#include #include #include + +class ModListSortProxy; +class PluginListSortProxy; +class Profile; +namespace MOBase { template class GuessedValue; } +namespace MOShared { class DirectoryEntry; } + +#include +#include +#include #include #include +#include #include +class QNetworkReply; +class QUrl; +class QWidget; + +#include +#include class PluginContainer; @@ -89,7 +101,7 @@ public: m_ExecutablesList = executablesList; } - Profile *currentProfile() { return m_CurrentProfile; } + Profile *currentProfile() const { return m_CurrentProfile; } void setCurrentProfile(const QString &profileName); std::vector enabledArchives(); @@ -155,6 +167,7 @@ public: bool onAboutToRun(const std::function &func); bool onFinishedRun(const std::function &func); void refreshModList(bool saveChanges = true); + QStringList modsSortedByProfilePriority() const; //std::vector > fileMapping(); diff --git a/src/organizerproxy.cpp b/src/organizerproxy.cpp index ba07c154..474f0837 100644 --- a/src/organizerproxy.cpp +++ b/src/organizerproxy.cpp @@ -1,6 +1,7 @@ #include "organizerproxy.h" -#include +#include "appconfig.h" +#include "organizercore.h" #include @@ -170,3 +171,8 @@ MOBase::IPluginGame const *OrganizerProxy::managedGame() const { return m_Proxied->managedGame(); } + +QStringList OrganizerProxy::modsSortedByProfilePriority() const +{ + return m_Proxied->modsSortedByProfilePriority(); +} diff --git a/src/organizerproxy.h b/src/organizerproxy.h index 62a35498..2a0fc397 100644 --- a/src/organizerproxy.h +++ b/src/organizerproxy.h @@ -3,7 +3,8 @@ #include -#include "mainwindow.h" + +class OrganizerCore; class OrganizerProxy : public MOBase::IOrganizer { @@ -47,6 +48,8 @@ public: virtual MOBase::IPluginGame const *managedGame() const; + virtual QStringList modsSortedByProfilePriority() const; + private: OrganizerCore *m_Proxied; diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index a2201a69..b6be108b 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -84,6 +84,12 @@ public: { return new DummySave(file); } + + virtual MissingAssets getMissingAssets(QString const &) const override + { + return {}; + } + }; } //end anonymous namespace -- cgit v1.3.1 From 6edf12f2f7089364611c7f979ad20fa867604477 Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Sun, 20 Dec 2015 21:22:38 +0000 Subject: Rename the save game identifier method to make it clearer what it's for. --- src/transfersavesdialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/transfersavesdialog.cpp') diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index b6be108b..2f1c41a1 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -63,7 +63,7 @@ public: return QFileInfo(m_File).created(); } - virtual QString getIdentifier() const override + virtual QString getSaveGroupIdentifier() const override { return m_File; } @@ -269,7 +269,7 @@ void TransferSavesDialog::refreshSaves(SaveCollection &saveCollection, QString c for (const QString &filename : files) { QString file = savesDir.absoluteFilePath(filename); MOBase::ISaveGame const *save = info->getSaveGameInfo(file); - saveCollection[save->getIdentifier()].push_back( + saveCollection[save->getSaveGroupIdentifier()].push_back( std::unique_ptr(save)); } } -- cgit v1.3.1 From 3869eaaf2bfacf4a44733b8346d790999588c37f Mon Sep 17 00:00:00 2001 From: Thomas Tanner Date: Fri, 25 Dec 2015 21:57:23 +0000 Subject: Transferring the savegame widget into gamebryo + some cleanup --- src/mainwindow.cpp | 40 +++++++++++++------------------------- src/mainwindow.h | 7 +++---- src/savegameinfowidgetgamebryo.cpp | 4 +++- src/transfersavesdialog.cpp | 4 ++++ 4 files changed, 24 insertions(+), 31 deletions(-) (limited to 'src/transfersavesdialog.cpp') diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index 8f71f636..0a690a8e 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -29,6 +29,7 @@ along with Mod Organizer. If not, see . #include "iplugingame.h" #include "iplugindiagnose.h" #include "isavegame.h" +#include "isavegameinfowidget.h" #include "nexusinterface.h" #include "organizercore.h" #include "pluginlistsortproxy.h" @@ -864,33 +865,25 @@ void MainWindow::setBrowserGeometry(const QByteArray &geometry) m_IntegratedBrowser.restoreGeometry(geometry); } -ISaveGame const *MainWindow::getSaveGame(QListWidgetItem *item) +void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem) { - try { + QString const &save = newItem->data(Qt::UserRole).toString(); + if (m_CurrentSaveView == nullptr) { + //FIXME Is this the right place? IPluginGame const *game = m_OrganizerCore.managedGame(); SaveGameInfo const *info = game->feature(); if (info != nullptr) { - return info->getSaveGameInfo(item->data(Qt::UserRole).toString()); + m_CurrentSaveView = info->getSaveGameWidget(this); + } + if (m_CurrentSaveView == nullptr) { + return; } - //SaveGameGamebryo *saveGame = new SaveGameGamebryo(/*this,*/ item->data(Qt::UserRole).toString(), game); - //saveGame->setParent(item->listWidget()); - //return saveGame; - } catch (const std::exception &e) { - reportError(tr("failed to read savegame: %1").arg(e.what())); - } - return nullptr; -} - -void MainWindow::displaySaveGameInfo(MOBase::ISaveGame const *save, QPoint pos) -{ - if (m_CurrentSaveView == nullptr) { - m_CurrentSaveView = new SaveGameInfoWidgetGamebryo(save, m_OrganizerCore.pluginList(), this); - } else { - m_CurrentSaveView->setSave(save); } + m_CurrentSaveView->setSave(save); QRect screenRect = QApplication::desktop()->availableGeometry(m_CurrentSaveView); + QPoint pos = QCursor::pos(); if (pos.x() + m_CurrentSaveView->width() > screenRect.right()) { pos.rx() -= (m_CurrentSaveView->width() + 2); } else { @@ -905,8 +898,9 @@ void MainWindow::displaySaveGameInfo(MOBase::ISaveGame const *save, QPoint pos) m_CurrentSaveView->move(pos); m_CurrentSaveView->show(); + m_CurrentSaveView->setProperty("displayItem", qVariantFromValue(static_cast(newItem))); + ui->savegameList->activateWindow(); - connect(m_CurrentSaveView, SIGNAL(closeSaveInfo()), this, SLOT(hideSaveGameInfo())); } @@ -915,20 +909,14 @@ void MainWindow::saveSelectionChanged(QListWidgetItem *newItem) if (newItem == nullptr) { hideSaveGameInfo(); } else if (m_CurrentSaveView == nullptr || newItem != m_CurrentSaveView->property("displayItem").value()) { - MOBase::ISaveGame const *save = getSaveGame(newItem); - if (save != nullptr) { - displaySaveGameInfo(save, QCursor::pos()); - m_CurrentSaveView->setProperty("displayItem", qVariantFromValue(static_cast(newItem))); - } + displaySaveGameInfo(newItem); } } - void MainWindow::hideSaveGameInfo() { if (m_CurrentSaveView != nullptr) { - disconnect(m_CurrentSaveView, SIGNAL(closeSaveInfo()), this, SLOT(hideSaveGameInfo())); m_CurrentSaveView->deleteLater(); m_CurrentSaveView = nullptr; } diff --git a/src/mainwindow.h b/src/mainwindow.h index 07f24540..0fd15d85 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -256,9 +256,7 @@ private: void setCategoryListVisible(bool visible); - MOBase::ISaveGame const *getSaveGame(QListWidgetItem *item); - - void displaySaveGameInfo(MOBase::ISaveGame const *save, QPoint pos); + void displaySaveGameInfo(QListWidgetItem *newItem); HANDLE nextChildProcess(); @@ -333,7 +331,8 @@ private: QTimer m_UpdateProblemsTimer; QTime m_StartTime; - SaveGameInfoWidget *m_CurrentSaveView; + //SaveGameInfoWidget *m_CurrentSaveView; + MOBase::ISaveGameInfoWidget *m_CurrentSaveView; OrganizerCore &m_OrganizerCore; PluginContainer &m_PluginContainer; diff --git a/src/savegameinfowidgetgamebryo.cpp b/src/savegameinfowidgetgamebryo.cpp index 854043a3..1836a8f2 100644 --- a/src/savegameinfowidgetgamebryo.cpp +++ b/src/savegameinfowidgetgamebryo.cpp @@ -54,7 +54,9 @@ void SaveGameInfoWidgetGamebryo::setSave(MOBase::ISaveGame const *saveGame) layout->addWidget(header); int count = 0; for (QString const &pluginName : gamebryoSave->getPlugins()) { - if (m_PluginList->isEnabled(pluginName)) { + //if (m_PluginList->isEnabled(pluginName)) { + //should use IPluginList * in interface + if (m_PluginList->state(pluginName) == MOBase::IPluginList::STATE_ACTIVE) { continue; } diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index 2f1c41a1..cb3d0d61 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -90,6 +90,10 @@ public: return {}; } + MOBase::ISaveGameInfoWidget *getSaveGameWidget(QWidget *) const override + { + return nullptr; + } }; } //end anonymous namespace -- cgit v1.3.1