diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/CMakeLists.txt | 9 | ||||
| -rw-r--r-- | src/aboutdialog.cpp | 8 | ||||
| -rw-r--r-- | src/aboutdialog.h | 7 | ||||
| -rw-r--r-- | src/activatemodsdialog.cpp | 22 | ||||
| -rw-r--r-- | src/activatemodsdialog.h | 10 | ||||
| -rw-r--r-- | src/iuserinterface.h | 1 | ||||
| -rw-r--r-- | src/mainwindow.cpp | 298 | ||||
| -rw-r--r-- | src/mainwindow.h | 112 | ||||
| -rw-r--r-- | src/modinfo.h | 1 | ||||
| -rw-r--r-- | src/organizer.pro | 9 | ||||
| -rw-r--r-- | src/organizercore.cpp | 35 | ||||
| -rw-r--r-- | src/organizercore.h | 29 | ||||
| -rw-r--r-- | src/organizerproxy.cpp | 8 | ||||
| -rw-r--r-- | src/organizerproxy.h | 5 | ||||
| -rw-r--r-- | src/profile.cpp | 36 | ||||
| -rw-r--r-- | src/profile.h | 19 | ||||
| -rw-r--r-- | src/profilesdialog.cpp | 24 | ||||
| -rw-r--r-- | src/profilesdialog.h | 15 | ||||
| -rw-r--r-- | src/savegame.cpp | 69 | ||||
| -rw-r--r-- | src/savegame.h | 121 | ||||
| -rw-r--r-- | src/savegamegamebryo.cpp | 66 | ||||
| -rw-r--r-- | src/savegamegamebyro.h | 77 | ||||
| -rw-r--r-- | src/savegameinfowidget.cpp | 65 | ||||
| -rw-r--r-- | src/savegameinfowidget.h | 61 | ||||
| -rw-r--r-- | src/savegameinfowidget.ui | 209 | ||||
| -rw-r--r-- | src/savegameinfowidgetgamebryo.cpp | 80 | ||||
| -rw-r--r-- | src/savegameinfowidgetgamebryo.h | 44 | ||||
| -rw-r--r-- | src/transfersavesdialog.cpp | 415 | ||||
| -rw-r--r-- | src/transfersavesdialog.h | 34 |
29 files changed, 603 insertions, 1286 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3c786868..b80283af 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -18,10 +18,6 @@ SET(organizer_SRCS settings.cpp selfupdater.cpp selectiondialog.cpp - savegameinfowidgetgamebryo.cpp - savegameinfowidget.cpp - savegamegamebryo.cpp - savegame.cpp queryoverwritedialog.cpp profilesdialog.cpp profile.cpp @@ -112,10 +108,6 @@ SET(organizer_HDRS settings.h selfupdater.h selectiondialog.h - savegameinfowidgetgamebryo.h - savegameinfowidget.h - savegamegamebyro.h - savegame.h queryoverwritedialog.h profilesdialog.h profile.h @@ -204,7 +196,6 @@ SET(organizer_UIS simpleinstalldialog.ui settingsdialog.ui selectiondialog.ui - savegameinfowidget.ui queryoverwritedialog.ui profilesdialog.ui overwriteinfodialog.ui diff --git a/src/aboutdialog.cpp b/src/aboutdialog.cpp index 6fce2acb..3657a10d 100644 --- a/src/aboutdialog.cpp +++ b/src/aboutdialog.cpp @@ -22,6 +22,14 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "ui_aboutdialog.h"
#include <utility.h>
+#include <QApplication>
+#include <QLabel>
+#include <QListWidget>
+#include <QListWidgetItem>
+#include <QTextBrowser>
+#include <QVariant>
+#include <Qt>
+
AboutDialog::AboutDialog(const QString &version, QWidget *parent)
: QDialog(parent)
diff --git a/src/aboutdialog.h b/src/aboutdialog.h index c3b38c10..103a0d2f 100644 --- a/src/aboutdialog.h +++ b/src/aboutdialog.h @@ -22,10 +22,11 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #define ABOUTDIALOG_H
#include <QDialog>
-#include <QListWidgetItem>
+class QListWidgetItem;
+#include <QObject>
+#include <QString>
+
#include <map>
-#include <vector>
-#include <utility>
namespace Ui {
class AboutDialog;
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 <http://www.gnu.org/licenses/>. #include "ui_activatemodsdialog.h"
#include <QComboBox>
+#include <QHeaderView>
#include <QLabel>
+#include <QString>
+#include <QTableWidget>
-ActivateModsDialog::ActivateModsDialog(const std::map<QString, std::vector<QString> > &missingPlugins, QWidget *parent)
+#include <QtGlobal>
+
+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::map<QString, std::vector<QStri int row = 0;
- modsTable->setRowCount(missingPlugins.size());
+ modsTable->setRowCount(missingAssets.size());
- for (std::map<QString, std::vector<QString> >::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<QString>::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 <http://www.gnu.org/licenses/>. #ifndef ACTIVATEMODSDIALOG_H
#define ACTIVATEMODSDIALOG_H
+#include "savegameinfo.h"
#include "tutorabledialog.h"
-#include <map>
+
+#include <QObject>
+
+class QString;
+class QWidget;
+
#include <set>
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<QString, std::vector<QString> > &missingPlugins, QWidget *parent = 0);
+ explicit ActivateModsDialog(SaveGameInfo::MissingAssets const &missingAssets, QWidget *parent = 0);
~ActivateModsDialog();
/**
diff --git a/src/iuserinterface.h b/src/iuserinterface.h index bcf800b7..e03bcde2 100644 --- a/src/iuserinterface.h +++ b/src/iuserinterface.h @@ -7,6 +7,7 @@ #include <ipluginmodpage.h>
#include <delayedfilewriter.h>
+class QSettings;
class IUserInterface
{
diff --git a/src/mainwindow.cpp b/src/mainwindow.cpp index f30e46f1..4d608d59 100644 --- a/src/mainwindow.cpp +++ b/src/mainwindow.cpp @@ -20,7 +20,24 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "mainwindow.h"
#include "ui_mainwindow.h"
+#include "directoryentry.h"
+#include "directoryrefresher.h"
+#include "executableinfo.h"
+#include "executableslist.h"
+#include "guessedvalue.h"
+#include "imodinterface.h"
+#include "iplugingame.h"
+#include "iplugindiagnose.h"
+#include "isavegame.h"
+#include "isavegameinfowidget.h"
+#include "nexusinterface.h"
+#include "organizercore.h"
+#include "pluginlistsortproxy.h"
+#include "previewgenerator.h"
+#include "savegameinfo.h"
#include "spawn.h"
+#include "versioninfo.h"
+
#include "report.h"
#include "modlist.h"
#include "modlistsortproxy.h"
@@ -31,7 +48,6 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "editexecutablesdialog.h"
#include "categories.h"
#include "categoriesdialog.h"
-#include "utility.h"
#include "modinfodialog.h"
#include "overwriteinfodialog.h"
#include "activatemodsdialog.h"
@@ -41,16 +57,13 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "messagedialog.h"
#include "installationmanager.h"
#include "lockeddialog.h"
-#include "syncoverwritedialog.h"
#include "logbuffer.h"
#include "downloadlistsortproxy.h"
#include "motddialog.h"
#include "filedialogmemory.h"
-#include "questionboxmemory.h"
#include "tutorialmanager.h"
#include "modflagicondelegate.h"
#include "genericicondelegate.h"
-#include "credentialsdialog.h"
#include "selectiondialog.h"
#include "csvbuilder.h"
#include "savetextasdialog.h"
@@ -59,82 +72,103 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "browserdialog.h"
#include "aboutdialog.h"
#include "safewritefile.h"
-//?
-//#include "isavegame.h"
-//#include "savegameinfo.h"
-//?
#include "nxmaccessmanager.h"
-#include <archive.h>
-#include <appconfig.h>
+#include "appconfig.h"
#include <utility.h>
-#include <ipluginproxy.h>
#include <dataarchives.h>
#include <bsainvalidation.h>
-#include <questionboxmemory.h>
#include <taskprogressmanager.h>
-#include <util.h>
#include <scopeguard.h>
-#include <QTime>
-#include <QInputDialog>
-#include <QSettings>
-#include <QWhatsThis>
-#include <QProcess>
-#include <QMenu>
+#include <QAbstractItemDelegate>
+#include <QAbstractProxyModel>
+#include <QAction>
+#include <QApplication>
#include <QBuffer>
-#include <QInputDialog>
-#include <QDirIterator>
-#include <QHelpEvent>
-#include <QToolTip>
-#include <QFileDialog>
-#include <QTimer>
-#include <QMessageBox>
+#include <QCheckBox>
+#include <QClipboard>
+#include <QCloseEvent>
+#include <QCoreApplication>
+#include <QCursor>
#include <QDebug>
-#include <QBuffer>
-#include <QWidgetAction>
-#include <QToolButton>
-#include <QGraphicsObject>
-#include <QPluginLoader>
-#include <QRadioButton>
#include <QDesktopWidget>
-#include <QtPlugin>
-#include <QIdentityProxyModel>
-#include <QClipboard>
-#include <QNetworkInterface>
-#include <QNetworkProxy>
-#include <QJsonDocument>
+#include <QDialog>
+#include <QDirIterator>
+#include <QDragEnterEvent>
+#include <QDropEvent>
+#include <QEvent>
+#include <QFileDialog>
+#include <QFont>
+#include <QFuture>
+#include <QHash>
+#include <QIODevice>
+#include <QIcon>
+#include <QInputDialog>
+#include <QItemSelection>
+#include <QItemSelectionModel>
#include <QJsonArray>
+#include <QJsonDocument>
#include <QJsonObject>
-#include <QJsonValue>
+#include <QJsonValueRef>
+#include <QLineEdit>
+#include <QListWidgetItem>
+#include <QMenu>
+#include <QMessageBox>
#include <QMimeData>
+#include <QModelIndex>
+#include <QNetworkProxyFactory>
+#include <QPainter>
+#include <QPixmap>
+#include <QPoint>
+#include <QProcess>
+#include <QProgressDialog>
+#include <QPushButton>
+#include <QRadioButton>
+#include <QRect>
+#include <QRegExp>
+#include <QResizeEvent>
+#include <QSettings>
+#include <QScopedPointer>
+#include <QSizePolicy>
+#include <QSize>
+#include <QTime>
+#include <QTimer>
+#include <QToolButton>
+#include <QToolTip>
+#include <QTranslator>
+#include <QTreeWidget>
+#include <QUrl>
+#include <QVariantList>
+#include <QWhatsThis>
+#include <QWidgetAction>
+
+#include <QtDebug>
+#include <QtGlobal>
+
+
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtConcurrent/QtConcurrentRun>
#else
#include <QtConcurrentRun>
#endif
-#include <QCoreApplication>
-#include <QProgressDialog>
#ifndef Q_MOC_RUN
#include <boost/thread.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/bind.hpp>
-#include <boost/foreach.hpp>
#include <boost/assign.hpp>
#endif
-#include <Psapi.h>
#include <shlobj.h>
-#include <ShellAPI.h>
-#include <TlHelp32.h>
-#include <sstream>
-#include <regex>
+#include <limits.h>
+#include <exception>
#include <functional>
#include <map>
-#include <ctime>
-#include <wchar.h>
-#include <utility.h>
+#include <regex>
+#include <stdexcept>
+#include <sstream>
+#include <utility>
#ifdef TEST_MODELS
#include "modeltest.h"
@@ -829,37 +863,24 @@ void MainWindow::setBrowserGeometry(const QByteArray &geometry) m_IntegratedBrowser.restoreGeometry(geometry);
}
-
-SaveGameGamebryo *MainWindow::getSaveGame(const QString &name)
-{
- IPluginGame const *game = m_OrganizerCore.managedGame();
- return new SaveGameGamebryo(this, name, game);
-}
-
-
-SaveGameGamebryo *MainWindow::getSaveGame(QListWidgetItem *item)
-{
- try {
- SaveGameGamebryo *saveGame = getSaveGame(item->data(Qt::UserRole).toString());
- 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(const SaveGameGamebryo *save, QPoint pos)
+void MainWindow::displaySaveGameInfo(QListWidgetItem *newItem)
{
+ QString const &save = newItem->data(Qt::UserRole).toString();
if (m_CurrentSaveView == nullptr) {
- m_CurrentSaveView = new SaveGameInfoWidgetGamebryo(save, m_OrganizerCore.pluginList(), this);
- } else {
- m_CurrentSaveView->setSave(save);
+ IPluginGame const *game = m_OrganizerCore.managedGame();
+ SaveGameInfo const *info = game->feature<SaveGameInfo>();
+ if (info != nullptr) {
+ m_CurrentSaveView = info->getSaveGameWidget(this);
+ }
+ if (m_CurrentSaveView == nullptr) {
+ return;
+ }
}
+ 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 {
@@ -874,8 +895,9 @@ void MainWindow::displaySaveGameInfo(const SaveGameGamebryo *save, QPoint pos) m_CurrentSaveView->move(pos);
m_CurrentSaveView->show();
+ m_CurrentSaveView->setProperty("displayItem", qVariantFromValue(static_cast<void *>(newItem)));
+
ui->savegameList->activateWindow();
- connect(m_CurrentSaveView, SIGNAL(closeSaveInfo()), this, SLOT(hideSaveGameInfo()));
}
@@ -883,21 +905,15 @@ void MainWindow::saveSelectionChanged(QListWidgetItem *newItem) {
if (newItem == nullptr) {
hideSaveGameInfo();
- } else if ((m_CurrentSaveView == nullptr) || (newItem != m_CurrentSaveView->property("displayItem").value<void*>())) {
- const SaveGameGamebryo *save = getSaveGame(newItem);
- if (save != nullptr) {
- displaySaveGameInfo(save, QCursor::pos());
- m_CurrentSaveView->setProperty("displayItem", qVariantFromValue((void*)newItem));
- }
+ } else if (m_CurrentSaveView == nullptr || newItem != m_CurrentSaveView->property("displayItem").value<void*>()) {
+ displaySaveGameInfo(newItem);
}
}
-
void MainWindow::hideSaveGameInfo()
{
if (m_CurrentSaveView != nullptr) {
- disconnect(m_CurrentSaveView, SIGNAL(closeSaveInfo()), this, SLOT(hideSaveGameInfo()));
m_CurrentSaveView->deleteLater();
m_CurrentSaveView = nullptr;
}
@@ -1262,7 +1278,7 @@ QDir MainWindow::currentSavesDir() const {
QDir savesDir;
if (m_OrganizerCore.currentProfile()->localSavesEnabled()) {
- savesDir.setPath(m_OrganizerCore.currentProfile()->absolutePath() + "/saves");
+ savesDir.setPath(m_OrganizerCore.currentProfile()->savePath());
} else {
wchar_t path[MAX_PATH];
::GetPrivateProfileStringW(
@@ -3189,109 +3205,47 @@ void MainWindow::on_categoriesList_itemSelectionChanged() void MainWindow::deleteSavegame_clicked()
{
- QModelIndexList selectedIndexes = ui->savegameList->selectionModel()->selectedIndexes();
+ SaveGameInfo const *info = m_OrganizerCore.managedGame()->feature<SaveGameInfo>();
QString savesMsgLabel;
QStringList deleteFiles;
int count = 0;
- foreach (const QModelIndex &idx, selectedIndexes) {
- QString name = idx.data().toString();
- SaveGame *save = new SaveGame(this, idx.data(Qt::UserRole).toString(), m_OrganizerCore.managedGame());
+ for (const QModelIndex &idx : ui->savegameList->selectionModel()->selectedIndexes()) {
+ QString name = idx.data(Qt::UserRole).toString();
if (count < 10) {
savesMsgLabel += "<li>" + QFileInfo(name).completeBaseName() + "</li>";
}
++count;
- deleteFiles << save->saveFiles();
+ if (info == nullptr) {
+ deleteFiles.push_back(name);
+ } else {
+ ISaveGame const *save = info->getSaveGameInfo(name);
+ deleteFiles += save->allFiles();
+ }
}
if (count > 10) {
savesMsgLabel += "<li><i>... " + tr("%1 more").arg(count - 10) + "</i></li>";
}
- if (QMessageBox::question(this, tr("Confirm"), tr("Are you sure you want to remove the following %n save(s)?<br><ul>%1</ul><br>Removed saves will be sent to the Recycle Bin.", "", selectedIndexes.count())
- .arg(savesMsgLabel),
+ if (QMessageBox::question(this, tr("Confirm"),
+ tr("Are you sure you want to remove the following %n save(s)?<br>"
+ "<ul>%1</ul><br>"
+ "Removed saves will be sent to the Recycle Bin.", "", count)
+ .arg(savesMsgLabel),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
shellDelete(deleteFiles, true); // recycle bin delete.
}
}
-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<QString, std::vector<QString> > 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<QString>();
- }
- }
-
- // 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<QString, std::vector<QString> >::iterator iter = missingPlugins.find(esp);
- if (iter != missingPlugins.end()) {
- iter->second.push_back("<data>");
- }
- }
- }
-
- // 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<QString, std::vector<QString> >::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<QString, std::vector<QString> >::iterator iter = missingPlugins.find(esp);
- if (iter != missingPlugins.end()) {
- iter->second.push_back("<overwrite>");
- }
- }
- }
-
-
- ActivateModsDialog dialog(missingPlugins, this);
+ ActivateModsDialog dialog(missingAssets, this);
if (dialog.exec() == QDialog::Accepted) {
// activate the required mods, then enable all esps
std::set<QString> modsToActivate = dialog.getModsToActivate();
@@ -3318,13 +3272,25 @@ void MainWindow::on_savegameList_customContextMenuRequested(const QPoint &pos) {
QItemSelectionModel *selection = ui->savegameList->selectionModel();
- if (!selection->hasSelection())
+ if (!selection->hasSelection()) {
return;
+ }
QMenu menu;
+ QAction *action = menu.addAction(tr("Enable Mods..."));
+ action->setEnabled(false);
- if (!(selection->selectedIndexes().count() > 1))
- menu.addAction(tr("Fix Mods..."), this, SLOT(fixMods_clicked()));
+ if (selection->selectedIndexes().count() == 1) {
+ SaveGameInfo const *info = this->m_OrganizerCore.managedGame()->feature<SaveGameInfo>();
+ 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 0cdea807..177048b4 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -20,51 +20,83 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #ifndef MAINWINDOW_H
#define MAINWINDOW_H
-#include <QMainWindow>
-#include <QFileInfo>
-#include <QDir>
-#include <QTreeWidget>
-#include <QListWidgetItem>
-#include <QProcess>
-#include <QThread>
-#include <QProgressBar>
-#include <QTranslator>
-#include <QPluginLoader>
-#include "modlist.h"
-#include "pluginlist.h"
-#include "plugincontainer.h"
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <archive.h>
-#include "directoryrefresher.h"
-#include <imoinfo.h>
-#include "settings.h"
-#include "downloadmanager.h"
-#include "installationmanager.h"
-#include "selfupdater.h"
-#include "savegamegamebyro.h"
-#include "modlistsortproxy.h"
-#include "pluginlistsortproxy.h"
-#include "tutorialcontrol.h"
-#include "savegameinfowidgetgamebryo.h"
-#include "previewgenerator.h"
+#include "bsafolder.h"
#include "browserdialog.h"
+#include "delayedfilewriter.h"
+#include "errorcodes.h"
+#include "imoinfo.h"
#include "iuserinterface.h"
-#include <guessedvalue.h>
-#include <directoryentry.h>
-#include <delayedfilewriter.h>
+#include "modinfo.h"
+#include "modlistsortproxy.h"
+#include "savegameinfo.h"
+#include "tutorialcontrol.h"
+
+//Note the commented headers here can be replaced with forward references,
+//when I get round to cleaning up main.cpp
+struct Executable;
+class CategoryFactory;
+class LockedDialog;
+class OrganizerCore;
+#include "plugincontainer.h" //class PluginContainer;
+class PluginListSortProxy;
+namespace BSA { class Archive; }
+#include "iplugingame.h" //namespace MOBase { class IPluginGame; }
+namespace MOBase { class IPluginModPage; }
+namespace MOBase { class IPluginTool; }
+namespace MOBase { class ISaveGame; }
+
+namespace MOShared { class DirectoryEntry; }
+
+#include <QByteArray>
+#include <QDir>
+#include <QFileInfo>
+#include <QFileSystemWatcher>
+#include <QList>
+#include <QMainWindow>
+#include <QObject>
+#include <QPersistentModelIndex>
+#include <QProcess>
+#include <QString>
+#include <QStringList>
+#include <QTime>
+#include <QTimer>
+#include <QVariant>
+#include <Qt>
+
+class QAction;
+class QAbstractItemModel;
+class QDateTime;
+class QEvent;
+class QFile;
+class QListWidgetItem;
+class QMenu;
+class QModelIndex;
+class QPoint;
+class QProgressBar;
+class QProgressDialog;
+class QTranslator;
+class QTreeWidgetItem;
+class QUrl;
+class QSettings;
+class QWidget;
+
#ifndef Q_MOC_RUN
#include <boost/signals2.hpp>
#endif
+//Sigh - just for HANDLE
+#define WIN32_LEAN_AND_MEAN
+#include <Windows.h>
+
+#include <functional>
+#include <set>
+#include <string>
+#include <vector>
+
namespace Ui {
class MainWindow;
}
-class LockedDialog;
-class QToolButton;
-class ModListSortProxy;
-class ModListGroupCategoriesProxy;
class MainWindow : public QMainWindow, public IUserInterface
@@ -223,10 +255,7 @@ private: void setCategoryListVisible(bool visible);
- SaveGameGamebryo *getSaveGame(const QString &name);
- SaveGameGamebryo *getSaveGame(QListWidgetItem *item);
-
- void displaySaveGameInfo(const SaveGameGamebryo *save, QPoint pos);
+ void displaySaveGameInfo(QListWidgetItem *newItem);
HANDLE nextChildProcess();
@@ -301,7 +330,8 @@ private: QTimer m_UpdateProblemsTimer;
QTime m_StartTime;
- SaveGameInfoWidget *m_CurrentSaveView;
+ //SaveGameInfoWidget *m_CurrentSaveView;
+ MOBase::ISaveGameInfoWidget *m_CurrentSaveView;
OrganizerCore &m_OrganizerCore;
PluginContainer &m_PluginContainer;
@@ -362,7 +392,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 <http://www.gnu.org/licenses/>. #include "imodinterface.h"
#include "versioninfo.h"
-//#include <directoryentry.h>
class QDateTime;
class QDir;
diff --git a/src/organizer.pro b/src/organizer.pro index 1284aa40..0ef2638b 100644 --- a/src/organizer.pro +++ b/src/organizer.pro @@ -27,10 +27,6 @@ SOURCES += \ settings.cpp \
selfupdater.cpp \
selectiondialog.cpp \
- savegameinfowidgetgamebryo.cpp \
- savegameinfowidget.cpp \
- savegamegamebryo.cpp \
- savegame.cpp \
queryoverwritedialog.cpp \
profilesdialog.cpp \
profile.cpp \
@@ -107,10 +103,6 @@ HEADERS += \ settings.h \
selfupdater.h \
selectiondialog.h \
- savegameinfowidgetgamebryo.h \
- savegameinfowidget.h \
- savegamegamebyro.h \
- savegame.h \
queryoverwritedialog.h \
profilesdialog.h \
profile.h \
@@ -183,7 +175,6 @@ FORMS += \ simpleinstalldialog.ui \
settingsdialog.ui \
selectiondialog.ui \
- savegameinfowidget.ui \
queryoverwritedialog.ui \
profilesdialog.ui \
overwriteinfodialog.ui \
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 <ipluginmodpage.h>
@@ -17,18 +21,27 @@ #include <directoryentry.h>
#include <scopeguard.h>
#include <utility.h>
-#include <appconfig.h>
+#include "appconfig.h"
#include <report.h>
#include <questionboxmemory.h>
-#include <QNetworkInterface>
-#include <QMessageBox>
-#include <QDialogButtonBox>
#include <QApplication>
+#include <QDialogButtonBox>
+#include <QMessageBox>
+#include <QNetworkInterface>
+#include <QProcess>
+#include <QTimer>
+#include <QWidget>
+
+#include <QtDebug>
#include <Psapi.h>
+#include <exception>
#include <functional>
+#include <memory>
+#include <set>
+#include <utility>
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 <directoryentry.h>
#include <imoinfo.h>
#include <iplugindiagnose.h>
-#include <iplugingame.h>
#include <versioninfo.h>
-#include <guessedvalue.h>
#include <delayedfilewriter.h>
#include <boost/signals2.hpp>
+
+class ModListSortProxy;
+class PluginListSortProxy;
+class Profile;
+namespace MOBase { template <typename T> class GuessedValue; }
+namespace MOShared { class DirectoryEntry; }
+
+#include <QDir>
+#include <QList>
+#include <QObject>
#include <QSettings>
#include <QString>
+#include <QStringList>
#include <QThread>
+class QNetworkReply;
+class QUrl;
+class QWidget;
+
+#include <functional>
+#include <vector>
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<QString> enabledArchives();
@@ -155,6 +167,7 @@ public: bool onAboutToRun(const std::function<bool (const QString &)> &func);
bool onFinishedRun(const std::function<void (const QString &, unsigned int)> &func);
void refreshModList(bool saveChanges = true);
+ QStringList modsSortedByProfilePriority() const;
//std::vector<std::pair<QString, QString> > 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 <appconfig.h>
+#include "appconfig.h"
+#include "organizercore.h"
#include <QApplication>
@@ -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 <imoinfo.h>
-#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/profile.cpp b/src/profile.cpp index 77f6ebd1..b0b8db46 100644 --- a/src/profile.cpp +++ b/src/profile.cpp @@ -19,30 +19,40 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "profile.h" -#include "windows_error.h" #include "modinfo.h" #include "safewritefile.h" #include <utility.h> -#include <util.h> #include <error_report.h> -#include <appconfig.h> +#include "appconfig.h" #include <iplugingame.h> #include <report.h> #include <bsainvalidation.h> #include <dataarchives.h> -#include <QMessageBox> #include <QApplication> -#include <QSettings> -#include <QTemporaryFile> +#include <QFile> // for QFile +#include <QFlags> // for operator|, QFlags +#include <QIODevice> // for QIODevice, etc +#include <QMessageBox> +#include <QScopedArrayPointer> +#include <QStringList> // for QStringList +#include <QtDebug> // for qDebug, qWarning, etc +#include <QtGlobal> // for qPrintable + +#include <Windows.h> +#include <assert.h> // for assert +#include <limits.h> // for UINT_MAX, INT_MAX, etc +#include <stddef.h> // for size_t +#include <string.h> // for wcslen + +#include <algorithm> // for max, min +#include <exception> // for exception #include <functional> +#include <set> // for set +#include <utility> // for find #include <stdexcept> -#define WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <shlobj.h> - using namespace MOBase; using namespace MOShared; @@ -687,6 +697,12 @@ QString Profile::absolutePath() const return QDir::cleanPath(m_Directory.absolutePath()); } +QString Profile::savePath() const +{ + return QDir::cleanPath(m_Directory.absoluteFilePath("saves")); + +} + void Profile::rename(const QString &newName) { QDir profileDir(qApp->property("dataPath").toString() + "/" + QString::fromStdWString(AppConfig::profilesPath())); diff --git a/src/profile.h b/src/profile.h index e33ac674..39e8ff5f 100644 --- a/src/profile.h +++ b/src/profile.h @@ -25,12 +25,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include <iprofile.h> #include <delayedfilewriter.h> -#include <QString> +#include <QByteArray> #include <QDir> -#include <QSettings> +#include <QObject> +#include <QString> -#include <vector> +#include <boost/shared_ptr.hpp> + +#include <string> #include <tuple> +#include <vector> namespace MOBase { class IPluginGame; } @@ -172,6 +176,15 @@ public: **/ QString absolutePath() const; + /** + * @return path to this profile's save games + **/ + QString savePath() const; + + /** + * @brief rename profile + * @param newName new name of profile + */ void rename(const QString &newName); /** diff --git a/src/profilesdialog.cpp b/src/profilesdialog.cpp index b21aee53..4d0b3389 100644 --- a/src/profilesdialog.cpp +++ b/src/profilesdialog.cpp @@ -19,22 +19,28 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "profilesdialog.h"
#include "ui_profilesdialog.h"
+
+#include "appconfig.h"
+#include "bsainvalidation.h"
+#include "iplugingame.h"
+#include "profile.h"
+#include "profileinputdialog.h"
#include "report.h"
-#include "utility.h"
#include "transfersavesdialog.h"
-#include "profileinputdialog.h"
-#include "mainwindow.h"
-#include "aboutdialog.h"
-#include <iplugingame.h>
-#include <bsainvalidation.h>
-#include <appconfig.h>
-#include <QListWidgetItem>
+#include "utility.h"
+
+#include <Qt>
+#include <QDir>
+#include <QDirIterator>
#include <QInputDialog>
#include <QLineEdit>
-#include <QDirIterator>
+#include <QListWidgetItem>
#include <QMessageBox>
#include <QWhatsThis>
+#include <Windows.h>
+
+#include <exception>
using namespace MOBase;
using namespace MOShared;
diff --git a/src/profilesdialog.h b/src/profilesdialog.h index 073d92b7..0e79b94b 100644 --- a/src/profilesdialog.h +++ b/src/profilesdialog.h @@ -21,17 +21,16 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #define PROFILESDIALOG_H
#include "tutorabledialog.h"
-#include <QListWidgetItem>
-#include "profile.h"
+class Profile;
+class QListWidget;
+class QListWidgetItem;
+#include <QObject>
+class QString;
-namespace Ui {
- class ProfilesDialog;
-}
+namespace Ui { class ProfilesDialog; }
-namespace MOBase {
- class IPluginGame;
-}
+namespace MOBase { class IPluginGame; }
/**
diff --git a/src/savegame.cpp b/src/savegame.cpp deleted file mode 100644 index 2b125575..00000000 --- a/src/savegame.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "savegame.h"
-
-#include "iplugingame.h"
-#include "scriptextender.h"
-#include "utility.h"
-
-#include <QApplication>
-#include <QDateTime>
-#include <QFile>
-#include <QFileInfo>
-
-#include <limits>
-#include <set>
-
-using namespace MOBase;
-
-SaveGame::SaveGame(QObject *parent, const QString &filename, const MOBase::IPluginGame *game)
- : QObject(parent)
- , m_FileName(filename)
- , m_Game(game)
-{
-}
-
-SaveGame::~SaveGame()
-{
-}
-
-QStringList SaveGame::attachedFiles() const
-{
- QStringList result;
- ScriptExtender const *extender = m_Game->feature<ScriptExtender>();
- if (extender != nullptr) {
- for (QString const &ext : extender->saveGameAttachmentExtensions()) {
- QFileInfo fi(fileName());
- fi.setFile(fi.canonicalPath() + "/" + fi.completeBaseName() + "." + ext);
- if (fi.exists()) {
- result.append(fi.filePath());
- }
- }
- }
-
- return result;
-}
-
-QStringList SaveGame::saveFiles() const
-{
- QStringList result = attachedFiles();
- result.append(fileName());
- return result;
-}
diff --git a/src/savegame.h b/src/savegame.h deleted file mode 100644 index d1bf4691..00000000 --- a/src/savegame.h +++ /dev/null @@ -1,121 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SAVEGAME_H
-#define SAVEGAME_H
-
-
-#include <QString>
-#include <QObject>
-#include <QImage>
-#include <QMetaType>
-#include <QFile>
-#include <QStringList>
-
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-
-namespace MOBase { class IPluginGame; }
-
-/**
- * @brief represents a single save game
- **/
-class SaveGame : public QObject {
-
-Q_OBJECT
-
-public:
-
- /**
- * @brief construct a save game and immediately read out information from the file
- *
- * @param filename absolute path of the save game file
- **/
- SaveGame(QObject *parent, const QString &filename, MOBase::IPluginGame const *game);
-
- virtual ~SaveGame();
-
- /**
- * @brief read out information from a savegame
- *
- * @param fileName absolute path of the save game file
- **/
- virtual void readFile(const QString) { }
-
- /**
- * @return filename of this savegame
- */
- const QString &fileName() const { return m_FileName; }
-
- /**
- * @return a list of additional files that belong to this savegame
- */
- virtual QStringList attachedFiles() const;
-
- /**
- * @return a list of all files that belong to this savegame
- */
- virtual QStringList saveFiles() const;
-
- /**
- * @return name of the player character
- **/
- const QString &pcName() const { return m_PCName; }
-
- /**
- * @return level of the player character
- **/
- unsigned short pcLevel() const { return m_PCLevel; }
-
- /**
- * @return location of the player character
- **/
- const QString &pcLocation() const { return m_PCLocation; }
-
- /**
- * @return index of the save game
- **/
- unsigned long saveNumber() const { return m_SaveNumber; }
-
- /**
- * @return creation time of the save game
- **/
- SYSTEMTIME creationTime() const { return m_CreationTime; }
-
- /**
- * @return screenshot in the savegame
- **/
- const QImage &screenshot() const { return m_Screenshot; }
-
-protected:
-
- QString m_FileName;
- QString m_PCName;
- unsigned short m_PCLevel;
- QString m_PCLocation;
- unsigned long m_SaveNumber;
- SYSTEMTIME m_CreationTime;
- QImage m_Screenshot;
-
-private:
- MOBase::IPluginGame const * const m_Game;
-};
-
-
-#endif // SAVEGAME_H
diff --git a/src/savegamegamebryo.cpp b/src/savegamegamebryo.cpp deleted file mode 100644 index 68ed30af..00000000 --- a/src/savegamegamebryo.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "savegamegamebyro.h"
-
-#include "isavegame.h"
-#include "savegameinfo.h"
-#include "iplugingame.h"
-#include "gamebryosavegame.h"
-
-#include <limits>
-#include <set>
-
-using namespace MOBase;
-
-
-SaveGameGamebryo::SaveGameGamebryo(QObject *parent, const QString &fileName, IPluginGame const *game)
- : SaveGame(parent, fileName, game)
- , m_Plugins()
-{
- SaveGameInfo const *info = game->feature<SaveGameInfo>();
- if (info != nullptr) {
- ISaveGame const *save = info->getSaveGameInfo(fileName);
- m_Save = save;
-
- //Kludgery
- GamebryoSaveGame const *s = dynamic_cast<GamebryoSaveGame const *>(save);
- m_PCName = s->getPCName();
- m_PCLevel = s->getPCLevel();
- m_PCLocation = s->getPCLocation();
- m_SaveNumber = s->getSaveNumber();
-
- QDateTime modified = s->getCreationTime();
- memset(&m_CreationTime, 0, sizeof(SYSTEMTIME));
-
- m_CreationTime.wDay = static_cast<WORD>(modified.date().day());
- m_CreationTime.wDayOfWeek = static_cast<WORD>(modified.date().dayOfWeek());
- m_CreationTime.wMonth = static_cast<WORD>(modified.date().month());
- m_CreationTime.wYear =static_cast<WORD>( modified.date().year());
-
- m_CreationTime.wHour = static_cast<WORD>(modified.time().hour());
- m_CreationTime.wMinute = static_cast<WORD>(modified.time().minute());
- m_CreationTime.wSecond = static_cast<WORD>(modified.time().second());
- m_CreationTime.wMilliseconds = static_cast<WORD>(modified.time().msec());
-
- m_Screenshot = s->getScreenshot();
-
- m_Plugins = s->getPlugins();
- }
-}
diff --git a/src/savegamegamebyro.h b/src/savegamegamebyro.h deleted file mode 100644 index bce08018..00000000 --- a/src/savegamegamebyro.h +++ /dev/null @@ -1,77 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SAVEGAMEGAMEBRYO_H
-#define SAVEGAMEGAMEBRYO_H
-
-#include "savegame.h"
-
-#include <QMetaType>
-#include <QObject>
-#include <QString>
-
-namespace MOBase { class IPluginGame; class ISaveGame; }
-
-/**
- * @brief represents a single save game
- **/
-class SaveGameGamebryo : public SaveGame {
-
-Q_OBJECT
-
-public:
-
- /**
- * @brief construct a save game and immediately read out information from the file
- *
- * @param filename absolute path of the save game file
- **/
- SaveGameGamebryo(QObject *parent, const QString &filename, MOBase::IPluginGame const *game);
-
- /*
-
- SaveGameGamebryo(const SaveGameGamebryo &reference);
-
- SaveGameGamebryo &operator=(const SaveGameGamebryo &reference);
-
- ~SaveGameGamebryo();
- */
-
- /**
- * @return number of plugins that were enabled when the save game was created
- **/
- int numPlugins() const { return m_Plugins.size(); }
-
- /**
- * retrieve the name of one of the plugins that were enabled when the save game
- * was created. valid indices are in the range between [0, numPlugins()[
- * @param index plugin index
- * @return name of the plugin
- **/
- const QString &plugin(int index) const { return m_Plugins.at(index); }
-
-private:
-
- QStringList m_Plugins;
- //Note: This isn't owned by us so safe to copy
- MOBase::ISaveGame const *m_Save;
-
-};
-
-#endif // SAVEGAMEGAMEBRYO_H
diff --git a/src/savegameinfowidget.cpp b/src/savegameinfowidget.cpp deleted file mode 100644 index 63eefb93..00000000 --- a/src/savegameinfowidget.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "savegameinfowidget.h"
-#include "ui_savegameinfowidget.h"
-#include "utility.h"
-#include "savegame.h"
-#include <QGraphicsDropShadowEffect>
-
-
-SaveGameInfoWidget::SaveGameInfoWidget(QWidget *parent)
- : QWidget(parent)
- , ui(new Ui::SaveGameInfoWidget)
-{
- ui->setupUi(this);
- this->setWindowFlags(Qt::ToolTip | Qt::BypassGraphicsProxyWidget);
- setWindowOpacity(style()->styleHint(QStyle::SH_ToolTipLabel_Opacity, 0, this) / qreal(255.0));
- ui->gameFrame->setStyleSheet("background-color: transparent;");
-// installEventFilter(this);
-}
-
-SaveGameInfoWidget::~SaveGameInfoWidget()
-{
- delete ui;
-}
-
-
-void SaveGameInfoWidget::setSave(const SaveGame *saveGame)
-{
- ui->saveNumLabel->setText(QString("%1").arg(saveGame->saveNumber()));
- ui->characterLabel->setText(saveGame->pcName());
- ui->locationLabel->setText(saveGame->pcLocation());
- ui->levelLabel->setText(QString("%1").arg(saveGame->pcLevel()));
- ui->dateLabel->setText(MOBase::ToString(saveGame->creationTime()));
- ui->screenshotLabel->setPixmap(QPixmap::fromImage(saveGame->screenshot()));
- if (ui->gameFrame->layout() != nullptr) {
- QLayoutItem *item = nullptr;
- while ((item = ui->gameFrame->layout()->takeAt(0)) != nullptr) {
- delete item->widget();
- delete item;
- }
- ui->gameFrame->layout()->setSizeConstraint(QLayout::SetFixedSize);
- }
-}
-
-QFrame *SaveGameInfoWidget::getGameFrame()
-{
- return ui->gameFrame;
-}
diff --git a/src/savegameinfowidget.h b/src/savegameinfowidget.h deleted file mode 100644 index dfb0f8b1..00000000 --- a/src/savegameinfowidget.h +++ /dev/null @@ -1,61 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SAVEGAMEINFOWIDGET_H
-#define SAVEGAMEINFOWIDGET_H
-
-#include <QWidget>
-#include <QFrame>
-
-namespace Ui {
-class SaveGameInfoWidget;
-}
-
-class SaveGame;
-
-class SaveGameInfoWidget : public QWidget
-{
- Q_OBJECT
-
-public:
-
- explicit SaveGameInfoWidget(QWidget *parent = 0);
- ~SaveGameInfoWidget();
-
- virtual void setSave(const SaveGame *saveGame);
-
-signals:
-
- void closeSaveInfo();
-
-protected:
-
-// virtual bool eventFilter(QObject *object, QEvent *event);
-
- QFrame *getGameFrame();
-
-private:
-
-private:
-
- Ui::SaveGameInfoWidget *ui;
-
-};
-
-#endif // SAVEGAMEINFOWIDGET_H
diff --git a/src/savegameinfowidget.ui b/src/savegameinfowidget.ui deleted file mode 100644 index e2e9588c..00000000 --- a/src/savegameinfowidget.ui +++ /dev/null @@ -1,209 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?>
-<ui version="4.0">
- <class>SaveGameInfoWidget</class>
- <widget class="QWidget" name="SaveGameInfoWidget">
- <property name="geometry">
- <rect>
- <x>0</x>
- <y>0</y>
- <width>400</width>
- <height>300</height>
- </rect>
- </property>
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="windowTitle">
- <string/>
- </property>
- <property name="toolTip">
- <string notr="true"/>
- </property>
- <layout class="QVBoxLayout" name="verticalLayout">
- <item>
- <layout class="QFormLayout" name="formLayout">
- <property name="fieldGrowthPolicy">
- <enum>QFormLayout::AllNonFixedFieldsGrow</enum>
- </property>
- <item row="0" column="0">
- <widget class="QLabel" name="label">
- <property name="font">
- <font>
- <italic>true</italic>
- </font>
- </property>
- <property name="text">
- <string>Save #</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0">
- <widget class="QLabel" name="label_2">
- <property name="font">
- <font>
- <italic>true</italic>
- </font>
- </property>
- <property name="text">
- <string>Character</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0">
- <widget class="QLabel" name="label_4">
- <property name="font">
- <font>
- <italic>true</italic>
- </font>
- </property>
- <property name="text">
- <string>Level</string>
- </property>
- </widget>
- </item>
- <item row="3" column="0">
- <widget class="QLabel" name="label_3">
- <property name="font">
- <font>
- <italic>true</italic>
- </font>
- </property>
- <property name="text">
- <string>Location</string>
- </property>
- </widget>
- </item>
- <item row="4" column="0">
- <widget class="QLabel" name="label_5">
- <property name="font">
- <font>
- <italic>true</italic>
- </font>
- </property>
- <property name="text">
- <string>Date</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1">
- <widget class="QLabel" name="saveNumLabel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string notr="true"/>
- </property>
- </widget>
- </item>
- <item row="1" column="1">
- <widget class="QLabel" name="characterLabel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string notr="true"/>
- </property>
- </widget>
- </item>
- <item row="2" column="1">
- <widget class="QLabel" name="levelLabel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- <item row="3" column="1">
- <widget class="QLabel" name="locationLabel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string notr="true"/>
- </property>
- </widget>
- </item>
- <item row="4" column="1">
- <widget class="QLabel" name="dateLabel">
- <property name="font">
- <font>
- <weight>75</weight>
- <bold>true</bold>
- </font>
- </property>
- <property name="text">
- <string/>
- </property>
- </widget>
- </item>
- </layout>
- </item>
- <item>
- <widget class="QFrame" name="gameFrame">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Expanding" vsizetype="Minimum">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="minimumSize">
- <size>
- <width>0</width>
- <height>0</height>
- </size>
- </property>
- <property name="frameShape">
- <enum>QFrame::StyledPanel</enum>
- </property>
- <property name="frameShadow">
- <enum>QFrame::Raised</enum>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QLabel" name="screenshotLabel">
- <property name="sizePolicy">
- <sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
- <horstretch>0</horstretch>
- <verstretch>0</verstretch>
- </sizepolicy>
- </property>
- <property name="maximumSize">
- <size>
- <width>16777215</width>
- <height>16777215</height>
- </size>
- </property>
- <property name="autoFillBackground">
- <bool>false</bool>
- </property>
- <property name="text">
- <string notr="true"/>
- </property>
- <property name="alignment">
- <set>Qt::AlignCenter</set>
- </property>
- </widget>
- </item>
- </layout>
- </widget>
- <resources/>
- <connections/>
-</ui>
diff --git a/src/savegameinfowidgetgamebryo.cpp b/src/savegameinfowidgetgamebryo.cpp deleted file mode 100644 index c97e5810..00000000 --- a/src/savegameinfowidgetgamebryo.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#include "savegamegamebyro.h"
-#include "savegameinfowidgetgamebryo.h"
-#include <QLabel>
-#include <QVBoxLayout>
-
-
-SaveGameInfoWidgetGamebryo::SaveGameInfoWidgetGamebryo(const SaveGame *saveGame, PluginList *pluginList, QWidget *parent)
- : SaveGameInfoWidget(parent), m_PluginList(pluginList)
-{
- QVBoxLayout *gameLayout = new QVBoxLayout();
- gameLayout->setMargin(0);
- gameLayout->setSpacing(2);
- getGameFrame()->setLayout(gameLayout);
- setSave(saveGame);
-}
-
-
-void SaveGameInfoWidgetGamebryo::setSave(const SaveGame *saveGame)
-{
- SaveGameInfoWidget::setSave(saveGame);
- const SaveGameGamebryo *gamebryoSave = qobject_cast<const SaveGameGamebryo*>(saveGame);
- QLayout *layout = getGameFrame()->layout();
- QLabel *header = new QLabel(tr("Missing ESPs"));
- QFont headerFont = header->font();
- QFont contentFont = headerFont;
- headerFont.setItalic(true);
- contentFont.setBold(true);
- contentFont.setPointSize(7);
- header->setFont(headerFont);
- layout->addWidget(header);
- int count = 0;
- for (int i = 0; i < gamebryoSave->numPlugins(); ++i) {
- const QString &pluginName = gamebryoSave->plugin(i);
- if (m_PluginList->isEnabled(pluginName)) {
- continue;
- } else {
- ++count;
- }
-
- if (count > 10) {
- break;
- }
-
- QLabel *pluginLabel = new QLabel(gamebryoSave->plugin(i));
- pluginLabel->setIndent(10);
- pluginLabel->setFont(contentFont);
- layout->addWidget(pluginLabel);
- }
- if (count > 10) {
- QLabel *dotDotLabel = new QLabel("...");
- dotDotLabel->setIndent(10);
- dotDotLabel->setFont(contentFont);
- layout->addWidget(dotDotLabel);
- }
- if (count == 0) {
- QLabel *dotDotLabel = new QLabel(tr("None"));
- dotDotLabel->setIndent(10);
- dotDotLabel->setFont(contentFont);
- layout->addWidget(dotDotLabel);
- }
-}
diff --git a/src/savegameinfowidgetgamebryo.h b/src/savegameinfowidgetgamebryo.h deleted file mode 100644 index 149a8885..00000000 --- a/src/savegameinfowidgetgamebryo.h +++ /dev/null @@ -1,44 +0,0 @@ -/*
-Copyright (C) 2012 Sebastian Herbord. All rights reserved.
-
-This file is part of Mod Organizer.
-
-Mod Organizer is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-Mod Organizer is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef SAVEGAMEINFOWIDGETGAMEBRYO_H
-#define SAVEGAMEINFOWIDGETGAMEBRYO_H
-
-
-#include "savegameinfowidget.h"
-#include "pluginlist.h"
-
-
-class SaveGame;
-
-class SaveGameInfoWidgetGamebryo : public SaveGameInfoWidget
-{
-public:
-
- explicit SaveGameInfoWidgetGamebryo(const SaveGame *saveGame, PluginList *pluginList, QWidget *parent = 0);
-
- virtual void setSave(const SaveGame *saveGame);
-
-private:
-
- PluginList *m_PluginList;
-
-};
-
-#endif // SAVEGAMEINFOWIDGETGAMEBRYO_H
diff --git a/src/transfersavesdialog.cpp b/src/transfersavesdialog.cpp index 48fc4548..cb3d0d61 100644 --- a/src/transfersavesdialog.cpp +++ b/src/transfersavesdialog.cpp @@ -21,19 +21,82 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "ui_transfersavesdialog.h"
#include "iplugingame.h"
-#include "savegamegamebyro.h"
-#include "utility.h"
+#include "isavegame.h"
+#include "savegameinfo.h"
+#include <QtDebug>
+#include <QDateTime>
#include <QDir>
+#include <QFile>
+#include <QFileInfo>
+#include <QFlags>
+#include <QLabel>
+#include <QListWidget>
+#include <QListWidgetItem>
#include <QMessageBox>
-
-#include <Shlwapi.h>
-#include <shlobj.h>
-
+#include <QPushButton>
+#include <QStringList>
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 getSaveGroupIdentifier() const override
+ {
+ return m_File;
+ }
+
+ virtual QStringList allFiles() 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);
+ }
+
+ virtual MissingAssets getMissingAssets(QString const &) const override
+ {
+ return {};
+ }
+
+ MOBase::ISaveGameInfoWidget *getSaveGameWidget(QWidget *) const override
+ {
+ return nullptr;
+ }
+};
+
+} //end anonymous namespace
TransferSavesDialog::TransferSavesDialog(const Profile &profile, IPluginGame const *gamePlugin, QWidget *parent)
: TutorableDialog("TransferSaves", parent)
@@ -42,6 +105,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 +117,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<QString> characters;
- for (std::vector<SaveGame*>::const_iterator iter = m_GlobalSaves.begin();
- iter != m_GlobalSaves.end(); ++iter) {
- characters.insert((*iter)->pcName());
- }
- ui->globalCharacterList->clear();
- for (std::set<QString>::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<QString> characters;
- for (std::vector<SaveGame*>::const_iterator iter = m_LocalSaves.begin();
- iter != m_LocalSaves.end(); ++iter) {
- characters.insert((*iter)->pcName());
- }
- ui->localCharacterList->clear();
- for (std::set<QString>::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 +159,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<SaveGame*>::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<SaveGame*>::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<SaveGame*>::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<SaveGame*>::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 +234,12 @@ void TransferSavesDialog::on_doneButton_clicked() void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QString ¤tText)
{
ui->globalSavesList->clear();
- for (std::vector<SaveGame*>::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 +247,90 @@ void TransferSavesDialog::on_globalCharacterList_currentTextChanged(const QStrin void TransferSavesDialog::on_localCharacterList_currentTextChanged(const QString ¤tText)
{
ui->localSavesList->clear();
- for (std::vector<SaveGame*>::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<SaveGameInfo>();
+ 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->getSaveGroupIdentifier()].push_back(
+ std::unique_ptr<MOBase::ISaveGame const>(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;
+
+ QDir destination(dest);
+ for (SaveListItem const &save : saves) {
+ 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)) {
+ 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;
}
diff --git a/src/transfersavesdialog.h b/src/transfersavesdialog.h index e2c556b4..d3f079e3 100644 --- a/src/transfersavesdialog.h +++ b/src/transfersavesdialog.h @@ -23,10 +23,19 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>. #include "tutorabledialog.h"
#include "profile.h"
+class QListWidget;
+#include <QObject>
+class QPushButton;
+#include <QString>
+class QWidget;
+
+#include <memory>
+#include <map>
+#include <vector>
+
namespace Ui { class TransferSavesDialog; }
namespace MOBase { class IPluginGame; }
-
-class SaveGame;
+namespace MOBase { class ISaveGame; }
class TransferSavesDialog : public MOBase::TutorableDialog
{
@@ -76,8 +85,25 @@ private: MOBase::IPluginGame const *m_GamePlugin;
- std::vector<SaveGame*> m_GlobalSaves;
- std::vector<SaveGame*> m_LocalSaves;
+ typedef std::unique_ptr<MOBase::ISaveGame const> SaveListItem;
+ typedef std::vector<SaveListItem> SaveList;
+ typedef std::map<QString, SaveList> SaveCollection;
+ SaveCollection m_GlobalSaves;
+ SaveCollection m_LocalSaves;
+
+ void refreshSaves(SaveCollection &saveCollection, const QString &savedir);
+ void refreshCharacters(SaveCollection const &saveCollection,
+ QListWidget *charList,
+ QPushButton *copy,
+ QPushButton *move);
+
+ bool transferCharacters(QString const &character,
+ char const *message,
+ SaveList &saves,
+ QString const &dest,
+ bool (method)(QString const &, QString const &),
+ char const *errmsg
+ );
};
|
