Fixed most of the memory leaks and started working on correctly exiting the thread

loadfix
pvdk 10 years ago
parent af883991e2
commit aa07a33906

@ -1,7 +1,6 @@
#include "maindialog.hpp"
#include <components/version/version.hpp>
#include <components/process/processinvoker.hpp>
#include <QLabel>
#include <QDate>
@ -35,27 +34,10 @@ using namespace Process;
Launcher::MainDialog::MainDialog(QWidget *parent)
: mGameSettings(mCfgMgr), QMainWindow (parent)
{
// Install the stylesheet font
QFile file;
QFontDatabase fontDatabase;
const QStringList fonts = fontDatabase.families();
// Check if the font is installed
if (!fonts.contains("EB Garamond")) {
QString font = QString::fromStdString(mCfgMgr.getGlobalDataPath().string()) + QString("resources/mygui/EBGaramond-Regular.ttf");
file.setFileName(font);
if (!file.exists()) {
font = QString::fromStdString(mCfgMgr.getLocalPath().string()) + QString("resources/mygui/EBGaramond-Regular.ttf");
}
fontDatabase.addApplicationFont(font);
}
setupUi(this);
mGameInvoker = new ProcessInvoker();
iconWidget->setViewMode(QListView::IconMode);
iconWidget->setWrapping(false);
iconWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); // Just to be sure
@ -94,9 +76,33 @@ Launcher::MainDialog::MainDialog(QWidget *parent)
QLatin1String("hh:mm:ss")).toString(Qt::SystemLocaleShortDate)));
}
// Install the stylesheet font
QFile file;
QFontDatabase fontDatabase;
const QStringList fonts = fontDatabase.families();
// Check if the font is installed
if (!fonts.contains("EB Garamond")) {
QString font = QString::fromStdString(mCfgMgr.getGlobalDataPath().string()) + QString("resources/mygui/EBGaramond-Regular.ttf");
file.setFileName(font);
if (!file.exists()) {
font = QString::fromStdString(mCfgMgr.getLocalPath().string()) + QString("resources/mygui/EBGaramond-Regular.ttf");
}
fontDatabase.addApplicationFont(font);
}
createIcons();
}
Launcher::MainDialog::~MainDialog()
{
delete mGameInvoker;
}
void Launcher::MainDialog::createIcons()
{
if (!QIcon::hasThemeIcon("document-new"))
@ -801,8 +807,7 @@ void Launcher::MainDialog::play()
}
// Launch the game detached
ProcessInvoker invoker(this);
if (invoker.startProcess(QLatin1String("openmw"), true))
if (mGameInvoker->startProcess(QLatin1String("openmw"), true))
qApp->quit();
}

@ -5,6 +5,9 @@
#ifndef Q_MOC_RUN
#include <components/files/configurationmanager.hpp>
#endif
#include <components/process/processinvoker.hpp>
#include <components/config/gamesettings.hpp>
#include <components/config/launchersettings.hpp>
@ -36,6 +39,8 @@ namespace Launcher
public:
explicit MainDialog(QWidget *parent = 0);
~MainDialog();
bool setup();
bool showFirstRunDialog();
@ -67,6 +72,7 @@ namespace Launcher
DataFilesPage *mDataFilesPage;
SettingsPage *mSettingsPage;
Process::ProcessInvoker *mGameInvoker;
Files::ConfigurationManager mCfgMgr;

@ -36,8 +36,8 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
languageComboBox->addItems(languages);
mWizardInvoker = new ProcessInvoker(this);
mImporterInvoker = new ProcessInvoker(this);
mWizardInvoker = new ProcessInvoker();
mImporterInvoker = new ProcessInvoker();
connect(mWizardInvoker->getProcess(), SIGNAL(started()),
this, SLOT(wizardStarted()));
@ -85,6 +85,12 @@ Launcher::SettingsPage::SettingsPage(Files::ConfigurationManager &cfg,
loadSettings();
}
Launcher::SettingsPage::~SettingsPage()
{
delete mWizardInvoker;
delete mImporterInvoker;
}
void Launcher::SettingsPage::on_wizardButton_clicked()
{
saveSettings();

@ -25,6 +25,7 @@ namespace Launcher
public:
SettingsPage(Files::ConfigurationManager &cfg, Config::GameSettings &gameSettings,
Config::LauncherSettings &launcherSettings, MainDialog *parent = 0);
~SettingsPage();
void saveSettings();
bool loadSettings();

@ -7,10 +7,11 @@
#include "mainwizard.hpp"
Wizard::ComponentSelectionPage::ComponentSelectionPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::ComponentSelectionPage::ComponentSelectionPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
setCommitPage(true);

@ -13,7 +13,7 @@ namespace Wizard
{
Q_OBJECT
public:
ComponentSelectionPage(MainWizard *wizard);
ComponentSelectionPage(QWidget *parent);
int nextId() const;
virtual bool validatePage();

@ -4,10 +4,11 @@
#include "mainwizard.hpp"
Wizard::ConclusionPage::ConclusionPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::ConclusionPage::ConclusionPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/images/intropage-background.png")));
}

@ -13,7 +13,7 @@ namespace Wizard
{
Q_OBJECT
public:
ConclusionPage(MainWizard *wizard);
ConclusionPage(QWidget *parent);
int nextId() const;

@ -8,16 +8,27 @@
#include "mainwizard.hpp"
Wizard::ExistingInstallationPage::ExistingInstallationPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::ExistingInstallationPage::ExistingInstallationPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
}
void Wizard::ExistingInstallationPage::initializePage()
{
QListWidgetItem *emptyItem = new QListWidgetItem(tr("No existing installations detected"));
emptyItem->setFlags(Qt::NoItemFlags);
installationsList->addItem(emptyItem);
// Test
if (mWizard->mInstallations.isEmpty()) {
qDebug() << "crashy crash";
return;
}
// Add the available installation paths
QStringList paths(mWizard->mInstallations.keys());

@ -13,7 +13,7 @@ namespace Wizard
{
Q_OBJECT
public:
ExistingInstallationPage(MainWizard *wizard);
ExistingInstallationPage(QWidget *parent);
int nextId() const;
virtual bool isComplete() const;
@ -27,6 +27,9 @@ namespace Wizard
private:
MainWizard *mWizard;
protected:
void initializePage();
};
}

@ -2,10 +2,11 @@
#include "mainwizard.hpp"
Wizard::ImportPage::ImportPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::ImportPage::ImportPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
registerField(QLatin1String("installation.import-settings"), importCheckBox);

@ -13,7 +13,7 @@ namespace Wizard
{
Q_OBJECT
public:
ImportPage(MainWizard *wizard);
ImportPage(QWidget *parent);
int nextId() const;

@ -9,48 +9,14 @@
#include "mainwizard.hpp"
#include "inisettings.hpp"
Wizard::InstallationPage::InstallationPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::InstallationPage::InstallationPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
mFinished = false;
}
void Wizard::InstallationPage::initializePage()
{
QString path(field(QLatin1String("installation.path")).toString());
QStringList components(field(QLatin1String("installation.components")).toStringList());
logTextEdit->appendPlainText(QString("Installing to %1").arg(path));
logTextEdit->appendPlainText(QString("Installing %1.").arg(components.join(", ")));
installProgressBar->setMinimum(0);
// Set the progressbar maximum to a multiple of 100
// That way installing all three components would yield 300%
// When one component is done the bar will be filled by 33%
if (field(QLatin1String("installation.new")).toBool() == true) {
installProgressBar->setMaximum((components.count() * 100));
} else {
if (components.contains(QLatin1String("Tribunal"))
&& !mWizard->mInstallations[path].hasTribunal)
installProgressBar->setMaximum(100);
if (components.contains(QLatin1String("Bloodmoon"))
&& !mWizard->mInstallations[path].hasBloodmoon)
installProgressBar->setMaximum(installProgressBar->maximum() + 100);
}
startInstallation();
}
void Wizard::InstallationPage::startInstallation()
{
QStringList components(field(QLatin1String("installation.components")).toStringList());
QString path(field(QLatin1String("installation.path")).toString());
mThread = new QThread();
mUnshield = new UnshieldWorker();
@ -88,6 +54,54 @@ void Wizard::InstallationPage::startInstallation()
connect(mUnshield, SIGNAL(requestFileDialog(Wizard::Component)),
this, SLOT(showFileDialog(Wizard::Component)), Qt::QueuedConnection);
}
Wizard::InstallationPage::~InstallationPage()
{
qDebug() << "stop!";
if (mThread->isRunning()) {
mUnshield->stopWorker();
mThread->wait();
}
delete mUnshield;
delete mThread;
}
void Wizard::InstallationPage::initializePage()
{
QString path(field(QLatin1String("installation.path")).toString());
QStringList components(field(QLatin1String("installation.components")).toStringList());
logTextEdit->appendPlainText(QString("Installing to %1").arg(path));
logTextEdit->appendPlainText(QString("Installing %1.").arg(components.join(", ")));
installProgressBar->setMinimum(0);
// Set the progressbar maximum to a multiple of 100
// That way installing all three components would yield 300%
// When one component is done the bar will be filled by 33%
if (field(QLatin1String("installation.new")).toBool() == true) {
installProgressBar->setMaximum((components.count() * 100));
} else {
if (components.contains(QLatin1String("Tribunal"))
&& !mWizard->mInstallations[path].hasTribunal)
installProgressBar->setMaximum(100);
if (components.contains(QLatin1String("Bloodmoon"))
&& !mWizard->mInstallations[path].hasBloodmoon)
installProgressBar->setMaximum(installProgressBar->maximum() + 100);
}
startInstallation();
}
void Wizard::InstallationPage::startInstallation()
{
QStringList components(field(QLatin1String("installation.components")).toStringList());
QString path(field(QLatin1String("installation.path")).toString());
if (field(QLatin1String("installation.new")).toBool() == true)
{

@ -19,7 +19,8 @@ namespace Wizard
{
Q_OBJECT
public:
InstallationPage(MainWizard *wizard);
InstallationPage(QWidget *parent);
~InstallationPage();
int nextId() const;
virtual bool isComplete() const;

@ -6,11 +6,12 @@
#include "mainwizard.hpp"
Wizard::InstallationTargetPage::InstallationTargetPage(MainWizard *wizard, const Files::ConfigurationManager &cfg) :
QWizardPage(wizard),
mWizard(wizard),
Wizard::InstallationTargetPage::InstallationTargetPage(QWidget *parent, const Files::ConfigurationManager &cfg) :
QWizardPage(parent),
mCfgMgr(cfg)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
registerField(QLatin1String("installation.path*"), targetLineEdit);

@ -18,7 +18,7 @@ namespace Wizard
{
Q_OBJECT
public:
InstallationTargetPage(MainWizard *wizard, const Files::ConfigurationManager &cfg);
InstallationTargetPage(QWidget *parent, const Files::ConfigurationManager &cfg);
int nextId() const;
virtual bool validatePage();

@ -2,10 +2,11 @@
#include "mainwizard.hpp"
Wizard::IntroPage::IntroPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::IntroPage::IntroPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
setPixmap(QWizard::WatermarkPixmap, QPixmap(QLatin1String(":/images/intropage-background.png")));
}

@ -13,7 +13,7 @@ namespace Wizard
{
Q_OBJECT
public:
IntroPage(MainWizard *wizard);
IntroPage(QWidget *parent);
int nextId() const;

@ -4,10 +4,11 @@
#include <QDebug>
Wizard::LanguageSelectionPage::LanguageSelectionPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::LanguageSelectionPage::LanguageSelectionPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
registerField(QLatin1String("installation.language"), languageComboBox);

@ -13,7 +13,7 @@ namespace Wizard
{
Q_OBJECT
public:
LanguageSelectionPage(MainWizard *wizard);
LanguageSelectionPage(QWidget *parent);
int nextId() const;

@ -1,7 +1,5 @@
#include "mainwizard.hpp"
#include <components/process/processinvoker.hpp>
#include <QDebug>
#include <QTime>
@ -25,7 +23,9 @@ using namespace Process;
Wizard::MainWizard::MainWizard(QWidget *parent) :
mGameSettings(mCfgMgr),
QWizard(parent)
QWizard(parent),
mError(false),
mInstallations()
{
#ifndef Q_OS_MAC
setWizardStyle(QWizard::ModernStyle);
@ -37,11 +37,26 @@ Wizard::MainWizard::MainWizard(QWidget *parent) :
setWindowIcon(QIcon(QLatin1String(":/images/openmw-wizard.png")));
setMinimumWidth(550);
// This prevents initializePage() being called multiple times
setOption(QWizard::IndependentPages);
// Set the property for comboboxes to the text instead of index
setDefaultProperty("QComboBox", "currentText", "currentIndexChanged");
setDefaultProperty("ComponentListWidget", "mCheckedItems", "checkedItemsChanged");
mImporterInvoker = new ProcessInvoker();
connect(mImporterInvoker->getProcess(), SIGNAL(started()),
this, SLOT(importerStarted()));
connect(mImporterInvoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(importerFinished(int,QProcess::ExitStatus)));
mLogError = tr("<html><head/><body><p><b>Could not open %1 for writing</b></p> \
<p>Please make sure you have the right permissions \
and try again.</p></body></html>");
setupLog();
setupGameSettings();
setupLauncherSettings();
@ -49,44 +64,58 @@ Wizard::MainWizard::MainWizard(QWidget *parent) :
setupPages();
}
Wizard::MainWizard::~MainWizard()
{
delete mImporterInvoker;
}
void Wizard::MainWizard::setupLog()
{
QString logPath(QString::fromUtf8(mCfgMgr.getLogPath().string().c_str()));
logPath.append(QLatin1String("wizard.log"));
QString message(tr("<html><head/><body><p><b>Could not open %1 for writing</b></p> \
<p>Please make sure you have the right permissions \
and try again.</p></body></html>"));
QFile *file = new QFile(logPath);
QFile file(logPath);
if (!file->open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Append)) {
if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Error opening Wizard log file"));
msgBox.setIcon(QMessageBox::Critical);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setText(message.arg(file->fileName()));
msgBox.setText(mLogError.arg(file.fileName()));
msgBox.exec();
return qApp->quit();
}
qDebug() << logPath;
mLog = new QTextStream(file);
mLog->setCodec(QTextCodec::codecForName("UTF-8"));
addLogText(QString("Started OpenMW Wizard on %1").arg(QDateTime::currentDateTime().toString()));
//addLogText(QLatin1String("test test 123 test"));
qDebug() << logPath;
}
void Wizard::MainWizard::addLogText(const QString &text)
{
QString logPath(QString::fromUtf8(mCfgMgr.getLogPath().string().c_str()));
logPath.append(QLatin1String("wizard.log"));
QFile file(logPath);
qDebug() << "AddLogText called! " << text;
if (!text.isEmpty()) {
qDebug() << "logging " << text;
*mLog << text << endl;
if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("Error opening Wizard log file"));
msgBox.setIcon(QMessageBox::Critical);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setText(mLogError.arg(file.fileName()));
msgBox.exec();
return qApp->quit();
}
if (!file.isSequential())
file.seek(file.size());
QTextStream out(&file);
if (!text.isEmpty())
out << text << endl;
// file.close();
}
@ -246,16 +275,8 @@ void Wizard::MainWizard::runSettingsImporter()
arguments.append(QLatin1String("--cfg"));
arguments.append(userPath + QLatin1String("openmw.cfg"));
ProcessInvoker *invoker = new ProcessInvoker(this);
if (!invoker->startProcess(QLatin1String("mwiniimport"), arguments, false))
return qApp->quit();;
connect(invoker->getProcess(), SIGNAL(started()),
this, SLOT(importerStarted()));
connect(invoker->getProcess(), SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(importerFinished(int,QProcess::ExitStatus)));
if (!mImporterInvoker->startProcess(QLatin1String("mwiniimport"), arguments, false))
return qApp->quit();
// Re-read the game settings
// setupGameSettings();
@ -305,6 +326,7 @@ void Wizard::MainWizard::setupPages()
setPage(Page_Import, new ImportPage(this));
setPage(Page_Conclusion, new ConclusionPage(this));
setStartId(Page_Intro);
}
void Wizard::MainWizard::importerStarted()

@ -5,6 +5,8 @@
#include <QWizard>
#include <QMap>
#include <components/process/processinvoker.hpp>
#include <components/files/configurationmanager.hpp>
#include <components/config/gamesettings.hpp>
#include <components/config/launchersettings.hpp>
@ -37,6 +39,7 @@ namespace Wizard
};
MainWizard(QWidget *parent = 0);
~MainWizard();
bool findFiles(const QString &name, const QString &path);
void addInstallation(const QString &path);
@ -46,6 +49,8 @@ namespace Wizard
Files::ConfigurationManager mCfgMgr;
Process::ProcessInvoker *mImporterInvoker;
bool mError;
public slots:
@ -64,7 +69,7 @@ namespace Wizard
Config::GameSettings mGameSettings;
Config::LauncherSettings mLauncherSettings;
QTextStream *mLog;
QString mLogError;
private slots:

@ -2,10 +2,11 @@
#include <QDebug>
#include "mainwizard.hpp"
Wizard::MethodSelectionPage::MethodSelectionPage(MainWizard *wizard) :
QWizardPage(wizard),
mWizard(wizard)
Wizard::MethodSelectionPage::MethodSelectionPage(QWidget *parent) :
QWizardPage(parent)
{
mWizard = qobject_cast<MainWizard*>(parent);
setupUi(this);
registerField(QLatin1String("installation.new"), newLocationRadioButton);

@ -13,7 +13,7 @@ namespace Wizard
{
Q_OBJECT
public:
MethodSelectionPage(MainWizard *wizard);
MethodSelectionPage(QWidget *parent);
int nextId() const;

@ -35,6 +35,8 @@ Wizard::UnshieldWorker::UnshieldWorker(QObject *parent) :
mTribunalDone = false;
mBloodmoonDone = false;
mStopped = false;
qRegisterMetaType<Wizard::Component>("Wizard::Component");
}
@ -42,6 +44,13 @@ Wizard::UnshieldWorker::~UnshieldWorker()
{
}
void Wizard::UnshieldWorker::stopWorker()
{
mMutex.lock();
mStopped = true;
mMutex.unlock();
}
void Wizard::UnshieldWorker::setInstallComponent(Wizard::Component component, bool install)
{
QWriteLocker writeLock(&mLock);
@ -781,6 +790,13 @@ bool Wizard::UnshieldWorker::extractCab(const QString &cabFile, const QString &d
for (size_t j=group->first_file; j<=group->last_file; ++j)
{
if (mStopped) {
qDebug() << "We're asked to stop!";
unshield_close(unshield);
return true;
}
if (unshield_file_is_valid(unshield, j)) {
success = extractFile(unshield, destination, group->name, j, counter);
@ -789,6 +805,8 @@ bool Wizard::UnshieldWorker::extractCab(const QString &cabFile, const QString &d
emit error(tr("Failed to extract %1.").arg(name),
tr("Complete path: %1").arg(destination + QDir::separator() + name));
unshield_close(unshield);
return false;
}
@ -892,11 +910,14 @@ bool Wizard::UnshieldWorker::findInCab(const QString &fileName, const QString &c
if (unshield_file_is_valid(unshield, j)) {
QString current(QString::fromUtf8(unshield_file_name(unshield, j)));
if (current.toLower() == fileName.toLower())
if (current.toLower() == fileName.toLower()) {
unshield_close(unshield);
return true; // File is found!
}
}
}
}
unshield_close(unshield);
return false;
}

@ -30,6 +30,8 @@ namespace Wizard
UnshieldWorker(QObject *parent = 0);
~UnshieldWorker();
void stopWorker();
void setInstallComponent(Wizard::Component component, bool install);
void setDiskPath(const QString &path);
@ -92,6 +94,8 @@ namespace Wizard
bool mTribunalDone;
bool mBloodmoonDone;
bool mStopped;
QString mPath;
QString mIniPath;
QString mDiskPath;

@ -8,10 +8,17 @@
#include <QDir>
#include <QDebug>
Process::ProcessInvoker::ProcessInvoker(QWidget *parent)
Process::ProcessInvoker::ProcessInvoker()
{
mProcess = new QProcess(this);
connect(mProcess, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(processError(QProcess::ProcessError)));
connect(mProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(processFinished(int,QProcess::ExitStatus)));
mName = QString();
mArguments = QStringList();
}
@ -48,13 +55,6 @@ QProcess* Process::ProcessInvoker::getProcess()
bool Process::ProcessInvoker::startProcess(const QString &name, const QStringList &arguments, bool detached)
{
// mProcess = new QProcess(this);
connect(mProcess, SIGNAL(error(QProcess::ProcessError)),
this, SLOT(processError(QProcess::ProcessError)));
connect(mProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
this, SLOT(processFinished(int,QProcess::ExitStatus)));
mName = name;
mArguments = arguments;

@ -13,7 +13,7 @@ namespace Process
public:
ProcessInvoker(QWidget *parent = 0);
ProcessInvoker();
~ProcessInvoker();
// void setProcessName(const QString &name);

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>510</width>
<height>324</height>
<width>508</width>
<height>322</height>
</rect>
</property>
<property name="windowTitle">
@ -45,6 +45,9 @@
<property name="text">
<string>Import add-on and plugin selection</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>

Loading…
Cancel
Save