From c4f5512b24b2ce9791b29cb7d68dcc103d460990 Mon Sep 17 00:00:00 2001 From: kervala Date: Sun, 29 May 2016 20:38:55 +0200 Subject: [PATCH] Merge with develop --- code/ryzom/client/src/client.cpp | 15 +- code/ryzom/client/src/init.cpp | 10 - .../client/ryzom_installer/src/configfile.cpp | 21 +- .../client/ryzom_installer/src/configfile.h | 5 + .../tools/client/ryzom_installer/src/main.cpp | 102 +++++--- .../client/ryzom_installer/src/mainwindow.cpp | 21 +- .../client/ryzom_installer/src/mainwindow.h | 1 + .../ryzom_installer/src/operationdialog.cpp | 86 ++++++- .../ryzom_installer/src/operationdialog.h | 22 +- .../ryzom_installer/src/profilesdialog.cpp | 2 +- .../ryzom_installer/src/profilesdialog.h | 2 +- .../src/uninstallwizarddialog.cpp | 217 ++++++++++++++++++ .../src/uninstallwizarddialog.h | 56 +++++ .../client/ryzom_installer/src/utils.cpp | 27 +++ .../tools/client/ryzom_installer/src/utils.h | 2 + .../client/ryzom_installer/ui/mainwindow.ui | 14 ++ .../ryzom_installer/ui/uninstallwizard.ui | 127 ++++++++++ 17 files changed, 671 insertions(+), 59 deletions(-) create mode 100644 code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.cpp create mode 100644 code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.h create mode 100644 code/ryzom/tools/client/ryzom_installer/ui/uninstallwizard.ui diff --git a/code/ryzom/client/src/client.cpp b/code/ryzom/client/src/client.cpp index 255e8e95b..306e4dca6 100644 --- a/code/ryzom/client/src/client.cpp +++ b/code/ryzom/client/src/client.cpp @@ -211,13 +211,18 @@ int main(int argc, char **argv) { std::string currentPath = CPath::getApplicationDirectory("Ryzom"); - // append profile ID to directory - if (Args.haveArg("p")) - currentPath = NLMISC::CPath::standardizePath(currentPath) + Args.getArg("p").front(); - + // create parent directory if (!CFile::isExists(currentPath)) CFile::createDirectory(currentPath); - CPath::setCurrentPath(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); + } + + if (!CPath::setCurrentPath(currentPath)) return 1; } #ifdef TEST_CRASH_COUNTER diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index d96147da8..321fb8f1e 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -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; } diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp index 4574e00b5..91877eb9e 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp @@ -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()) { diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.h b/code/ryzom/tools/client/ryzom_installer/src/configfile.h index 7a8f2307c..aa3a61f8b 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.h +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.h @@ -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; diff --git a/code/ryzom/tools/client/ryzom_installer/src/main.cpp b/code/ryzom/tools/client/ryzom_installer/src/main.cpp index b0d0e90ec..ea4b87918 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/main.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/main.cpp @@ -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 selectedServers; + QVector 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; - - if (!dialog.exec()) displayMainWindow = false; - } } - - if (displayMainWindow) + + if (step != CConfigFile::Done) { + COperationDialog dialog; + dialog.setOperation(config.getSrcServerDirectory().isEmpty() ? COperationDialog::OperationInstall: COperationDialog::OperationMigrate); + + if (!dialog.exec()) return 1; + step = config.getNextStep(); - - if (step == CConfigFile::Done) - { - CMainWindow mainWindow; - mainWindow.show(); - - return QApplication::exec(); - } } - return 0; + CMainWindow mainWindow; + mainWindow.show(); + + return QApplication::exec(); } diff --git a/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp b/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp index ff70f3376..d28aaf5fc 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp @@ -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("
"); diff --git a/code/ryzom/tools/client/ryzom_installer/src/mainwindow.h b/code/ryzom/tools/client/ryzom_installer/src/mainwindow.h index bbc9121cd..fbd4ec1aa 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/mainwindow.h +++ b/code/ryzom/tools/client/ryzom_installer/src/mainwindow.h @@ -42,6 +42,7 @@ public slots: void onConfigureClicked(); void onProfiles(); + void onUninstall(); void onAbout(); void onAboutQt(); diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp index 736ed4cd0..df5cd7d8c 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp @@ -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(); diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h index f72b0a877..6876933a6 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h @@ -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 diff --git a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp index b9c3ef29a..04937c485 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp @@ -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); diff --git a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.h b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.h index 231ab554a..5116d0b7b 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.h +++ b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.h @@ -33,7 +33,7 @@ class CProfilesDialog : public QDialog, public Ui::ProfilesDialog Q_OBJECT public: - CProfilesDialog(); + CProfilesDialog(QWidget *parent = NULL); virtual ~CProfilesDialog(); private slots: diff --git a/code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.cpp new file mode 100644 index 000000000..7c5bdfab0 --- /dev/null +++ b/code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.cpp @@ -0,0 +1,217 @@ +// Ryzom - MMORPG Framework +// 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 . + +#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 CUninstallWizardDialog::getSelectedServers() const +{ + QVector res; + + QStandardItemModel *model = qobject_cast(componentsTreeView->model()); + if (model == NULL) return res; + + QMap::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 CUninstallWizardDialog::getSelectedProfiles() const +{ + QVector res; + + QStandardItemModel *model = qobject_cast(componentsTreeView->model()); + if (model == NULL) return res; + + QMap::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(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(componentsTreeView->model()); + + CConfigFile *config = CConfigFile::getInstance(); + + // clients + QMap::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(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); +} diff --git a/code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.h b/code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.h new file mode 100644 index 000000000..c5f911b33 --- /dev/null +++ b/code/ryzom/tools/client/ryzom_installer/src/uninstallwizarddialog.h @@ -0,0 +1,56 @@ +// Ryzom - MMORPG Framework +// 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 . + +#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 getSelectedServers() const; + QVector 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 m_serversIndices; + QMap m_profilesIndices; + + int m_installerIndex; +}; + +#endif diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp index 4cc50f7f0..b07db1e43 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp @@ -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()); diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.h b/code/ryzom/tools/client/ryzom_installer/src/utils.h index a20c93260..8e760b400 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.h +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.h @@ -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); diff --git a/code/ryzom/tools/client/ryzom_installer/ui/mainwindow.ui b/code/ryzom/tools/client/ryzom_installer/ui/mainwindow.ui index ed8188a1d..e687996b3 100644 --- a/code/ryzom/tools/client/ryzom_installer/ui/mainwindow.ui +++ b/code/ryzom/tools/client/ryzom_installer/ui/mainwindow.ui @@ -2,6 +2,14 @@ MainWindow + + + 0 + 0 + 547 + 386 + + 0 @@ -117,6 +125,7 @@ p, li { white-space: pre-wrap; } + @@ -155,6 +164,11 @@ p, li { white-space: pre-wrap; } &Quit + + + &Uninstall + + diff --git a/code/ryzom/tools/client/ryzom_installer/ui/uninstallwizard.ui b/code/ryzom/tools/client/ryzom_installer/ui/uninstallwizard.ui new file mode 100644 index 000000000..b8c0ee298 --- /dev/null +++ b/code/ryzom/tools/client/ryzom_installer/ui/uninstallwizard.ui @@ -0,0 +1,127 @@ + + + UninstallWizardDialog + + + Qt::ApplicationModal + + + + 0 + 0 + 415 + 365 + + + + Ryzom Installer + + + true + + + + + + + + :/images/background.png + + + + + + + + + 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). + + + Qt::PlainText + + + Qt::AlignJustify|Qt::AlignTop + + + true + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Components to remove + + + + + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::NoSelection + + + false + + + true + + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Uninstall + + + + + + + Quit + + + + + + + + + + + +