2013-02-25 21:22:07 +01:00
|
|
|
#include "maindialog.hpp"
|
|
|
|
|
2014-01-22 17:51:10 +01:00
|
|
|
#include <components/version/version.hpp>
|
2020-04-18 20:54:21 +00:00
|
|
|
#include <components/misc/helpviewer.hpp>
|
2014-01-22 17:51:10 +01:00
|
|
|
|
2022-06-16 21:29:55 +02:00
|
|
|
#include <QTime>
|
2022-04-17 17:13:31 +00:00
|
|
|
#include <QDir>
|
2022-06-16 21:29:55 +02:00
|
|
|
#include <QDebug>
|
2014-05-29 17:57:41 +02:00
|
|
|
#include <QMessageBox>
|
2013-03-12 01:29:13 +01:00
|
|
|
#include <QCloseEvent>
|
|
|
|
#include <QTextCodec>
|
2011-03-29 01:36:26 +02:00
|
|
|
|
2022-06-25 17:51:01 +02:00
|
|
|
#include <boost/program_options/options_description.hpp>
|
|
|
|
#include <boost/program_options/variables_map.hpp>
|
|
|
|
|
2011-04-07 23:57:03 +02:00
|
|
|
#include "playpage.hpp"
|
2011-05-02 22:21:42 +02:00
|
|
|
#include "graphicspage.hpp"
|
2011-04-07 23:57:03 +02:00
|
|
|
#include "datafilespage.hpp"
|
2014-01-27 20:14:02 +01:00
|
|
|
#include "settingspage.hpp"
|
2018-01-28 22:49:49 -06:00
|
|
|
#include "advancedpage.hpp"
|
2011-03-29 01:36:26 +02:00
|
|
|
|
2014-02-25 15:33:30 +01:00
|
|
|
using namespace Process;
|
|
|
|
|
2015-11-26 01:49:14 -05:00
|
|
|
void cfgError(const QString& title, const QString& msg) {
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setWindowTitle(title);
|
|
|
|
msgBox.setIcon(QMessageBox::Critical);
|
|
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
|
|
msgBox.setText(msg);
|
|
|
|
msgBox.exec();
|
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
Launcher::MainDialog::MainDialog(QWidget *parent)
|
2015-04-25 13:37:42 -05:00
|
|
|
: QMainWindow(parent), mGameSettings (mCfgMgr)
|
2011-04-23 04:34:58 +02:00
|
|
|
{
|
2013-03-03 00:48:09 +01:00
|
|
|
setupUi(this);
|
|
|
|
|
2014-04-18 13:17:37 +02:00
|
|
|
mGameInvoker = new ProcessInvoker();
|
2014-05-29 17:57:41 +02:00
|
|
|
mWizardInvoker = new ProcessInvoker();
|
|
|
|
|
2014-05-30 02:41:09 +02:00
|
|
|
connect(mWizardInvoker->getProcess(), SIGNAL(started()),
|
|
|
|
this, SLOT(wizardStarted()));
|
|
|
|
|
2014-05-29 17:57:41 +02:00
|
|
|
connect(mWizardInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)),
|
|
|
|
this, SLOT(wizardFinished(int,QProcess::ExitStatus)));
|
2014-04-18 13:17:37 +02:00
|
|
|
|
2013-03-03 00:48:09 +01:00
|
|
|
iconWidget->setViewMode(QListView::IconMode);
|
|
|
|
iconWidget->setWrapping(false);
|
|
|
|
iconWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Just to be sure
|
|
|
|
iconWidget->setIconSize(QSize(48, 48));
|
|
|
|
iconWidget->setMovement(QListView::Static);
|
|
|
|
|
|
|
|
iconWidget->setSpacing(4);
|
|
|
|
iconWidget->setCurrentRow(0);
|
|
|
|
iconWidget->setFlow(QListView::LeftToRight);
|
|
|
|
|
2021-05-18 19:20:59 -05:00
|
|
|
auto *helpButton = new QPushButton(tr("Help"));
|
|
|
|
auto *playButton = new QPushButton(tr("Play"));
|
2019-11-23 17:42:10 +01:00
|
|
|
buttonBox->button(QDialogButtonBox::Close)->setText(tr("Close"));
|
2020-04-18 20:54:21 +00:00
|
|
|
buttonBox->addButton(helpButton, QDialogButtonBox::HelpRole);
|
2013-03-03 00:48:09 +01:00
|
|
|
buttonBox->addButton(playButton, QDialogButtonBox::AcceptRole);
|
2012-02-22 08:34:47 +01:00
|
|
|
|
2011-04-24 23:03:21 +02:00
|
|
|
connect(buttonBox, SIGNAL(rejected()), this, SLOT(close()));
|
|
|
|
connect(buttonBox, SIGNAL(accepted()), this, SLOT(play()));
|
2020-04-18 20:54:21 +00:00
|
|
|
connect(buttonBox, SIGNAL(helpRequested()), this, SLOT(help()));
|
2011-05-02 22:21:42 +02:00
|
|
|
|
2013-03-03 00:48:09 +01:00
|
|
|
// Remove what's this? button
|
|
|
|
setWindowFlags(this->windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
|
|
|
|
2011-05-02 22:21:42 +02:00
|
|
|
createIcons();
|
2011-03-29 01:36:26 +02:00
|
|
|
}
|
|
|
|
|
2014-04-18 13:17:37 +02:00
|
|
|
Launcher::MainDialog::~MainDialog()
|
|
|
|
{
|
|
|
|
delete mGameInvoker;
|
2014-05-29 17:57:41 +02:00
|
|
|
delete mWizardInvoker;
|
2014-04-18 13:17:37 +02:00
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
void Launcher::MainDialog::createIcons()
|
2011-03-29 01:36:26 +02:00
|
|
|
{
|
2013-02-25 21:22:07 +01:00
|
|
|
if (!QIcon::hasThemeIcon("document-new"))
|
2011-05-10 18:00:15 +02:00
|
|
|
QIcon::setThemeName("tango");
|
|
|
|
|
2021-05-18 19:20:59 -05:00
|
|
|
auto *playButton = new QListWidgetItem(iconWidget);
|
2011-06-24 21:42:18 +02:00
|
|
|
playButton->setIcon(QIcon(":/images/openmw.png"));
|
2011-05-10 18:00:15 +02:00
|
|
|
playButton->setText(tr("Play"));
|
|
|
|
playButton->setTextAlignment(Qt::AlignCenter);
|
|
|
|
playButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
|
|
|
|
2021-05-18 19:20:59 -05:00
|
|
|
auto *dataFilesButton = new QListWidgetItem(iconWidget);
|
2011-06-24 21:42:18 +02:00
|
|
|
dataFilesButton->setIcon(QIcon(":/images/openmw-plugin.png"));
|
2011-05-10 18:00:15 +02:00
|
|
|
dataFilesButton->setText(tr("Data Files"));
|
|
|
|
dataFilesButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
|
|
|
dataFilesButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
2011-04-07 23:57:03 +02:00
|
|
|
|
2021-05-18 19:20:59 -05:00
|
|
|
auto *graphicsButton = new QListWidgetItem(iconWidget);
|
2018-07-28 13:18:38 +04:00
|
|
|
graphicsButton->setIcon(QIcon(":/images/preferences-video.png"));
|
2014-01-27 20:14:02 +01:00
|
|
|
graphicsButton->setText(tr("Graphics"));
|
|
|
|
graphicsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom | Qt::AlignAbsolute);
|
|
|
|
graphicsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
|
|
|
|
2021-05-18 19:20:59 -05:00
|
|
|
auto *settingsButton = new QListWidgetItem(iconWidget);
|
2018-07-28 13:18:38 +04:00
|
|
|
settingsButton->setIcon(QIcon(":/images/preferences.png"));
|
2014-01-27 20:14:02 +01:00
|
|
|
settingsButton->setText(tr("Settings"));
|
|
|
|
settingsButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
|
|
|
settingsButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
|
|
|
|
2021-05-18 19:20:59 -05:00
|
|
|
auto *advancedButton = new QListWidgetItem(iconWidget);
|
2018-07-28 13:18:38 +04:00
|
|
|
advancedButton->setIcon(QIcon(":/images/preferences-advanced.png"));
|
2018-01-28 22:49:49 -06:00
|
|
|
advancedButton->setText(tr("Advanced"));
|
|
|
|
advancedButton->setTextAlignment(Qt::AlignHCenter | Qt::AlignBottom);
|
|
|
|
advancedButton->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
|
|
|
|
2013-03-03 00:48:09 +01:00
|
|
|
connect(iconWidget,
|
2011-04-07 23:57:03 +02:00
|
|
|
SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)),
|
|
|
|
this, SLOT(changePage(QListWidgetItem*,QListWidgetItem*)));
|
2011-04-24 23:03:21 +02:00
|
|
|
|
2011-05-02 22:21:42 +02:00
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
void Launcher::MainDialog::createPages()
|
2011-09-06 03:50:40 +02:00
|
|
|
{
|
2019-12-08 17:03:27 +03:00
|
|
|
// Avoid creating the widgets twice
|
|
|
|
if (pagesWidget->count() != 0)
|
|
|
|
return;
|
|
|
|
|
2011-09-06 03:50:40 +02:00
|
|
|
mPlayPage = new PlayPage(this);
|
2013-02-11 15:01:00 +01:00
|
|
|
mDataFilesPage = new DataFilesPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
2021-05-08 23:28:29 -05:00
|
|
|
mGraphicsPage = new GraphicsPage(this);
|
2014-04-17 00:01:19 +02:00
|
|
|
mSettingsPage = new SettingsPage(mCfgMgr, mGameSettings, mLauncherSettings, this);
|
2021-05-08 23:28:29 -05:00
|
|
|
mAdvancedPage = new AdvancedPage(mGameSettings, this);
|
2013-10-06 21:13:47 -05:00
|
|
|
|
2012-02-22 08:34:47 +01:00
|
|
|
// Set the combobox of the play page to imitate the combobox on the datafilespage
|
2013-10-06 21:13:47 -05:00
|
|
|
mPlayPage->setProfilesModel(mDataFilesPage->profilesModel());
|
|
|
|
mPlayPage->setProfilesIndex(mDataFilesPage->profilesIndex());
|
2011-05-03 01:23:35 +02:00
|
|
|
|
2011-05-02 22:21:42 +02:00
|
|
|
// Add the pages to the stacked widget
|
2013-03-03 00:48:09 +01:00
|
|
|
pagesWidget->addWidget(mPlayPage);
|
|
|
|
pagesWidget->addWidget(mDataFilesPage);
|
2014-01-27 20:14:02 +01:00
|
|
|
pagesWidget->addWidget(mGraphicsPage);
|
|
|
|
pagesWidget->addWidget(mSettingsPage);
|
2018-01-28 22:49:49 -06:00
|
|
|
pagesWidget->addWidget(mAdvancedPage);
|
2011-05-02 22:21:42 +02:00
|
|
|
|
2011-05-03 02:46:46 +02:00
|
|
|
// Select the first page
|
2013-03-03 00:48:09 +01:00
|
|
|
iconWidget->setCurrentItem(iconWidget->item(0), QItemSelectionModel::Select);
|
2011-05-03 02:46:46 +02:00
|
|
|
|
2013-03-03 01:49:41 +01:00
|
|
|
connect(mPlayPage, SIGNAL(playButtonClicked()), this, SLOT(play()));
|
2011-05-03 03:17:01 +02:00
|
|
|
|
2013-10-06 21:13:47 -05:00
|
|
|
connect(mPlayPage, SIGNAL(signalProfileChanged(int)), mDataFilesPage, SLOT(slotProfileChanged(int)));
|
|
|
|
connect(mDataFilesPage, SIGNAL(signalProfileChanged(int)), mPlayPage, SLOT(setProfilesIndex(int)));
|
2018-06-08 19:16:24 -05:00
|
|
|
// Using Qt::QueuedConnection because signal is emitted in a subthread and slot is in the main thread
|
2018-06-08 19:18:23 -05:00
|
|
|
connect(mDataFilesPage, SIGNAL(signalLoadedCellsChanged(QStringList)), mAdvancedPage, SLOT(slotLoadedCellsChanged(QStringList)), Qt::QueuedConnection);
|
2011-05-03 02:46:46 +02:00
|
|
|
}
|
|
|
|
|
2015-05-16 13:18:04 +03:00
|
|
|
Launcher::FirstRunDialogResult Launcher::MainDialog::showFirstRunDialog()
|
2013-02-20 19:27:04 +01:00
|
|
|
{
|
2014-05-30 02:12:48 +02:00
|
|
|
if (!setupLauncherSettings())
|
2015-05-16 13:18:04 +03:00
|
|
|
return FirstRunDialogResultFailure;
|
2014-05-30 02:12:48 +02:00
|
|
|
|
2022-04-17 17:13:31 +00:00
|
|
|
// Dialog wizard and setup will fail if the config directory does not already exist
|
|
|
|
QDir userConfigDir = QDir(QString::fromStdString(mCfgMgr.getUserConfigPath().string()));
|
|
|
|
if ( ! userConfigDir.exists() ) {
|
|
|
|
if ( ! userConfigDir.mkpath(".") )
|
|
|
|
{
|
|
|
|
cfgError(tr("Error opening OpenMW configuration file"),
|
|
|
|
tr("<br><b>Could not create directory %0</b><br><br> \
|
|
|
|
Please make sure you have the right permissions \
|
|
|
|
and try again.<br>").arg(userConfigDir.canonicalPath())
|
|
|
|
);
|
|
|
|
return FirstRunDialogResultFailure;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-30 02:12:48 +02:00
|
|
|
if (mLauncherSettings.value(QString("General/firstrun"), QString("true")) == QLatin1String("true"))
|
2014-05-29 17:57:41 +02:00
|
|
|
{
|
2014-05-30 02:12:48 +02:00
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setWindowTitle(tr("First run"));
|
|
|
|
msgBox.setIcon(QMessageBox::Question);
|
|
|
|
msgBox.setStandardButtons(QMessageBox::NoButton);
|
|
|
|
msgBox.setText(tr("<html><head/><body><p><b>Welcome to OpenMW!</b></p> \
|
|
|
|
<p>It is recommended to run the Installation Wizard.</p> \
|
|
|
|
<p>The Wizard will let you select an existing Morrowind installation, \
|
|
|
|
or install Morrowind for OpenMW to use.</p></body></html>"));
|
|
|
|
|
|
|
|
QAbstractButton *wizardButton =
|
|
|
|
msgBox.addButton(tr("Run &Installation Wizard"), QMessageBox::AcceptRole); // ActionRole doesn't work?!
|
|
|
|
QAbstractButton *skipButton =
|
|
|
|
msgBox.addButton(tr("Skip"), QMessageBox::RejectRole);
|
|
|
|
|
|
|
|
msgBox.exec();
|
|
|
|
|
|
|
|
if (msgBox.clickedButton() == wizardButton)
|
|
|
|
{
|
2019-12-08 17:03:27 +03:00
|
|
|
if (mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
2015-05-16 13:18:04 +03:00
|
|
|
return FirstRunDialogResultWizard;
|
2014-05-29 17:57:41 +02:00
|
|
|
}
|
2019-12-08 17:03:27 +03:00
|
|
|
else if (msgBox.clickedButton() == skipButton)
|
|
|
|
{
|
|
|
|
// Don't bother setting up absent game data.
|
|
|
|
if (setup())
|
|
|
|
return FirstRunDialogResultContinue;
|
|
|
|
}
|
|
|
|
return FirstRunDialogResultFailure;
|
2014-05-29 17:57:41 +02:00
|
|
|
}
|
2013-03-16 01:46:28 +01:00
|
|
|
|
2017-08-03 23:15:26 +02:00
|
|
|
if (!setup() || !setupGameData()) {
|
|
|
|
return FirstRunDialogResultFailure;
|
|
|
|
}
|
|
|
|
return FirstRunDialogResultContinue;
|
2013-02-20 19:27:04 +01:00
|
|
|
}
|
2012-06-20 20:43:51 +02:00
|
|
|
|
2015-07-18 03:01:06 +02:00
|
|
|
void Launcher::MainDialog::setVersionLabel()
|
|
|
|
{
|
|
|
|
// Add version information to bottom of the window
|
|
|
|
Version::Version v = Version::getOpenmwVersion(mGameSettings.value("resources").toUtf8().constData());
|
|
|
|
|
|
|
|
QString revision(QString::fromUtf8(v.mCommitHash.c_str()));
|
|
|
|
QString tag(QString::fromUtf8(v.mTagHash.c_str()));
|
|
|
|
|
|
|
|
versionLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
|
2015-08-06 02:54:47 +02:00
|
|
|
if (!v.mVersion.empty() && (revision.isEmpty() || revision == tag))
|
|
|
|
versionLabel->setText(tr("OpenMW %1 release").arg(QString::fromUtf8(v.mVersion.c_str())));
|
|
|
|
else
|
|
|
|
versionLabel->setText(tr("OpenMW development (%1)").arg(revision.left(10)));
|
|
|
|
|
|
|
|
// Add the compile date and time
|
2020-10-22 15:50:47 +04:00
|
|
|
auto compileDate = QLocale(QLocale::C).toDate(QString(__DATE__).simplified(), QLatin1String("MMM d yyyy"));
|
|
|
|
auto compileTime = QLocale(QLocale::C).toTime(QString(__TIME__).simplified(), QLatin1String("hh:mm:ss"));
|
|
|
|
versionLabel->setToolTip(tr("Compiled on %1 %2").arg(QLocale::system().toString(compileDate, QLocale::LongFormat),
|
|
|
|
QLocale::system().toString(compileTime, QLocale::ShortFormat)));
|
2015-07-18 03:01:06 +02:00
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
bool Launcher::MainDialog::setup()
|
2012-06-20 20:43:51 +02:00
|
|
|
{
|
2013-02-20 19:27:04 +01:00
|
|
|
if (!setupGameSettings())
|
|
|
|
return false;
|
|
|
|
|
2015-07-18 03:01:06 +02:00
|
|
|
setVersionLabel();
|
|
|
|
|
2015-01-10 18:46:47 +13:00
|
|
|
mLauncherSettings.setContentList(mGameSettings);
|
|
|
|
|
2013-02-20 19:27:04 +01:00
|
|
|
if (!setupGraphicsSettings())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
// Now create the pages as they need the settings
|
|
|
|
createPages();
|
|
|
|
|
2015-05-12 17:40:42 +02:00
|
|
|
// Call this so we can exit on SDL errors before mainwindow is shown
|
2013-06-23 03:49:30 +02:00
|
|
|
if (!mGraphicsPage->loadSettings())
|
2013-02-20 19:27:04 +01:00
|
|
|
return false;
|
|
|
|
|
2013-02-15 14:12:25 +01:00
|
|
|
loadSettings();
|
2014-05-29 17:57:41 +02:00
|
|
|
|
2012-06-20 20:43:51 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2014-04-16 16:54:55 +02:00
|
|
|
bool Launcher::MainDialog::reloadSettings()
|
|
|
|
{
|
|
|
|
if (!setupLauncherSettings())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!setupGameSettings())
|
|
|
|
return false;
|
|
|
|
|
2015-01-10 18:46:47 +13:00
|
|
|
mLauncherSettings.setContentList(mGameSettings);
|
|
|
|
|
2014-04-16 16:54:55 +02:00
|
|
|
if (!setupGraphicsSettings())
|
|
|
|
return false;
|
|
|
|
|
2014-04-17 00:01:19 +02:00
|
|
|
if (!mSettingsPage->loadSettings())
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!mDataFilesPage->loadSettings())
|
|
|
|
return false;
|
2014-04-16 16:54:55 +02:00
|
|
|
|
|
|
|
if (!mGraphicsPage->loadSettings())
|
|
|
|
return false;
|
|
|
|
|
2018-01-28 22:49:49 -06:00
|
|
|
if (!mAdvancedPage->loadSettings())
|
|
|
|
return false;
|
|
|
|
|
2014-04-16 16:54:55 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
void Launcher::MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous)
|
2011-03-29 01:36:26 +02:00
|
|
|
{
|
2011-04-07 23:57:03 +02:00
|
|
|
if (!current)
|
|
|
|
current = previous;
|
2011-03-29 01:36:26 +02:00
|
|
|
|
2013-10-06 21:13:47 -05:00
|
|
|
int currentIndex = iconWidget->row(current);
|
|
|
|
pagesWidget->setCurrentIndex(currentIndex);
|
2015-02-22 08:46:12 +13:00
|
|
|
mSettingsPage->resetProgressBar();
|
2011-05-03 02:46:46 +02:00
|
|
|
}
|
2011-04-23 04:34:58 +02:00
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
bool Launcher::MainDialog::setupLauncherSettings()
|
2013-02-20 19:27:04 +01:00
|
|
|
{
|
2015-11-27 20:52:29 +01:00
|
|
|
mLauncherSettings.clear();
|
|
|
|
|
2013-06-02 21:43:22 +02:00
|
|
|
mLauncherSettings.setMultiValueEnabled(true);
|
|
|
|
|
2014-01-14 23:29:24 +04:00
|
|
|
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
2013-02-20 19:27:04 +01:00
|
|
|
|
|
|
|
QStringList paths;
|
2015-01-10 18:46:47 +13:00
|
|
|
paths.append(QString(Config::LauncherSettings::sLauncherConfigFileName));
|
|
|
|
paths.append(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName));
|
2013-02-20 19:27:04 +01:00
|
|
|
|
2019-10-06 13:39:27 +02:00
|
|
|
for (const QString &path : paths)
|
|
|
|
{
|
2015-11-26 17:34:22 +01:00
|
|
|
qDebug() << "Loading config file:" << path.toUtf8().constData();
|
2013-02-20 19:27:04 +01:00
|
|
|
QFile file(path);
|
|
|
|
if (file.exists()) {
|
|
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
2015-11-26 01:49:14 -05:00
|
|
|
cfgError(tr("Error opening OpenMW configuration file"),
|
|
|
|
tr("<br><b>Could not open %0 for reading</b><br><br> \
|
|
|
|
Please make sure you have the right permissions \
|
|
|
|
and try again.<br>").arg(file.fileName()));
|
2013-02-20 19:27:04 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
QTextStream stream(&file);
|
|
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
|
|
|
|
mLauncherSettings.readFile(stream);
|
|
|
|
}
|
|
|
|
file.close();
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
bool Launcher::MainDialog::setupGameSettings()
|
2013-02-20 19:27:04 +01:00
|
|
|
{
|
2015-11-27 20:52:29 +01:00
|
|
|
mGameSettings.clear();
|
|
|
|
|
2016-11-01 21:14:24 +01:00
|
|
|
QString localPath = QString::fromUtf8(mCfgMgr.getLocalPath().string().c_str());
|
2014-01-14 23:29:24 +04:00
|
|
|
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
|
|
|
QString globalPath = QString::fromUtf8(mCfgMgr.getGlobalPath().string().c_str());
|
2013-02-20 19:27:04 +01:00
|
|
|
|
2022-06-30 20:57:51 +02:00
|
|
|
QFile file;
|
2013-02-20 19:27:04 +01:00
|
|
|
|
2022-07-02 11:19:36 +02:00
|
|
|
auto loadFile = [&] (const QString& path, bool(Config::GameSettings::*reader)(QTextStream&, bool), bool ignoreContent = false) -> std::optional<bool>
|
2019-10-06 13:39:27 +02:00
|
|
|
{
|
2022-06-30 20:57:51 +02:00
|
|
|
qDebug() << "Loading config file:" << path.toUtf8().constData();
|
|
|
|
file.setFileName(path);
|
2013-02-20 19:27:04 +01:00
|
|
|
if (file.exists()) {
|
|
|
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
2015-11-26 01:49:14 -05:00
|
|
|
cfgError(tr("Error opening OpenMW configuration file"),
|
2022-06-30 20:57:51 +02:00
|
|
|
tr("<br><b>Could not open %0 for reading</b><br><br> \
|
|
|
|
Please make sure you have the right permissions \
|
|
|
|
and try again.<br>").arg(file.fileName()));
|
2022-07-02 11:19:36 +02:00
|
|
|
return {};
|
2013-02-20 19:27:04 +01:00
|
|
|
}
|
|
|
|
QTextStream stream(&file);
|
|
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
|
2022-06-30 20:57:51 +02:00
|
|
|
(mGameSettings.*reader)(stream, ignoreContent);
|
2019-09-10 22:54:43 +03:00
|
|
|
file.close();
|
2022-07-02 11:19:36 +02:00
|
|
|
return true;
|
2013-02-20 19:27:04 +01:00
|
|
|
}
|
2022-07-02 11:19:36 +02:00
|
|
|
return false;
|
2022-06-30 20:57:51 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
// Load the user config file first, separately
|
|
|
|
// So we can write it properly, uncontaminated
|
2022-07-02 11:19:36 +02:00
|
|
|
if(!loadFile(userPath + QLatin1String("openmw.cfg"), &Config::GameSettings::readUserFile))
|
|
|
|
return false;
|
2022-06-30 20:57:51 +02:00
|
|
|
|
|
|
|
// Now the rest - priority: user > local > global
|
2022-07-02 11:19:36 +02:00
|
|
|
if(auto result = loadFile(localPath + QString("openmw.cfg"), &Config::GameSettings::readFile, true))
|
|
|
|
{
|
|
|
|
// Load global if local wasn't found
|
|
|
|
if(!*result && !loadFile(globalPath + QString("openmw.cfg"), &Config::GameSettings::readFile, true))
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
if(!loadFile(userPath + QString("openmw.cfg"), &Config::GameSettings::readFile))
|
|
|
|
return false;
|
2013-02-20 19:27:04 +01:00
|
|
|
|
2017-08-03 23:15:26 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Launcher::MainDialog::setupGameData()
|
|
|
|
{
|
2013-02-25 01:22:14 +01:00
|
|
|
QStringList dataDirs;
|
|
|
|
|
|
|
|
// Check if the paths actually contain data files
|
2019-10-06 13:39:27 +02:00
|
|
|
for (const QString& path3 : mGameSettings.getDataDirs())
|
|
|
|
{
|
2016-11-13 22:48:33 +09:00
|
|
|
QDir dir(path3);
|
2013-02-25 01:22:14 +01:00
|
|
|
QStringList filters;
|
2013-10-22 21:52:35 -05:00
|
|
|
filters << "*.esp" << "*.esm" << "*.omwgame" << "*.omwaddon";
|
2013-02-25 01:22:14 +01:00
|
|
|
|
|
|
|
if (!dir.entryList(filters).isEmpty())
|
2016-11-13 22:48:33 +09:00
|
|
|
dataDirs.append(path3);
|
2013-02-25 01:22:14 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
if (dataDirs.isEmpty())
|
2013-02-20 19:27:04 +01:00
|
|
|
{
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setWindowTitle(tr("Error detecting Morrowind installation"));
|
|
|
|
msgBox.setIcon(QMessageBox::Warning);
|
2019-12-08 17:03:27 +03:00
|
|
|
msgBox.setStandardButtons(QMessageBox::NoButton);
|
2014-05-29 17:57:41 +02:00
|
|
|
msgBox.setText(tr("<br><b>Could not find the Data Files location</b><br><br> \
|
2014-11-20 22:39:21 +01:00
|
|
|
The directory containing the data files was not found."));
|
2013-11-03 22:08:38 +01:00
|
|
|
|
2014-05-29 17:57:41 +02:00
|
|
|
QAbstractButton *wizardButton =
|
|
|
|
msgBox.addButton(tr("Run &Installation Wizard..."), QMessageBox::ActionRole);
|
2019-12-08 17:03:27 +03:00
|
|
|
QAbstractButton *skipButton =
|
|
|
|
msgBox.addButton(tr("Skip"), QMessageBox::RejectRole);
|
|
|
|
|
2020-06-27 01:20:57 +02:00
|
|
|
Q_UNUSED(skipButton); // Suppress compiler unused warning
|
2013-08-17 22:56:50 +01:00
|
|
|
|
2014-05-29 17:57:41 +02:00
|
|
|
msgBox.exec();
|
2013-02-20 19:27:04 +01:00
|
|
|
|
2014-11-20 22:39:21 +01:00
|
|
|
if (msgBox.clickedButton() == wizardButton)
|
2014-05-29 17:57:41 +02:00
|
|
|
{
|
2019-12-08 17:03:27 +03:00
|
|
|
if (!mWizardInvoker->startProcess(QLatin1String("openmw-wizard"), false))
|
2014-05-29 17:57:41 +02:00
|
|
|
return false;
|
2013-08-17 22:56:50 +01:00
|
|
|
}
|
2013-02-20 19:27:04 +01:00
|
|
|
}
|
2017-06-20 00:13:32 +02:00
|
|
|
|
2013-02-20 19:27:04 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
bool Launcher::MainDialog::setupGraphicsSettings()
|
2013-02-20 19:27:04 +01:00
|
|
|
{
|
2022-07-11 20:41:07 +04:00
|
|
|
Settings::Manager::clear(); // Ensure to clear previous settings in case we had already loaded settings.
|
2022-01-16 01:59:20 +01:00
|
|
|
try
|
|
|
|
{
|
|
|
|
boost::program_options::variables_map variables;
|
|
|
|
boost::program_options::options_description desc;
|
|
|
|
mCfgMgr.addCommonOptions(desc);
|
|
|
|
mCfgMgr.readConfiguration(variables, desc, true);
|
2022-07-11 20:41:07 +04:00
|
|
|
Settings::Manager::load(mCfgMgr);
|
2022-01-16 01:59:20 +01:00
|
|
|
return true;
|
2015-11-25 13:17:03 -05:00
|
|
|
}
|
2022-01-16 01:59:20 +01:00
|
|
|
catch (std::exception& e)
|
|
|
|
{
|
|
|
|
cfgError(tr("Error reading OpenMW configuration files"),
|
|
|
|
tr("<br>The problem may be due to an incomplete installation of OpenMW.<br> \
|
|
|
|
Reinstalling OpenMW may resolve the problem.<br>") + e.what());
|
2015-11-25 13:17:03 -05:00
|
|
|
return false;
|
2013-02-20 19:27:04 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
void Launcher::MainDialog::loadSettings()
|
2013-02-11 15:01:00 +01:00
|
|
|
{
|
2013-02-15 14:12:25 +01:00
|
|
|
int width = mLauncherSettings.value(QString("General/MainWindow/width")).toInt();
|
|
|
|
int height = mLauncherSettings.value(QString("General/MainWindow/height")).toInt();
|
2013-02-11 15:01:00 +01:00
|
|
|
|
2013-02-15 14:12:25 +01:00
|
|
|
int posX = mLauncherSettings.value(QString("General/MainWindow/posx")).toInt();
|
|
|
|
int posY = mLauncherSettings.value(QString("General/MainWindow/posy")).toInt();
|
|
|
|
|
|
|
|
resize(width, height);
|
|
|
|
move(posX, posY);
|
2013-02-11 15:01:00 +01:00
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
void Launcher::MainDialog::saveSettings()
|
2013-02-11 15:01:00 +01:00
|
|
|
{
|
|
|
|
QString width = QString::number(this->width());
|
|
|
|
QString height = QString::number(this->height());
|
|
|
|
|
|
|
|
mLauncherSettings.setValue(QString("General/MainWindow/width"), width);
|
|
|
|
mLauncherSettings.setValue(QString("General/MainWindow/height"), height);
|
|
|
|
|
2013-02-15 14:12:25 +01:00
|
|
|
QString posX = QString::number(this->pos().x());
|
|
|
|
QString posY = QString::number(this->pos().y());
|
|
|
|
|
|
|
|
mLauncherSettings.setValue(QString("General/MainWindow/posx"), posX);
|
|
|
|
mLauncherSettings.setValue(QString("General/MainWindow/posy"), posY);
|
2013-02-20 19:27:04 +01:00
|
|
|
|
|
|
|
mLauncherSettings.setValue(QString("General/firstrun"), QString("false"));
|
|
|
|
|
2013-02-11 15:01:00 +01:00
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
bool Launcher::MainDialog::writeSettings()
|
2011-05-03 02:46:46 +02:00
|
|
|
{
|
2011-05-03 15:09:21 +02:00
|
|
|
// Now write all config files
|
2013-02-11 15:01:00 +01:00
|
|
|
saveSettings();
|
|
|
|
mDataFilesPage->saveSettings();
|
2014-04-17 00:01:19 +02:00
|
|
|
mGraphicsPage->saveSettings();
|
|
|
|
mSettingsPage->saveSettings();
|
2018-01-28 22:49:49 -06:00
|
|
|
mAdvancedPage->saveSettings();
|
2013-01-27 16:39:51 +01:00
|
|
|
|
2014-01-14 23:29:24 +04:00
|
|
|
QString userPath = QString::fromUtf8(mCfgMgr.getUserConfigPath().string().c_str());
|
2013-01-27 16:39:51 +01:00
|
|
|
QDir dir(userPath);
|
|
|
|
|
|
|
|
if (!dir.exists()) {
|
|
|
|
if (!dir.mkpath(userPath)) {
|
2015-11-26 01:49:14 -05:00
|
|
|
cfgError(tr("Error creating OpenMW configuration directory"),
|
|
|
|
tr("<br><b>Could not create %0</b><br><br> \
|
|
|
|
Please make sure you have the right permissions \
|
|
|
|
and try again.<br>").arg(userPath));
|
|
|
|
return false;
|
2013-01-27 16:39:51 +01:00
|
|
|
}
|
|
|
|
}
|
2012-05-22 20:37:18 +02:00
|
|
|
|
2013-01-27 16:39:51 +01:00
|
|
|
// Game settings
|
|
|
|
QFile file(userPath + QString("openmw.cfg"));
|
|
|
|
|
2015-06-14 14:51:01 +10:00
|
|
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
|
2013-01-27 16:39:51 +01:00
|
|
|
// File cannot be opened or created
|
2015-11-26 01:49:14 -05:00
|
|
|
cfgError(tr("Error writing OpenMW configuration file"),
|
|
|
|
tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
|
|
|
Please make sure you have the right permissions \
|
|
|
|
and try again.<br>").arg(file.fileName()));
|
|
|
|
return false;
|
2013-01-27 16:39:51 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-06-14 14:51:01 +10:00
|
|
|
mGameSettings.writeFileWithComments(file);
|
2013-01-27 16:39:51 +01:00
|
|
|
file.close();
|
|
|
|
|
|
|
|
// Graphics settings
|
2015-11-26 17:15:28 +01:00
|
|
|
const std::string settingsPath = (mCfgMgr.getUserConfigPath() / "settings.cfg").string();
|
2015-11-25 13:17:03 -05:00
|
|
|
try {
|
2022-07-11 20:41:07 +04:00
|
|
|
Settings::Manager::saveUser(settingsPath);
|
2015-11-25 13:17:03 -05:00
|
|
|
}
|
|
|
|
catch (std::exception& e) {
|
|
|
|
std::string msg = "<br><b>Error writing settings.cfg</b><br><br>" +
|
|
|
|
settingsPath + "<br><br>" + e.what();
|
2015-11-26 17:13:13 +01:00
|
|
|
cfgError(tr("Error writing user settings file"), tr(msg.c_str()));
|
2015-11-25 13:17:03 -05:00
|
|
|
return false;
|
2013-01-27 16:39:51 +01:00
|
|
|
}
|
2013-02-11 15:01:00 +01:00
|
|
|
|
|
|
|
// Launcher settings
|
2015-01-10 18:46:47 +13:00
|
|
|
file.setFileName(userPath + QString(Config::LauncherSettings::sLauncherConfigFileName));
|
2013-02-11 15:01:00 +01:00
|
|
|
|
|
|
|
if (!file.open(QIODevice::ReadWrite | QIODevice::Text | QIODevice::Truncate)) {
|
|
|
|
// File cannot be opened or created
|
2015-11-26 01:49:14 -05:00
|
|
|
cfgError(tr("Error writing Launcher configuration file"),
|
|
|
|
tr("<br><b>Could not open or create %0 for writing</b><br><br> \
|
|
|
|
Please make sure you have the right permissions \
|
|
|
|
and try again.<br>").arg(file.fileName()));
|
|
|
|
return false;
|
2013-02-11 15:01:00 +01:00
|
|
|
}
|
2012-05-22 20:37:18 +02:00
|
|
|
|
2015-11-25 13:17:03 -05:00
|
|
|
QTextStream stream(&file);
|
2013-02-11 15:01:00 +01:00
|
|
|
stream.setDevice(&file);
|
|
|
|
stream.setCodec(QTextCodec::codecForName("UTF-8"));
|
|
|
|
|
|
|
|
mLauncherSettings.writeFile(stream);
|
|
|
|
file.close();
|
2013-03-10 21:12:26 +01:00
|
|
|
|
|
|
|
return true;
|
2013-02-11 15:01:00 +01:00
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
void Launcher::MainDialog::closeEvent(QCloseEvent *event)
|
2013-02-11 15:01:00 +01:00
|
|
|
{
|
|
|
|
writeSettings();
|
2011-05-03 02:46:46 +02:00
|
|
|
event->accept();
|
|
|
|
}
|
2011-04-23 04:34:58 +02:00
|
|
|
|
2014-05-29 17:57:41 +02:00
|
|
|
void Launcher::MainDialog::wizardStarted()
|
|
|
|
{
|
2014-05-30 02:41:09 +02:00
|
|
|
hide();
|
2014-05-29 17:57:41 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void Launcher::MainDialog::wizardFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
|
|
|
{
|
|
|
|
if (exitCode != 0 || exitStatus == QProcess::CrashExit)
|
|
|
|
return qApp->quit();
|
|
|
|
|
2014-05-30 02:50:17 +02:00
|
|
|
// HACK: Ensure the pages are created, else segfault
|
|
|
|
setup();
|
|
|
|
|
2019-12-08 17:03:27 +03:00
|
|
|
if (setupGameData() && reloadSettings())
|
2014-05-30 02:41:09 +02:00
|
|
|
show();
|
2014-05-29 17:57:41 +02:00
|
|
|
}
|
|
|
|
|
2013-10-25 11:17:26 -05:00
|
|
|
void Launcher::MainDialog::play()
|
2011-05-03 02:46:46 +02:00
|
|
|
{
|
2014-05-29 17:57:41 +02:00
|
|
|
if (!writeSettings())
|
|
|
|
return qApp->quit();
|
2012-06-27 00:55:25 +02:00
|
|
|
|
2014-05-29 17:57:41 +02:00
|
|
|
if (!mGameSettings.hasMaster()) {
|
|
|
|
QMessageBox msgBox;
|
|
|
|
msgBox.setWindowTitle(tr("No game file selected"));
|
|
|
|
msgBox.setIcon(QMessageBox::Warning);
|
|
|
|
msgBox.setStandardButtons(QMessageBox::Ok);
|
|
|
|
msgBox.setText(tr("<br><b>You do not have a game file selected.</b><br><br> \
|
|
|
|
OpenMW will not start without a game file selected.<br>"));
|
2022-04-17 16:28:14 +00:00
|
|
|
msgBox.exec();
|
2014-05-29 17:57:41 +02:00
|
|
|
return;
|
2013-06-17 08:58:48 +00:00
|
|
|
}
|
2012-06-27 00:55:25 +02:00
|
|
|
|
2013-02-20 19:27:04 +01:00
|
|
|
// Launch the game detached
|
2014-04-16 16:54:55 +02:00
|
|
|
|
2014-04-18 13:17:37 +02:00
|
|
|
if (mGameInvoker->startProcess(QLatin1String("openmw"), true))
|
2014-05-29 17:57:41 +02:00
|
|
|
return qApp->quit();
|
2011-03-29 01:36:26 +02:00
|
|
|
}
|
2020-04-18 20:54:21 +00:00
|
|
|
|
|
|
|
void Launcher::MainDialog::help()
|
|
|
|
{
|
|
|
|
Misc::HelpViewer::openHelp("reference/index.html");
|
|
|
|
}
|