Merge with develop

This commit is contained in:
kervala 2016-05-29 20:38:55 +02:00
parent ac448eac18
commit c4f5512b24
17 changed files with 671 additions and 59 deletions

View file

@ -211,13 +211,18 @@ int main(int argc, char **argv)
{
std::string currentPath = CPath::getApplicationDirectory("Ryzom");
// create parent directory
if (!CFile::isExists(currentPath)) CFile::createDirectory(currentPath);
// append profile ID to directory
if (Args.haveArg("p"))
{
currentPath = NLMISC::CPath::standardizePath(currentPath) + Args.getArg("p").front();
if (!CFile::isExists(currentPath)) CFile::createDirectory(currentPath);
}
CPath::setCurrentPath(currentPath);
if (!CPath::setCurrentPath(currentPath)) return 1;
}
#ifdef TEST_CRASH_COUNTER

View file

@ -1537,15 +1537,6 @@ void postlogInit()
ProgressBar.newMessage ( ClientCfg.buildLoadingString(nmsg) );
if(ClientCfg.SoundOn)
{
// tmp fix : it seems that, at this point, if the bg downloader window has focus and
// not the Ryzom one, then sound init fails
/*#ifdef NL_OS_WINDOWS
HWND hWnd = Driver->getDisplay ();
nlassert (hWnd);
ShowWindow(hWnd, SW_RESTORE);
SetForegroundWindow(hWnd);
#endif*/
// bg downloader not used anymore anyways
SoundMngr = new CSoundManager(&ProgressBar);
try
{
@ -1554,7 +1545,6 @@ void postlogInit()
catch(const Exception &e)
{
nlwarning("init : Error when creating 'SoundMngr' : %s", e.what());
// leak the alocated sound manager...
delete SoundMngr;
SoundMngr = NULL;
}

View file

@ -29,7 +29,7 @@ const CProfile NoProfile;
CConfigFile *CConfigFile::s_instance = NULL;
CConfigFile::CConfigFile(QObject *parent):QObject(parent), m_defaultServerIndex(0), m_defaultProfileIndex(0), m_use64BitsClient(false)
CConfigFile::CConfigFile(QObject *parent):QObject(parent), m_defaultServerIndex(0), m_defaultProfileIndex(0), m_use64BitsClient(false), m_shouldUninstallOldClient(true)
{
s_instance = this;
@ -56,7 +56,8 @@ bool CConfigFile::load(const QString &filename)
m_language = settings.value("language", m_language).toString();
m_srcDirectory = settings.value("source_directory").toString();
m_installationDirectory = settings.value("installation_directory").toString();
m_use64BitsClient = settings.value("use_64bits_client").toBool();
m_use64BitsClient = settings.value("use_64bits_client", true).toBool();
m_shouldUninstallOldClient = settings.value("should_uninstall_old_client", true).toBool();
settings.endGroup();
settings.beginGroup("product");
@ -149,6 +150,7 @@ bool CConfigFile::save() const
settings.setValue("source_directory", m_srcDirectory);
settings.setValue("installation_directory", m_installationDirectory);
settings.setValue("use_64bits_client", m_use64BitsClient);
settings.setValue("should_uninstall_old_client", m_shouldUninstallOldClient);
settings.endGroup();
settings.beginGroup("product");
@ -363,6 +365,16 @@ void CConfigFile::setUse64BitsClient(bool on)
m_use64BitsClient = on;
}
bool CConfigFile::shouldUninstallOldClient() const
{
return m_shouldUninstallOldClient;
}
void CConfigFile::setShouldUninstallOldClient(bool on)
{
m_shouldUninstallOldClient = on;
}
QString CConfigFile::expandVariables(const QString &str) const
{
QString res = str;
@ -710,6 +722,11 @@ CConfigFile::InstallationStep CConfigFile::getNextStep() const
return CopyInstaller;
}
if (m_shouldUninstallOldClient && !getSrcServerDirectory().isEmpty() && QFile::exists(getSrcServerDirectory() + "/Uninstall.exe"))
{
return UninstallOldClient;
}
// no default profile
if (profile.id.isEmpty())
{

View file

@ -93,6 +93,7 @@ public:
CleanFiles,
ExtractBnpClient,
CopyInstaller,
UninstallOldClient,
CreateProfile,
CreateShortcuts,
CreateAddRemoveEntry,
@ -164,6 +165,9 @@ public:
bool use64BitsClient() const;
void setUse64BitsClient(bool on);
bool shouldUninstallOldClient() const;
void setShouldUninstallOldClient(bool on);
QString expandVariables(const QString &str) const;
QString getClientArch() const;
@ -192,6 +196,7 @@ private:
QString m_installationDirectory;
QString m_srcDirectory;
bool m_use64BitsClient;
bool m_shouldUninstallOldClient;
QString m_language;
QString m_defaultConfigPath;

View file

@ -19,11 +19,9 @@
#include "configfile.h"
#include "migratewizarddialog.h"
#include "installwizarddialog.h"
#include "uninstallwizarddialog.h"
#include "operationdialog.h"
#include "nel/misc/path.h"
#include "nel/misc/ucstring.h"
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@ -58,8 +56,6 @@ int main(int argc, char *argv[])
QApplication app(argc, argv);
// TODO: parameters -u (uinstall) and -s (silent)
QApplication::setApplicationName("Ryzom");
QApplication::setApplicationVersion(RYZOM_VERSION);
QApplication::setWindowIcon(QIcon(":/icons/ryzom.ico"));
@ -90,46 +86,92 @@ int main(int argc, char *argv[])
return 1;
}
bool displayMainWindow = true;
// use product name from installer.ini
if (!config.getProductName().isEmpty()) QApplication::setApplicationName(config.getProductName());
// define commandline arguments
QCommandLineParser parser;
// parser.setApplicationDescription(DESCRIPTION);
parser.addHelpOption();
parser.addVersionOption();
// root, username and password are optional because they can be saved in settings file
QCommandLineOption uninstallOption(QStringList() << "u" << "uninstall", QApplication::tr("Uninstall"));
parser.addOption(uninstallOption);
QCommandLineOption silentOption(QStringList() << "s" << "silent", QApplication::tr("Silent mode"));
parser.addOption(silentOption);
// process the actual command line arguments given by the user
parser.process(app);
if (parser.isSet(uninstallOption))
{
QVector<int> selectedServers;
QVector<int> selectedProfiles;
bool selectedInstaller = true;
// add all servers by default
for (int i = 0; i < config.getServersCount(); ++i)
{
selectedServers << i;
}
// show uninstall wizard dialog if not in silent mode
if (!parser.isSet(silentOption))
{
CUninstallWizardDialog dialog;
if (dialog.exec())
{
selectedServers = dialog.getSelectedServers();
selectedProfiles = dialog.getSelectedProfiles();
selectedInstaller = dialog.isInstallerSelected();
}
}
{
COperationDialog dialog;
dialog.setOperation(COperationDialog::OperationUninstall);
// TODO: set all components to uninstall
if (dialog.exec()) return 0;
}
return 1;
}
if (step == CConfigFile::ShowMigrateWizard)
{
CMigrateWizardDialog dialog;
if (!dialog.exec()) displayMainWindow = false;
if (!dialog.exec()) return 1;
step = config.getNextStep();
}
else if (step == CConfigFile::ShowInstallWizard)
{
CInstallWizardDialog dialog;
if (!dialog.exec()) displayMainWindow = false;
}
if (!dialog.exec()) return 1;
if (displayMainWindow)
{
step = config.getNextStep();
}
if (step != CConfigFile::Done)
{
COperationDialog dialog;
dialog.setOperation(config.getSrcServerDirectory().isEmpty() ? COperationDialog::OperationInstall: COperationDialog::OperationMigrate);
if (!dialog.exec()) displayMainWindow = false;
}
}
if (!dialog.exec()) return 1;
if (displayMainWindow)
{
step = config.getNextStep();
}
if (step == CConfigFile::Done)
{
CMainWindow mainWindow;
mainWindow.show();
return QApplication::exec();
}
}
return 0;
}

View file

@ -18,6 +18,8 @@
#include "mainwindow.h"
#include "downloader.h"
#include "profilesdialog.h"
#include "uninstallwizarddialog.h"
#include "operationdialog.h"
#include "configfile.h"
#include "config.h"
#include "profilesmodel.h"
@ -38,6 +40,7 @@ CMainWindow::CMainWindow():QMainWindow()
connect(m_downloader, SIGNAL(htmlPageContent(QString)), SLOT(onHtmlPageContent(QString)));
connect(actionProfiles, SIGNAL(triggered()), SLOT(onProfiles()));
connect(actionUninstall, SIGNAL(triggered()), SLOT(onUninstall()));
connect(playButton, SIGNAL(clicked()), SLOT(onPlayClicked()));
connect(configureButton, SIGNAL(clicked()), SLOT(onConfigureClicked()));
@ -84,7 +87,7 @@ void CMainWindow::onPlayClicked()
QStringList arguments;
arguments << "-p";
arguments << QString::number(profileIndex);
arguments << profile.arguments;
arguments << profile.arguments.split(' ');
bool started = QProcess::startDetached(profile.executable, arguments);
@ -116,7 +119,7 @@ void CMainWindow::onConfigureClicked()
void CMainWindow::onProfiles()
{
CProfilesDialog dialog;
CProfilesDialog dialog(this);
if (dialog.exec())
{
@ -124,6 +127,20 @@ void CMainWindow::onProfiles()
}
}
void CMainWindow::onUninstall()
{
CUninstallWizardDialog dialog(this);
if (dialog.exec())
{
COperationDialog dialog(&dialog);
dialog.setOperation(COperationDialog::OperationUninstall);
dialog.exec();
}
}
void CMainWindow::onAbout()
{
QString br("<br>");

View file

@ -42,6 +42,7 @@ public slots:
void onConfigureClicked();
void onProfiles();
void onUninstall();
void onAbout();
void onAboutQt();

View file

@ -41,7 +41,7 @@
#define new DEBUG_NEW
#endif
COperationDialog::COperationDialog():QDialog(), m_aborting(false)
COperationDialog::COperationDialog(QWidget *parent):QDialog(parent), m_aborting(false), m_operation(OperationNone)
{
setupUi(this);
@ -84,7 +84,33 @@ COperationDialog::~COperationDialog()
{
}
void COperationDialog::setOperation(Operation operation)
{
m_operation = operation;
}
void COperationDialog::processNextStep()
{
switch (m_operation)
{
case OperationMigrate:
processMigrateNextStep();
break;
case OperationInstall:
processInstallNextStep();
break;
case OperationUninstall:
processUninstallNextStep();
break;
default:
break;
}
}
void COperationDialog::processMigrateNextStep()
{
CConfigFile *config = CConfigFile::getInstance();
@ -132,16 +158,20 @@ void COperationDialog::processNextStep()
QtConcurrent::run(this, &COperationDialog::copyProfileFiles);
break;
case CConfigFile::CleanFiles:
QtConcurrent::run(this, &COperationDialog::cleanFiles);
break;
case CConfigFile::ExtractBnpClient:
QtConcurrent::run(this, &COperationDialog::extractBnpClient);
break;
case CConfigFile::CopyInstaller:
QtConcurrent::run(this, &COperationDialog::copyIntaller);
QtConcurrent::run(this, &COperationDialog::copyInstaller);
break;
case CConfigFile::CleanFiles:
QtConcurrent::run(this, &COperationDialog::cleanFiles);
case CConfigFile::UninstallOldClient:
uninstallOldClient();
break;
case CConfigFile::CreateProfile:
@ -166,6 +196,14 @@ void COperationDialog::processNextStep()
}
}
void COperationDialog::processInstallNextStep()
{
}
void COperationDialog::processUninstallNextStep()
{
}
void COperationDialog::showEvent(QShowEvent *e)
{
#if defined(Q_OS_WIN32) && defined(QT_WINEXTRAS_LIB)
@ -415,7 +453,7 @@ void COperationDialog::extractBnpClient()
emit done();
}
void COperationDialog::copyIntaller()
void COperationDialog::copyInstaller()
{
CConfigFile *config = CConfigFile::getInstance();
@ -462,6 +500,44 @@ void COperationDialog::copyIntaller()
emit done();
}
void COperationDialog::uninstallOldClient()
{
#ifdef Q_OS_WIN
#ifdef Q_OS_WIN64
// use WOW6432Node in 64 bits (64 bits OS and 64 bits Installer) because Ryzom old installer was in 32 bits
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ryzom", QSettings::NativeFormat);
#else
QSettings settings("HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ryzom", QSettings::NativeFormat);
#endif
// check if Ryzom 2.1.0 is installed
if (settings.contains("UninstallString"))
{
QString uninstaller = settings.value("UninstallString").toString();
if (!uninstaller.isEmpty() && QFile::exists(uninstaller))
{
QMessageBox::StandardButtons button = QMessageBox::question(this, tr("Uninstall old client"), tr("An old version of Ryzom has been detected on this system, would you like to uninstall it to save space disk?"));
if (button == QMessageBox::Yes)
{
CConfigFile::getInstance()->setShouldUninstallOldClient(true);
QDesktopServices::openUrl(QUrl::fromLocalFile(uninstaller));
}
else
{
// don't ask this question anymore
CConfigFile::getInstance()->setShouldUninstallOldClient(false);
}
}
}
#endif
emit done();
}
void COperationDialog::cleanFiles()
{
CConfigFile *config = CConfigFile::getInstance();

View file

@ -35,9 +35,19 @@ class COperationDialog : public QDialog, public Ui::OperationDialog, public IOpe
Q_OBJECT
public:
COperationDialog();
COperationDialog(QWidget *parent = NULL);
virtual ~COperationDialog();
enum Operation
{
OperationNone,
OperationMigrate,
OperationInstall,
OperationUninstall
};
void setOperation(Operation operation);
public slots:
void onAbortClicked();
@ -80,15 +90,19 @@ protected:
void closeEvent(QCloseEvent *e);
void processNextStep();
void processMigrateNextStep();
void processInstallNextStep();
void processUninstallNextStep();
// operations
void downloadData();
void downloadClient();
void copyServerFiles();
void copyProfileFiles();
void extractBnpClient();
void copyIntaller();
void cleanFiles();
void extractBnpClient();
void copyInstaller();
void uninstallOldClient();
bool createDefaultProfile();
bool createDefaultShortcuts();
bool createAddRemoveEntry();
@ -112,6 +126,8 @@ protected:
QMutex m_abortingMutex;
bool m_aborting;
Operation m_operation;
};
#endif

View file

@ -23,7 +23,7 @@
#define new DEBUG_NEW
#endif
CProfilesDialog::CProfilesDialog():QDialog(), m_currentProfileIndex(-1)
CProfilesDialog::CProfilesDialog(QWidget *parent):QDialog(parent), m_currentProfileIndex(-1)
{
setupUi(this);

View file

@ -33,7 +33,7 @@ class CProfilesDialog : public QDialog, public Ui::ProfilesDialog
Q_OBJECT
public:
CProfilesDialog();
CProfilesDialog(QWidget *parent = NULL);
virtual ~CProfilesDialog();
private slots:

View file

@ -0,0 +1,217 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdpch.h"
#include "uninstallwizarddialog.h"
#include "configfile.h"
#include "utils.h"
#include "nel/misc/system_info.h"
#include "nel/misc/common.h"
#ifdef DEBUG_NEW
#define new DEBUG_NEW
#endif
CUninstallWizardDialog::CUninstallWizardDialog(QWidget *parent):QDialog(parent), m_installerIndex(-1)
{
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
setupUi(this);
CConfigFile *config = CConfigFile::getInstance();
int serverCount = config->getServersCount();
QStandardItemModel *model = new QStandardItemModel(0, 2, this);
QStringList columns;
columns << tr("Component");
columns << tr("Size");
model->setHorizontalHeaderLabels(columns);
// clients
for (int row = 0; row < serverCount; ++row)
{
const CServer &server = config->getServer(row);
if (QFile::exists(config->getInstallationDirectory() + "/" + server.id))
{
m_serversIndices[row] = model->rowCount();
QStandardItem *item = new QStandardItem(tr("Client for %1").arg(server.name));
item->setCheckable(true);
item->setCheckState(Qt::Checked);
model->appendRow(item);
}
}
int profilesCount = config->getProfilesCount();
// profiles
for (int row = 0; row < profilesCount; ++row)
{
m_profilesIndices[row] = model->rowCount();
const CProfile &profile = config->getProfile(row);
QStandardItem *item = new QStandardItem(tr("Profile #%1: %2").arg(profile.id).arg(profile.name));
item->setCheckable(true);
model->appendRow(item);
}
m_installerIndex = model->rowCount();
QStandardItem *item = new QStandardItem(tr("Ryzom Installer"));
item->setCheckable(true);
item->setCheckState(Qt::Checked);
model->appendRow(item);
componentsTreeView->setModel(model);
componentsTreeView->resizeColumnToContents(0);
connect(uninstallButton, SIGNAL(clicked()), SLOT(accept()));
connect(quitButton, SIGNAL(clicked()), SLOT(reject()));
connect(model, SIGNAL(itemChanged(QStandardItem *)), SLOT(onItemChanged(QStandardItem *)));
adjustSize();
QtConcurrent::run(this, &CUninstallWizardDialog::updateSizes);
updateButtons();
}
CUninstallWizardDialog::~CUninstallWizardDialog()
{
}
QVector<int> CUninstallWizardDialog::getSelectedServers() const
{
QVector<int> res;
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(componentsTreeView->model());
if (model == NULL) return res;
QMap<int, int>::const_iterator it = m_serversIndices.begin(), iend = m_serversIndices.end();
while (it != iend)
{
QStandardItem *item = model->item(m_installerIndex);
if (item && item->checkState() == Qt::Checked) res << it.value();
++it;
}
return res;
}
QVector<int> CUninstallWizardDialog::getSelectedProfiles() const
{
QVector<int> res;
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(componentsTreeView->model());
if (model == NULL) return res;
QMap<int, int>::const_iterator it = m_profilesIndices.begin(), iend = m_profilesIndices.end();
while (it != iend)
{
QStandardItem *item = model->item(m_installerIndex);
if (item && item->checkState() == Qt::Checked) res << it.value();
++it;
}
return res;
}
bool CUninstallWizardDialog::isInstallerSelected() const
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(componentsTreeView->model());
if (model == NULL) return false;
QStandardItem *item = model->item(m_installerIndex);
return item && item->checkState() == Qt::Checked;
}
void CUninstallWizardDialog::accept()
{
QDialog::accept();
}
void CUninstallWizardDialog::onItemChanged(QStandardItem * /* item */)
{
updateButtons();
}
void CUninstallWizardDialog::updateSizes()
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(componentsTreeView->model());
CConfigFile *config = CConfigFile::getInstance();
// clients
QMap<int, int>::const_iterator it = m_serversIndices.begin(), iend = m_serversIndices.end();
while(it != iend)
{
const CServer &server = config->getServer(it.key());
qint64 bytes = getDirectorySize(config->getInstallationDirectory() + "/" + server.id);
QStandardItem *item = new QStandardItem(qBytesToHumanReadable(bytes));
model->setItem(it.value(), 1, item);
++it;
}
// profiles
it = m_profilesIndices.begin(), iend = m_profilesIndices.end();
while (it != iend)
{
const CProfile &profile = config->getProfile(it.key());
qint64 bytes = getDirectorySize(config->getProfileDirectory() + "/" + profile.id);
QStandardItem *item = new QStandardItem(qBytesToHumanReadable(bytes));
model->setItem(it.value(), 1, item);
++it;
}
componentsTreeView->resizeColumnToContents(1);
}
void CUninstallWizardDialog::updateButtons()
{
QStandardItemModel *model = qobject_cast<QStandardItemModel*>(componentsTreeView->model());
int checkedCount = 0;
// Uninstall button should be enabled only if at least one component is selected
for (int i = 0; i < model->rowCount(); ++i)
{
if (model->item(i)->checkState() == Qt::Checked) ++checkedCount;
}
uninstallButton->setEnabled(checkedCount > 0);
}

View file

@ -0,0 +1,56 @@
// Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
// Copyright (C) 2010 Winch Gate Property Limited
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program 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 Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#ifndef UNINSTALLWIZARDDIALOG_H
#define UNINSTALLWIZARDDIALOG_H
#include "ui_uninstallwizard.h"
/**
* Wizard displayed at first launch, that asks user to choose source and destination directories.
*
* \author Cedric 'Kervala' OCHS
* \date 2016
*/
class CUninstallWizardDialog : public QDialog, public Ui::UninstallWizardDialog
{
Q_OBJECT
public:
CUninstallWizardDialog(QWidget *parent = NULL);
virtual ~CUninstallWizardDialog();
QVector<int> getSelectedServers() const;
QVector<int> getSelectedProfiles() const;
bool isInstallerSelected() const;
private slots:
void accept();
void onItemChanged(QStandardItem *item);
private:
void updateSizes();
void updateButtons();
// key is original ID, value is row index
QMap<int, int> m_serversIndices;
QMap<int, int> m_profilesIndices;
int m_installerIndex;
};
#endif

View file

@ -34,6 +34,33 @@ QString qBytesToHumanReadable(qint64 bytes)
return QString::fromUtf8(NLMISC::bytesToHumanReadable(bytes).c_str());
}
qint64 getDirectorySize(const QString &directory)
{
qint64 size = 0;
QDir dir(directory);
if (dir.exists())
{
QFileInfoList list = dir.entryInfoList(QDir::Files | QDir::Dirs | QDir::Hidden | QDir::NoSymLinks | QDir::NoDotAndDotDot);
for (int i = 0; i < list.size(); ++i)
{
QFileInfo fileInfo = list.at(i);
if (fileInfo.isDir())
{
size += getDirectorySize(fileInfo.absoluteFilePath());
}
else
{
size += fileInfo.size();
}
}
}
return size;
}
QString qFromUtf8(const std::string &str)
{
return QString::fromUtf8(str.c_str());

View file

@ -30,6 +30,8 @@
QString qBytesToHumanReadable(qint64 bytes);
qint64 getDirectorySize(const QString &directory);
// Convert a UTF-8 string to QString
QString qFromUtf8(const std::string &str);

View file

@ -2,6 +2,14 @@
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>547</width>
<height>386</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -117,6 +125,7 @@ p, li { white-space: pre-wrap; }
</property>
<addaction name="actionProfiles"/>
<addaction name="actionDirectories"/>
<addaction name="actionUninstall"/>
<addaction name="separator"/>
<addaction name="actionQuit"/>
</widget>
@ -155,6 +164,11 @@ p, li { white-space: pre-wrap; }
<string>&amp;Quit</string>
</property>
</action>
<action name="actionUninstall">
<property name="text">
<string>&amp;Uninstall</string>
</property>
</action>
</widget>
<resources>
<include location="../res/resources.qrc"/>

View file

@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>UninstallWizardDialog</class>
<widget class="QDialog" name="UninstallWizardDialog">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>415</width>
<height>365</height>
</rect>
</property>
<property name="windowTitle">
<string>Ryzom Installer</string>
</property>
<property name="modal">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="dialogLayout">
<item>
<layout class="QHBoxLayout" name="mainLayout">
<item>
<widget class="QLabel" name="headerBitmap">
<property name="pixmap">
<pixmap resource="../res/resources.qrc">:/images/background.png</pixmap>
</property>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="contentLayout" stretch="0,0,0,0">
<item>
<widget class="QLabel" name="messageLabel">
<property name="text">
<string>You're about to uninstall some or all components of Ryzom. Please check each component you want to remove (warning, it can't be reverted).</string>
</property>
<property name="textFormat">
<enum>Qt::PlainText</enum>
</property>
<property name="alignment">
<set>Qt::AlignJustify|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="componentsSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="componentsLabel">
<property name="text">
<string>Components to remove</string>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="componentsTreeView">
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::NoSelection</enum>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="uniformRowHeights">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="buttonsLayout" stretch="1,0,0">
<item>
<spacer name="buttonsSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="uninstallButton">
<property name="text">
<string>Uninstall</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="quitButton">
<property name="text">
<string>Quit</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<resources>
<include location="../res/resources.qrc"/>
</resources>
<connections/>
</ui>