summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt19
-rw-r--r--src/aboutdialog.cpp8
-rw-r--r--src/aboutdialog.h7
-rw-r--r--src/activatemodsdialog.cpp22
-rw-r--r--src/activatemodsdialog.h10
-rw-r--r--src/downloadmanager.cpp4
-rw-r--r--src/iuserinterface.h1
-rw-r--r--src/mainwindow.cpp310
-rw-r--r--src/mainwindow.h112
-rw-r--r--src/modinfo.cpp6
-rw-r--r--src/modinfo.h1
-rw-r--r--src/nexusinterface.cpp12
-rw-r--r--src/organizer.pro9
-rw-r--r--src/organizercore.cpp43
-rw-r--r--src/organizercore.h29
-rw-r--r--src/organizerproxy.cpp13
-rw-r--r--src/organizerproxy.h6
-rw-r--r--src/pluginlist.cpp6
-rw-r--r--src/profile.cpp38
-rw-r--r--src/profile.h19
-rw-r--r--src/profilesdialog.cpp24
-rw-r--r--src/profilesdialog.h15
-rw-r--r--src/savegame.cpp69
-rw-r--r--src/savegame.h121
-rw-r--r--src/savegamegamebryo.cpp66
-rw-r--r--src/savegamegamebyro.h77
-rw-r--r--src/savegameinfowidget.cpp65
-rw-r--r--src/savegameinfowidget.h61
-rw-r--r--src/savegameinfowidget.ui209
-rw-r--r--src/savegameinfowidgetgamebryo.cpp80
-rw-r--r--src/savegameinfowidgetgamebryo.h44
-rw-r--r--src/selfupdater.cpp40
-rw-r--r--src/selfupdater.h17
-rw-r--r--src/settings.cpp2
-rw-r--r--src/shared/fallout3info.cpp88
-rw-r--r--src/shared/fallout3info.h59
-rw-r--r--src/shared/falloutnvinfo.cpp88
-rw-r--r--src/shared/falloutnvinfo.h59
-rw-r--r--src/shared/gameinfo.cpp164
-rw-r--r--src/shared/gameinfo.h95
-rw-r--r--src/shared/oblivioninfo.cpp88
-rw-r--r--src/shared/oblivioninfo.h58
-rw-r--r--src/shared/shared.pro10
-rw-r--r--src/shared/skyriminfo.cpp104
-rw-r--r--src/shared/skyriminfo.h62
-rw-r--r--src/transfersavesdialog.cpp415
-rw-r--r--src/transfersavesdialog.h34
47 files changed, 676 insertions, 2213 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3c786868..94b75031 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
@@ -92,12 +88,7 @@ SET(organizer_SRCS
shared/windows_error.cpp
shared/error_report.cpp
shared/directoryentry.cpp
- shared/gameinfo.cpp
- shared/oblivioninfo.cpp
- shared/fallout3info.cpp
- shared/falloutnvinfo.cpp
shared/util.cpp
- shared/skyriminfo.cpp
shared/appconfig.cpp
shared/leaktrace.cpp
shared/stackdata.cpp
@@ -112,10 +103,6 @@ SET(organizer_HDRS
settings.h
selfupdater.h
selectiondialog.h
- savegameinfowidgetgamebryo.h
- savegameinfowidget.h
- savegamegamebyro.h
- savegame.h
queryoverwritedialog.h
profilesdialog.h
profile.h
@@ -186,12 +173,7 @@ SET(organizer_HDRS
shared/windows_error.h
shared/error_report.h
shared/directoryentry.h
- shared/gameinfo.h
- shared/oblivioninfo.h
- shared/fallout3info.h
- shared/falloutnvinfo.h
shared/util.h
- shared/skyriminfo.h
shared/appconfig.h
shared/appconfig.inc
shared/leaktrace.h
@@ -204,7 +186,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/downloadmanager.cpp b/src/downloadmanager.cpp
index c551e590..e327e55a 100644
--- a/src/downloadmanager.cpp
+++ b/src/downloadmanager.cpp
@@ -450,7 +450,7 @@ void DownloadManager::addNXMDownload(const QString &url)
{
NXMUrl nxmInfo(url);
- QString managedGame = m_ManagedGame->getGameShortName();
+ QString managedGame = m_ManagedGame->gameShortName();
qDebug("add nxm download: %s", qPrintable(url));
if (nxmInfo.game().compare(managedGame, Qt::CaseInsensitive) != 0) {
qDebug("download requested for wrong game (game: %s, url: %s)", qPrintable(managedGame), qPrintable(nxmInfo.game()));
@@ -1247,7 +1247,7 @@ int DownloadManager::startDownloadURLs(const QStringList &urls)
int DownloadManager::startDownloadNexusFile(int modID, int fileID)
{
int newID = m_ActiveDownloads.size();
- addNXMDownload(QString("nxm://%1/mods/%2/files/%3").arg(m_ManagedGame->getGameShortName()).arg(modID).arg(fileID));
+ addNXMDownload(QString("nxm://%1/mods/%2/files/%3").arg(m_ManagedGame->gameShortName()).arg(modID).arg(fileID));
return newID;
}
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..096ce94b 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,14 +1278,14 @@ 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(
L"General", L"SLocalSavePath", L"Saves",
path, MAX_PATH,
ToWString(m_OrganizerCore.currentProfile()->absolutePath() + "/" +
- m_OrganizerCore.managedGame()->getIniFiles()[0]).c_str());
+ m_OrganizerCore.managedGame()->iniFiles()[0]).c_str());
savesDir.setPath(m_OrganizerCore.managedGame()->documentsDirectory().absoluteFilePath(QString::fromWCharArray(path)));
}
@@ -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());
@@ -3846,7 +3812,7 @@ void MainWindow::on_actionEndorseMO_triggered()
NexusInterface::instance()->getGameURL()),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
NexusInterface::instance()->requestToggleEndorsement(
- m_OrganizerCore.managedGame()->getNexusModOrganizerID(), true, this, QVariant(), QString());
+ m_OrganizerCore.managedGame()->nexusModOrganizerID(), true, this, QVariant(), QString());
}
}
@@ -3910,7 +3876,7 @@ void MainWindow::nxmUpdatesAvailable(const std::vector<int> &modIDs, QVariant us
QVariantList resultList = resultData.toList();
for (auto iter = resultList.begin(); iter != resultList.end(); ++iter) {
QVariantMap result = iter->toMap();
- if (result["id"].toInt() == m_OrganizerCore.managedGame()->getNexusModOrganizerID()) {
+ if (result["id"].toInt() == m_OrganizerCore.managedGame()->nexusModOrganizerID()) {
if (!result["voted_by_user"].toBool()) {
ui->actionEndorseMO->setVisible(true);
}
@@ -4426,7 +4392,7 @@ void MainWindow::on_bossButton_clicked()
parameters << "--unattended"
<< "--stdout"
<< "--noreport"
- << "--game" << m_OrganizerCore.managedGame()->getGameShortName()
+ << "--game" << m_OrganizerCore.managedGame()->gameShortName()
<< "--gamePath" << QString("\"%1\"").arg(m_OrganizerCore.managedGame()->gameDirectory().absolutePath())
<< "--out" << outPath;
@@ -4560,12 +4526,12 @@ void MainWindow::on_bossButton_clicked()
// if the game specifies load order by file time, our own load order file needs to be removed because it's outdated.
// refreshESPList will then use the file time as the load order.
- if (m_OrganizerCore.managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
+ if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
qDebug("removing loadorder.txt");
QFile::remove(m_OrganizerCore.currentProfile()->getLoadOrderFileName());
}
m_OrganizerCore.refreshESPList();
- if (m_OrganizerCore.managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
+ if (m_OrganizerCore.managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
// the load order should have been retrieved from file time, now save it to our own format
m_OrganizerCore.savePluginList();
}
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.cpp b/src/modinfo.cpp
index 8bc767c5..1081daf8 100644
--- a/src/modinfo.cpp
+++ b/src/modinfo.cpp
@@ -220,8 +220,8 @@ void ModInfo::updateFromDisc(const QString &modDirectory,
}
{ // list plugins in the data directory and make a foreign-managed mod out of each
- QStringList dlcPlugins = game->getDLCPlugins();
- QStringList mainPlugins = game->getPrimaryPlugins();
+ QStringList dlcPlugins = game->DLCPlugins();
+ QStringList mainPlugins = game->primaryPlugins();
QDir dataDir(game->dataDirectory());
for (const QString &file : dataDir.entryList({ "*.esp", "*.esm" })) {
if (std::find_if(mainPlugins.begin(), mainPlugins.end(),
@@ -291,7 +291,7 @@ int ModInfo::checkAllForUpdate(QObject *receiver)
//I ought to store this, it's used elsewhere
IPluginGame const *game = qApp->property("managed_game").value<IPluginGame const *>();
- modIDs.push_back(game->getNexusModOrganizerID());
+ modIDs.push_back(game->nexusModOrganizerID());
for (const ModInfo::Ptr &mod : s_Collection) {
if (mod->canBeUpdated()) {
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/nexusinterface.cpp b/src/nexusinterface.cpp
index 26a74ef6..d0eb58a6 100644
--- a/src/nexusinterface.cpp
+++ b/src/nexusinterface.cpp
@@ -250,12 +250,12 @@ bool NexusInterface::isURLGameRelated(const QUrl &url) const
QString NexusInterface::getGameURL() const
{
- return "http://www.nexusmods.com/" + m_Game->getGameShortName().toLower();
+ return "http://www.nexusmods.com/" + m_Game->gameShortName().toLower();
}
QString NexusInterface::getOldModsURL() const
{
- return "http://" + m_Game->getGameShortName().toLower() + ".nexusmods.com/mods";
+ return "http://" + m_Game->gameShortName().toLower() + ".nexusmods.com/mods";
}
@@ -593,7 +593,7 @@ void NexusInterface::managedGameChanged(IPluginGame const *game)
namespace {
QString get_management_url(MOBase::IPluginGame const *game)
{
- return "http://nmm.nexusmods.com/" + game->getGameShortName().toLower();
+ return "http://nmm.nexusmods.com/" + game->gameShortName().toLower();
}
}
@@ -613,7 +613,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_ID(s_NextID.fetchAndAddAcquire(1))
, m_URL(get_management_url(game))
, m_SubModule(subModule)
- , m_NexusGameID(game->getNexusGameID())
+ , m_NexusGameID(game->nexusGameID())
, m_Endorse(false)
{}
@@ -634,7 +634,7 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(std::vector<int> modIDList
, m_ID(s_NextID.fetchAndAddAcquire(1))
, m_URL(get_management_url(game))
, m_SubModule(subModule)
- , m_NexusGameID(game->getNexusGameID())
+ , m_NexusGameID(game->nexusGameID())
, m_Endorse(false)
{}
@@ -655,6 +655,6 @@ NexusInterface::NXMRequestInfo::NXMRequestInfo(int modID
, m_ID(s_NextID.fetchAndAddAcquire(1))
, m_URL(get_management_url(game))
, m_SubModule(subModule)
- , m_NexusGameID(game->getNexusGameID())
+ , m_NexusGameID(game->nexusGameID())
, m_Endorse(false)
{}
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..cee367b0 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;
@@ -401,8 +414,8 @@ void OrganizerCore::connectPlugins(PluginContainer *container)
}
//Do this the hard way
for (const IPluginGame * const game : container->plugins<IPluginGame>()) {
- QString n = game->getGameShortName();
- if (game->getGameShortName() == "Skyrim") {
+ QString n = game->gameShortName();
+ if (game->gameShortName() == "Skyrim") {
m_Updater.setNexusDownload(game);
break;
}
@@ -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 &currentDirectory, bool closeAfterStart, const QString &steamAppID)
{
LockedDialog *dialog = new LockedDialog(qApp->activeWindow());
@@ -932,12 +955,12 @@ void OrganizerCore::spawnBinary(const QFileInfo &binary, const QString &argument
refreshDirectoryStructure();
// need to remove our stored load order because it may be outdated if a foreign tool changed the
// file time. After removing that file, refreshESPList will use the file time as the order
- if (managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
+ if (managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
qDebug("removing loadorder.txt");
QFile::remove(m_CurrentProfile->getLoadOrderFileName());
}
refreshESPList();
- if (managedGame()->getLoadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
+ if (managedGame()->loadOrderMechanism() == IPluginGame::LoadOrderMechanism::FileTime) {
// the load order should have been retrieved from file time, now save it to our own format
savePluginList();
}
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..b6dbd242 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>
@@ -166,7 +167,17 @@ MOBase::IModList *OrganizerProxy::modList() const
return m_Proxied->modList();
}
+MOBase::IProfile *OrganizerProxy::profile() const
+{
+ return m_Proxied->currentProfile();
+}
+
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..7ce8982e 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
{
@@ -37,6 +38,7 @@ public:
virtual MOBase::IDownloadManager *downloadManager() const;
virtual MOBase::IPluginList *pluginList() const;
virtual MOBase::IModList *modList() const;
+ virtual MOBase::IProfile *profile() const override;
virtual HANDLE startApplication(const QString &executable, const QStringList &args = QStringList(), const QString &cwd = "", const QString &profile = "");
virtual bool waitForApplication(HANDLE handle, LPDWORD exitCode = nullptr) const;
virtual void refreshModList(bool saveChanges);
@@ -47,6 +49,8 @@ public:
virtual MOBase::IPluginGame const *managedGame() const;
+ virtual QStringList modsSortedByProfilePriority() const;
+
private:
OrganizerCore *m_Proxied;
diff --git a/src/pluginlist.cpp b/src/pluginlist.cpp
index 7a609374..bf5a09dc 100644
--- a/src/pluginlist.cpp
+++ b/src/pluginlist.cpp
@@ -127,7 +127,7 @@ void PluginList::refresh(const QString &profileName
m_ESPsByPriority.clear();
m_ESPs.clear();
- QStringList primaryPlugins = m_GamePlugin->getPrimaryPlugins();
+ QStringList primaryPlugins = m_GamePlugin->primaryPlugins();
m_CurrentProfile = profileName;
@@ -312,7 +312,7 @@ bool PluginList::readLoadOrder(const QString &fileName)
int priority = 0;
- QStringList primaryPlugins = m_GamePlugin->getPrimaryPlugins();
+ QStringList primaryPlugins = m_GamePlugin->primaryPlugins();
for (const QString &plugin : primaryPlugins) {
if (availableESPs.find(plugin) != availableESPs.end()) {
m_ESPLoadOrder[plugin] = priority++;
@@ -503,7 +503,7 @@ void PluginList::saveTo(const QString &pluginFileName
bool PluginList::saveLoadOrder(DirectoryEntry &directoryStructure)
{
- if (m_GamePlugin->getLoadOrderMechanism() != IPluginGame::LoadOrderMechanism::FileTime) {
+ if (m_GamePlugin->loadOrderMechanism() != IPluginGame::LoadOrderMechanism::FileTime) {
// nothing to do
return true;
}
diff --git a/src/profile.cpp b/src/profile.cpp
index 77f6ebd1..21fb0b7a 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;
@@ -674,7 +684,7 @@ QString Profile::getDeleterFileName() const
QString Profile::getIniFileName() const
{
- return m_Directory.absoluteFilePath(m_GamePlugin->getIniFiles()[0]);
+ return m_Directory.absoluteFilePath(m_GamePlugin->iniFiles()[0]);
}
QString Profile::getProfileTweaks() const
@@ -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/selfupdater.cpp b/src/selfupdater.cpp
index 11478fbc..bc8908bc 100644
--- a/src/selfupdater.cpp
+++ b/src/selfupdater.cpp
@@ -19,6 +19,8 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include "selfupdater.h"
+#include "archive.h"
+#include "callback.h"
#include "utility.h"
#include "installationmanager.h"
#include "iplugingame.h"
@@ -30,15 +32,36 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#include <report.h>
#include <util.h>
+#include <QApplication>
+#include <QCoreApplication>
+#include <QDir>
+#include <QFileInfo>
+#include <QLibrary>
#include <QMessageBox>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
-#include <QDir>
-#include <QLibrary>
+#include <QNetworkReply>
#include <QProcess>
-#include <QApplication>
+#include <QProgressDialog>
+#include <QRegExp>
+#include <QStringList>
+#include <QTimer>
+#include <QUrl>
+#include <QVariantList>
+#include <QVariantMap>
+
+#include <Qt>
+#include <QtDebug>
+#include <QtAlgorithms>
+
#include <boost/bind.hpp>
+#include <Windows.h> //for VS_FIXEDFILEINFO, GetLastError
+
+#include <exception>
+#include <map>
+#include <stddef.h> //for size_t
+#include <stdexcept>
using namespace MOBase;
using namespace MOShared;
@@ -77,8 +100,6 @@ SelfUpdater::SelfUpdater(NexusInterface *nexusInterface)
throw MyException(InstallationManager::getErrorString(m_ArchiveHandler->getLastError()));
}
- connect(m_Progress, SIGNAL(canceled()), this, SLOT(downloadCancel()));
-
VS_FIXEDFILEINFO version = GetFileVersion(ToWString(QApplication::applicationFilePath()));
m_MOVersion = VersionInfo(version.dwFileVersionMS >> 16,
@@ -105,7 +126,7 @@ void SelfUpdater::testForUpdate()
}
if (m_UpdateRequestID == -1 && m_NexusDownload != nullptr) {
m_UpdateRequestID = m_Interface->requestDescription(
- m_NexusDownload->getNexusModOrganizerID(), this, QVariant(),
+ m_NexusDownload->nexusModOrganizerID(), this, QVariant(),
QString(), m_NexusDownload);
}
}
@@ -123,7 +144,7 @@ void SelfUpdater::startUpdate()
if (QMessageBox::question(m_Parent, tr("Update"),
tr("An update is available (newest version: %1), do you want to install it?").arg(m_NewestVersion),
QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes) {
- m_UpdateRequestID = m_Interface->requestFiles(m_NexusDownload->getNexusModOrganizerID(),
+ m_UpdateRequestID = m_Interface->requestFiles(m_NexusDownload->nexusModOrganizerID(),
this, m_NewestVersion, "",
m_NexusDownload);
}
@@ -135,6 +156,7 @@ void SelfUpdater::showProgress()
{
if (m_Progress == nullptr) {
m_Progress = new QProgressDialog(m_Parent, Qt::Dialog);
+ connect(m_Progress, SIGNAL(canceled()), this, SLOT(downloadCancel()));
}
m_Progress->setModal(true);
m_Progress->show();
@@ -416,7 +438,7 @@ void SelfUpdater::nxmFilesAvailable(int, QVariant userData, QVariant resultData,
if (updateFileID != -1) {
qDebug("update available: %d", updateFileID);
- m_UpdateRequestID = m_Interface->requestDownloadURL(m_NexusDownload->getNexusModOrganizerID(),
+ m_UpdateRequestID = m_Interface->requestDownloadURL(m_NexusDownload->nexusModOrganizerID(),
updateFileID, this, updateFileName, "",
m_NexusDownload);
} else if (mainFileID != -1) {
@@ -425,7 +447,7 @@ void SelfUpdater::nxmFilesAvailable(int, QVariant userData, QVariant resultData,
tr("No incremental update available for this version, "
"the complete package needs to be downloaded (%1 kB)").arg(mainFileSize),
QMessageBox::Ok | QMessageBox::Cancel) == QMessageBox::Ok) {
- m_UpdateRequestID = m_Interface->requestDownloadURL(m_NexusDownload->getNexusModOrganizerID(),
+ m_UpdateRequestID = m_Interface->requestDownloadURL(m_NexusDownload->nexusModOrganizerID(),
mainFileID, this, mainFileName, "",
m_NexusDownload);
}
diff --git a/src/selfupdater.h b/src/selfupdater.h
index 446778fb..37021b42 100644
--- a/src/selfupdater.h
+++ b/src/selfupdater.h
@@ -21,17 +21,20 @@ along with Mod Organizer. If not, see <http://www.gnu.org/licenses/>.
#define SELFUPDATER_H
-#include <archive.h>
#include <versioninfo.h>
-#include <QObject>
-#include <QNetworkReply>
-#include <QFile>
-#include <QProgressDialog>
-
+class Archive;
+class NexusInterface;
namespace MOBase { class IPluginGame; }
-class NexusInterface;
+#include <QFile>
+#include <QObject>
+#include <QString>
+#include <QVariant>
+#include <QtGlobal> //for qint64
+
+class QNetworkReply;
+class QProgressDialog;
/**
diff --git a/src/settings.cpp b/src/settings.cpp
index d493be1d..7b812759 100644
--- a/src/settings.cpp
+++ b/src/settings.cpp
@@ -107,7 +107,7 @@ void Settings::registerAsNXMHandler(bool force)
std::wstring nxmPath = ToWString(QCoreApplication::applicationDirPath() + "/nxmhandler.exe");
std::wstring executable = ToWString(QCoreApplication::applicationFilePath());
std::wstring mode = force ? L"forcereg" : L"reg";
- std::wstring parameters = mode + L" " + m_GamePlugin->getGameShortName().toStdWString() + L" \"" + executable + L"\"";
+ std::wstring parameters = mode + L" " + m_GamePlugin->gameShortName().toStdWString() + L" \"" + executable + L"\"";
HINSTANCE res = ::ShellExecuteW(nullptr, L"open", nxmPath.c_str(), parameters.c_str(), nullptr, SW_SHOWNORMAL);
if ((int)res <= 32) {
QMessageBox::critical(nullptr, tr("Failed"),
diff --git a/src/shared/fallout3info.cpp b/src/shared/fallout3info.cpp
deleted file mode 100644
index 797d68ec..00000000
--- a/src/shared/fallout3info.cpp
+++ /dev/null
@@ -1,88 +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 "fallout3info.h"
-#include "util.h"
-#include <tchar.h>
-#include <ShlObj.h>
-#include <sstream>
-#include "windows_error.h"
-#include "error_report.h"
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include <boost/assign.hpp>
-
-namespace MOShared {
-
-Fallout3Info::Fallout3Info(const std::wstring &gameDirectory)
- : GameInfo(gameDirectory)
-{
- identifyMyGamesDirectory(L"fallout3");
-}
-
-bool Fallout3Info::identifyGame(const std::wstring &searchPath)
-{
- return FileExists(searchPath, L"Fallout3.exe") &&
- FileExists(searchPath, L"FalloutLauncher.exe");
-}
-
-std::wstring Fallout3Info::getRegPathStatic()
-{
- HKEY key;
- LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\Fallout3",
- 0, KEY_QUERY_VALUE, &key);
-
- if (errorcode != ERROR_SUCCESS) {
- return std::wstring();
- }
-
- WCHAR temp[MAX_PATH];
- DWORD bufferSize = MAX_PATH;
-
- if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
- return std::wstring(temp);
- } else {
- return std::wstring();
- }
-}
-
-
-std::vector<std::wstring> Fallout3Info::getIniFileNames() const
-{
- return boost::assign::list_of(L"fallout.ini")(L"falloutprefs.ini");
-}
-
-std::wstring Fallout3Info::getReferenceDataFile() const
-{
- return L"Fallout - Meshes.bsa";
-}
-
-bool Fallout3Info::rerouteToProfile(const wchar_t *fileName, const wchar_t*) const
-{
- static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", nullptr };
-
- for (int i = 0; profileFiles[i] != nullptr; ++i) {
- if (_wcsicmp(fileName, profileFiles[i]) == 0) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace MOShared
diff --git a/src/shared/fallout3info.h b/src/shared/fallout3info.h
deleted file mode 100644
index 5cf98e3b..00000000
--- a/src/shared/fallout3info.h
+++ /dev/null
@@ -1,59 +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 FALLOUT3INFO_H
-#define FALLOUT3INFO_H
-
-#include "gameinfo.h"
-
-namespace MOShared {
-
-
-class Fallout3Info : public GameInfo
-{
-
- friend class GameInfo;
-
-public:
-
- virtual ~Fallout3Info() {}
-
- static std::wstring getRegPathStatic();
- virtual std::wstring getRegPath() const { return getRegPathStatic(); }
-
- // file name of this games ini (no path)
- virtual std::vector<std::wstring> getIniFileNames() const;
-
- virtual std::wstring getReferenceDataFile() const;
-
- virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
-
- virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
-
-private:
-
- Fallout3Info(const std::wstring &gameDirectory);
-
- static bool identifyGame(const std::wstring &searchPath);
-
-};
-
-} // namespace MOShared
-
-#endif // FALLOUT3INFO_H
diff --git a/src/shared/falloutnvinfo.cpp b/src/shared/falloutnvinfo.cpp
deleted file mode 100644
index 6347224d..00000000
--- a/src/shared/falloutnvinfo.cpp
+++ /dev/null
@@ -1,88 +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 "falloutnvinfo.h"
-#include "util.h"
-#include <tchar.h>
-#include <ShlObj.h>
-#include <sstream>
-#include "windows_error.h"
-#include "error_report.h"
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include <boost/assign.hpp>
-
-namespace MOShared {
-
-
-FalloutNVInfo::FalloutNVInfo(const std::wstring &gameDirectory)
- : GameInfo(gameDirectory)
-{
- identifyMyGamesDirectory(L"falloutnv");
-}
-
-bool FalloutNVInfo::identifyGame(const std::wstring &searchPath)
-{
- return FileExists(searchPath, L"FalloutNV.exe") &&
- FileExists(searchPath, L"FalloutNVLauncher.exe");
-}
-
-std::wstring FalloutNVInfo::getRegPathStatic()
-{
- HKEY key;
- LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\FalloutNV",
- 0, KEY_QUERY_VALUE, &key);
-
- if (errorcode != ERROR_SUCCESS) {
- return std::wstring();
- }
-
- WCHAR temp[MAX_PATH];
- DWORD bufferSize = MAX_PATH;
-
- if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
- return std::wstring(temp);
- } else {
- return std::wstring();
- }
-}
-
-std::vector<std::wstring> FalloutNVInfo::getIniFileNames() const
-{
- return boost::assign::list_of(L"fallout.ini")(L"falloutprefs.ini");
-}
-
-std::wstring FalloutNVInfo::getReferenceDataFile() const
-{
- return L"Fallout - Meshes.bsa";
-}
-
-bool FalloutNVInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) const
-{
- static LPCWSTR profileFiles[] = { L"fallout.ini", L"falloutprefs.ini", L"plugins.txt", nullptr };
-
- for (int i = 0; profileFiles[i] != nullptr; ++i) {
- if (_wcsicmp(fileName, profileFiles[i]) == 0) {
- return true;
- }
- }
- return false;
-}
-
-} // namespace MOShared
diff --git a/src/shared/falloutnvinfo.h b/src/shared/falloutnvinfo.h
deleted file mode 100644
index 04c13c7d..00000000
--- a/src/shared/falloutnvinfo.h
+++ /dev/null
@@ -1,59 +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 FALLOUTNVINFO_H
-#define FALLOUTNVINFO_H
-
-
-#include "gameinfo.h"
-
-namespace MOShared {
-
-
-class FalloutNVInfo : public GameInfo
-{
-
- friend class GameInfo;
-
-public:
-
- virtual ~FalloutNVInfo() {}
-
- static std::wstring getRegPathStatic();
- virtual std::wstring getRegPath() const { return getRegPathStatic(); }
-
- // file name of this games ini (no path)
- virtual std::vector<std::wstring> getIniFileNames() const;
-
- virtual std::wstring getReferenceDataFile() const;
-
- virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
-
- virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
-
-private:
-
- FalloutNVInfo(const std::wstring &gameDirectory);
-
- static bool identifyGame(const std::wstring &searchPath);
-};
-
-} // namespace MOShared
-
-#endif // FALLOUTNVINFO_H
diff --git a/src/shared/gameinfo.cpp b/src/shared/gameinfo.cpp
deleted file mode 100644
index 5c13a520..00000000
--- a/src/shared/gameinfo.cpp
+++ /dev/null
@@ -1,164 +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 "gameinfo.h"
-
-#include "windows_error.h"
-
-#include "oblivioninfo.h"
-#include "fallout3info.h"
-#include "falloutnvinfo.h"
-#include "skyriminfo.h"
-#include "util.h"
-
-#include <boost/assign.hpp>
-#include <boost/format.hpp>
-
-#include <shlobj.h>
-#include <sstream>
-#include <cassert>
-
-namespace MOShared {
-
-
-GameInfo* GameInfo::s_Instance = nullptr;
-
-
-GameInfo::GameInfo(const std::wstring &gameDirectory)
- : m_GameDirectory(gameDirectory)
-{
- atexit(&cleanup);
-}
-
-
-void GameInfo::cleanup() {
- delete GameInfo::s_Instance;
- GameInfo::s_Instance = nullptr;
-}
-
-
-void GameInfo::identifyMyGamesDirectory(const std::wstring &file)
-{
- // this function attempts 3 (three!) ways to determine the correct "My Games" folder.
- wchar_t myDocuments[MAX_PATH];
- memset(myDocuments, '\0', MAX_PATH * sizeof(wchar_t));
-
- m_MyGamesDirectory.clear();
-
- // a) this is the way it should work. get the configured My Documents\My Games directory
- if (::SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, myDocuments) == S_OK) {
- m_MyGamesDirectory = std::wstring(myDocuments) + L"\\My Games";
- }
-
- // b) if there is no <game> directory there, look in the default directory
- if (m_MyGamesDirectory.empty()
- || !FileExists(m_MyGamesDirectory + L"\\" + file)) {
- if (::SHGetFolderPathW(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_DEFAULT, myDocuments) == S_OK) {
- std::wstring fromDefault = std::wstring(myDocuments) + L"\\My Games";
- if (FileExists(fromDefault + L"\\" + file)) {
- m_MyGamesDirectory = fromDefault;
- }
- }
- }
- // c) finally, look in the registry. This is discouraged
- if (m_MyGamesDirectory.empty()
- || !FileExists(m_MyGamesDirectory + L"\\" + file)) {
- std::wstring fromRegistry = getSpecialPath(L"Personal") + L"\\My Games";
- if (FileExists(fromRegistry + L"\\" + file)) {
- m_MyGamesDirectory = fromRegistry;
- }
- }
-}
-
-bool GameInfo::identifyGame(const std::wstring &searchPath)
-{
- if (OblivionInfo::identifyGame(searchPath)) {
- s_Instance = new OblivionInfo(searchPath);
- } else if (Fallout3Info::identifyGame(searchPath)) {
- s_Instance = new Fallout3Info(searchPath);
- } else if (FalloutNVInfo::identifyGame(searchPath)) {
- s_Instance = new FalloutNVInfo(searchPath);
- } else if (SkyrimInfo::identifyGame(searchPath)) {
- s_Instance = new SkyrimInfo(searchPath);
- }
-
- return s_Instance != nullptr;
-}
-
-
-bool GameInfo::init(const std::wstring &moDirectory, const std::wstring &gamePath)
-{
- if (s_Instance == nullptr) {
- if (gamePath.length() == 0) {
- // search upward in the directory until a recognized game-binary is found
- std::wstring searchPath(moDirectory);
- while (!identifyGame(searchPath)) {
- size_t lastSep = searchPath.find_last_of(L"/\\");
- if (lastSep == std::string::npos) {
- return false;
- }
- searchPath.erase(lastSep);
- }
- } else if (!identifyGame(gamePath)) {
- return false;
- }
- }
- return true;
-}
-
-
-GameInfo &GameInfo::instance()
-{
- assert(s_Instance != nullptr && "gameinfo not yet initialized");
- return *s_Instance;
-}
-
-std::wstring GameInfo::getGameDirectory() const
-{
- return m_GameDirectory;
-}
-
-std::wstring GameInfo::getSpecialPath(LPCWSTR name) const
-{
- HKEY key;
- LONG errorcode = ::RegOpenKeyExW(HKEY_CURRENT_USER, L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders",
- 0, KEY_QUERY_VALUE, &key);
-
- if (errorcode != ERROR_SUCCESS) {
- throw windows_error("failed to look up special folder (path)", errorcode);
- }
-
- WCHAR temp[MAX_PATH];
- DWORD bufferSize = MAX_PATH;
-
- errorcode = ::RegQueryValueExW(key, name, nullptr, nullptr, (LPBYTE)temp, &bufferSize);
- if (errorcode != ERROR_SUCCESS) {
- throw windows_error((boost::format("failed to look up special folder (%1%)") % ToString(name, true)).str(), errorcode);
- }
-
- WCHAR temp2[MAX_PATH];
- // try to expand variables in the path, if any
- if (::ExpandEnvironmentStringsW(temp, temp2, MAX_PATH) != 0) {
- return temp2;
- } else {
- return temp;
- }
-}
-
-} // namespace MOShared
diff --git a/src/shared/gameinfo.h b/src/shared/gameinfo.h
deleted file mode 100644
index 7bc86d3a..00000000
--- a/src/shared/gameinfo.h
+++ /dev/null
@@ -1,95 +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 GAMEINFO_H
-#define GAMEINFO_H
-
-#include <string>
-#include <vector>
-#include <wchar.h>
-
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-
-namespace MOShared {
-
-
-/**
- Class to manage information that depends on the used game type. The intention is to keep
- as much of the rest of omo is game-agnostic. It is mostly concerned with figuring out the
- correct paths, filenames and data types.
-*/
-class GameInfo
-{
-
-public:
-
- virtual ~GameInfo() {}
-
- //**USED IN HOOKDLL and at startup to set up for hookdll to work
- // initialise with the path to the mo directory (needs to be where hook.dll is stored). This
- // needs to be called before the instance can be retrieved
- static bool init(const std::wstring &moDirectory, const std::wstring &gamePath = L"");
-
- //**USED ONLY IN HOOKDLL
- static GameInfo& instance();
-
- //**USED ONLY IN HOOKDLL
- virtual std::wstring getGameDirectory() const;
-
- //**USED ONLY IN HOOKDLL
- virtual std::wstring getRegPath() const = 0;
-
- //**USED ONLY IN HOOKDLL
- // file name of this games ini file(s)
- virtual std::vector<std::wstring> getIniFileNames() const = 0;
-
- //**USED ONLY IN HOOKDLL
- virtual std::wstring getReferenceDataFile() const = 0;
-
- //**USED ONLY IN HOOKDLL
- virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const = 0;
-
-protected:
-
- GameInfo(const std::wstring &gameDirectory);
-
- void identifyMyGamesDirectory(const std::wstring &file);
-
-private:
-
- static bool identifyGame(const std::wstring &searchPath);
- std::wstring getSpecialPath(LPCWSTR name) const;
-
- static void cleanup();
-
-private:
-
- static GameInfo *s_Instance;
-
- std::wstring m_MyGamesDirectory;
-
- std::wstring m_GameDirectory;
-
-};
-
-
-} // namespace MOShared
-
-#endif // GAMEINFO_H
diff --git a/src/shared/oblivioninfo.cpp b/src/shared/oblivioninfo.cpp
deleted file mode 100644
index b50f1daa..00000000
--- a/src/shared/oblivioninfo.cpp
+++ /dev/null
@@ -1,88 +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 "oblivioninfo.h"
-#include <tchar.h>
-#include <ShlObj.h>
-#include "util.h"
-#include <sstream>
-#include "windows_error.h"
-#include "error_report.h"
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include <boost/assign.hpp>
-
-namespace MOShared {
-
-
-OblivionInfo::OblivionInfo(const std::wstring &gameDirectory)
- : GameInfo(gameDirectory)
-{
- identifyMyGamesDirectory(L"oblivion");
-}
-
-bool OblivionInfo::identifyGame(const std::wstring &searchPath)
-{
- return FileExists(searchPath, L"Oblivion.exe") &&
- FileExists(searchPath, L"OblivionLauncher.exe");
-}
-
-std::wstring OblivionInfo::getRegPathStatic()
-{
- HKEY key;
- LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\Oblivion",
- 0, KEY_QUERY_VALUE, &key);
-
- if (errorcode != ERROR_SUCCESS) {
- return std::wstring();
- }
-
- WCHAR temp[MAX_PATH];
- DWORD bufferSize = MAX_PATH;
-
- if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
- return std::wstring(temp);
- } else {
- return std::wstring();
- }
-}
-
-std::vector<std::wstring> OblivionInfo::getIniFileNames() const
-{
- return boost::assign::list_of(L"oblivion.ini")(L"oblivionprefs.ini");
-}
-
-bool OblivionInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t*) const
-{
- static LPCWSTR profileFiles[] = { L"oblivion.ini", L"oblivionprefs.ini", L"plugins.txt", nullptr };
-
- for (int i = 0; profileFiles[i] != nullptr; ++i) {
- if (_wcsicmp(fileName, profileFiles[i]) == 0) {
- return true;
- }
- }
- return false;
-}
-
-std::wstring OblivionInfo::getReferenceDataFile() const
-{
- return L"Oblivion - Meshes.bsa";
-}
-
-} // namespace MOShared
diff --git a/src/shared/oblivioninfo.h b/src/shared/oblivioninfo.h
deleted file mode 100644
index bf0b2707..00000000
--- a/src/shared/oblivioninfo.h
+++ /dev/null
@@ -1,58 +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 OBLIVIONINFO_H
-#define OBLIVIONINFO_H
-
-#include "gameinfo.h"
-
-namespace MOShared {
-
-class OblivionInfo : public GameInfo
-{
-
- friend class GameInfo;
-
-public:
-
- virtual ~OblivionInfo() {}
-
- static std::wstring getRegPathStatic();
- virtual std::wstring getRegPath() const { return getRegPathStatic(); }
-
- // file name of this games ini (no path)
- virtual std::vector<std::wstring> getIniFileNames() const;
-
- virtual std::wstring getReferenceDataFile() const;
-
- virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
-
- virtual std::wstring archiveListKey() const { return L"SArchiveList"; }
-
-private:
-
- OblivionInfo(const std::wstring &gameDirectory);
-
- static bool identifyGame(const std::wstring &searchPath);
-
-};
-
-} // namespace MOShared
-
-#endif // OBLIVIONINFO_H
diff --git a/src/shared/shared.pro b/src/shared/shared.pro
index a64e781d..517e1e86 100644
--- a/src/shared/shared.pro
+++ b/src/shared/shared.pro
@@ -21,12 +21,7 @@ SOURCES += \
windows_error.cpp \
error_report.cpp \
directoryentry.cpp \
- gameinfo.cpp \
- oblivioninfo.cpp \
- fallout3info.cpp \
- falloutnvinfo.cpp \
util.cpp \
- skyriminfo.cpp \
appconfig.cpp \
leaktrace.cpp \
stackdata.cpp
@@ -36,12 +31,7 @@ HEADERS += \
windows_error.h \
error_report.h \
directoryentry.h \
- gameinfo.h \
- oblivioninfo.h \
- fallout3info.h \
- falloutnvinfo.h \
util.h \
- skyriminfo.h \
appconfig.h \
appconfig.inc \
leaktrace.h \
diff --git a/src/shared/skyriminfo.cpp b/src/shared/skyriminfo.cpp
deleted file mode 100644
index 9662e66d..00000000
--- a/src/shared/skyriminfo.cpp
+++ /dev/null
@@ -1,104 +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 "skyriminfo.h"
-
-#include "util.h"
-#include <tchar.h>
-#include <ShlObj.h>
-#include <sstream>
-#include "windows_error.h"
-#include "error_report.h"
-#define WIN32_LEAN_AND_MEAN
-#include <Windows.h>
-#include <Shlwapi.h>
-#include <boost/assign.hpp>
-
-namespace MOShared {
-
-
-SkyrimInfo::SkyrimInfo(const std::wstring &gameDirectory)
- : GameInfo(gameDirectory)
-{
- identifyMyGamesDirectory(L"skyrim");
-
- wchar_t appDataPath[MAX_PATH];
- if (SUCCEEDED(SHGetFolderPathW(nullptr, CSIDL_LOCAL_APPDATA, nullptr, SHGFP_TYPE_CURRENT, appDataPath))) {
- m_AppData = appDataPath;
- }
-}
-
-bool SkyrimInfo::identifyGame(const std::wstring &searchPath)
-{
- return FileExists(searchPath, L"TESV.exe") &&
- FileExists(searchPath, L"SkyrimLauncher.exe");
-}
-
-
-
-
-std::wstring SkyrimInfo::getRegPathStatic()
-{
- HKEY key;
- LONG errorcode = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"Software\\Bethesda Softworks\\Skyrim",
- 0, KEY_QUERY_VALUE, &key);
-
- if (errorcode != ERROR_SUCCESS) {
- return std::wstring();
- }
-
- WCHAR temp[MAX_PATH];
- DWORD bufferSize = MAX_PATH;
-
- if (::RegQueryValueExW(key, L"Installed Path", nullptr, nullptr, (LPBYTE)temp, &bufferSize) == ERROR_SUCCESS) {
- return std::wstring(temp);
- } else {
- return std::wstring();
- }
-}
-
-std::vector<std::wstring> SkyrimInfo::getIniFileNames() const
-{
- return boost::assign::list_of(L"skyrim.ini")(L"skyrimprefs.ini");
-}
-
-std::wstring SkyrimInfo::getReferenceDataFile() const
-{
- return L"Skyrim - Meshes.bsa";
-}
-
-bool SkyrimInfo::rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const
-{
- static LPCWSTR profileFiles[] = { L"skyrim.ini", L"skyrimprefs.ini", L"loadorder.txt", nullptr };
-
- for (int i = 0; profileFiles[i] != nullptr; ++i) {
- if (_wcsicmp(fileName, profileFiles[i]) == 0) {
- return true;
- }
- }
-
- if ((_wcsicmp(fileName, L"plugins.txt") == 0) &&
- (m_AppData.empty() || (StrStrIW(fullPath, m_AppData.c_str()) != nullptr))) {
- return true;
- }
-
- return false;
-}
-
-} // namespace MOShared
diff --git a/src/shared/skyriminfo.h b/src/shared/skyriminfo.h
deleted file mode 100644
index bd329403..00000000
--- a/src/shared/skyriminfo.h
+++ /dev/null
@@ -1,62 +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 SKYRIMINFO_H
-#define SKYRIMINFO_H
-
-
-#include "gameinfo.h"
-
-namespace MOShared {
-
-
-class SkyrimInfo : public GameInfo
-{
-
- friend class GameInfo;
-
-public:
-
- virtual ~SkyrimInfo() {}
-
- static std::wstring getRegPathStatic();
- virtual std::wstring getRegPath() const { return getRegPathStatic(); }
-
- // file name of this games ini (no path)
- virtual std::vector<std::wstring> getIniFileNames() const;
-
- virtual std::wstring getReferenceDataFile() const;
-
- virtual bool rerouteToProfile(const wchar_t *fileName, const wchar_t *fullPath) const;
-
-private:
-
- SkyrimInfo(const std::wstring &gameDirectory);
-
- static bool identifyGame(const std::wstring &searchPath);
-
-private:
-
- std::wstring m_AppData;
-
-};
-
-} // namespace MOShared
-
-#endif // SKYRIMINFO_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 &currentText)
{
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 &currentText)
{
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
+ );
};