diff --git a/code/nel/src/misc/app_context.cpp b/code/nel/src/misc/app_context.cpp index 5206681f9..68ca720ed 100644 --- a/code/nel/src/misc/app_context.cpp +++ b/code/nel/src/misc/app_context.cpp @@ -18,6 +18,7 @@ #include "nel/misc/app_context.h" #include "nel/misc/dynloadlib.h" #include "nel/misc/command.h" +#include "nel/misc/system_utils.h" #include @@ -71,6 +72,9 @@ INelContext::~INelContext() CInstanceCounterLocalManager::releaseInstance(); + // uninit some systems stuff + CSystemUtils::uninit(); + _NelContext = NULL; *(_getInstance()) = NULL; } @@ -90,6 +94,9 @@ void INelContext::contextReady() // set numeric locale to C to avoid the use of decimal separators different of a dot char *locale = setlocale(LC_NUMERIC, "C"); + // init some systems stuff + CSystemUtils::init(); + // register any pending thinks // register local instance counter in the global instance counter manager diff --git a/code/ryzom/client/src/init.cpp b/code/ryzom/client/src/init.cpp index 666e86760..ffc6aa308 100644 --- a/code/ryzom/client/src/init.cpp +++ b/code/ryzom/client/src/init.cpp @@ -1154,7 +1154,6 @@ void prelogInit() Driver->setSwapVBLInterval(0); // initialize system utils class - CSystemUtils::init(); CSystemUtils::setWindow(Driver->getDisplay()); CLoginProgressPostThread::getInstance().step(CLoginStep(LoginStep_VideoModeSetupHighColor, "login_step_video_mode_setup_high_color")); diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp index 594bf9d1c..47315f6ac 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp @@ -32,11 +32,52 @@ QString CServer::getDirectory() const return CConfigFile::getInstance()->getInstallationDirectory() + "/" + id; } +QString CServer::getClientFullPath() const +{ + if (clientFilename.isEmpty()) return ""; + + return getDirectory() + "/" + clientFilename; +} + +QString CServer::getConfigurationFullPath() const +{ + if (configurationFilename.isEmpty()) return ""; + + return getDirectory() + "/" + configurationFilename; +} + QString CProfile::getDirectory() const { return CConfigFile::getInstance()->getProfileDirectory() + "/" + id; } +QString CProfile::getClientFullPath() const +{ + if (!executable.isEmpty()) return executable; + + const CServer &s = CConfigFile::getInstance()->getServer(server); + + return s.getClientFullPath(); +} + +QString CProfile::getClientDesktopLinkFullPath() const +{ +#ifdef Q_OS_WIN32 + return CConfigFile::getInstance()->getDesktopDirectory() + "/" + name + ".lnk"; +#else + return ""; +#endif +} + +QString CProfile::getClientMenuLinkFullPath() const +{ +#ifdef Q_OS_WIN32 + return CConfigFile::getInstance()->getMenuDirectory() + "/" + name + ".lnk"; +#else + return ""; +#endif +} + CConfigFile *CConfigFile::s_instance = NULL; CConfigFile::CConfigFile(QObject *parent):QObject(parent), m_defaultServerIndex(0), m_defaultProfileIndex(0), m_use64BitsClient(false), m_shouldUninstallOldClient(true) @@ -323,6 +364,16 @@ void CConfigFile::removeProfile(const QString &id) } } +QString CConfigFile::getDesktopDirectory() const +{ + return QStandardPaths::writableLocation(QStandardPaths::DesktopLocation); +} + +QString CConfigFile::getMenuDirectory() const +{ + return QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/" + QApplication::applicationName(); +} + bool CConfigFile::has64bitsOS() { return QSysInfo::currentCpuArchitecture() == "x86_64"; @@ -380,9 +431,28 @@ QString CConfigFile::getProfileDirectory() const QString CConfigFile::getSrcProfileDirectory() const { - if (QFile::exists(getSrcServerDirectory() + "/client.cfg")) return getSrcServerDirectory(); + QString filename = "client.cfg"; - return qFromUtf8(NLMISC::CPath::getApplicationDirectory("Ryzom")); + QStringList paths; + + // same path as client + paths << getSrcServerDirectory(); + + // profile path root + paths << getProfileDirectory(); + +#if !defined(Q_OS_WIN32) && !defined(Q_OS_MAC) + // specific path under Linux + paths << QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.ryzom"; +#endif + + // search config file in these locations + foreach(const QString &path, paths) + { + if (QFile::exists(path + "/" + filename)) return path; + } + + return ""; } bool CConfigFile::use64BitsClient() const @@ -597,21 +667,33 @@ bool CConfigFile::foundTemporaryFiles(const QString &directory) const if (!dir.cd("data") && dir.exists()) return false; + QStringList filter; + filter << "*.string_cache"; + + if (dir.exists("packed_sheets.bnp")) + { + filter << "*.packed_sheets"; + filter << "*.packed"; + filter << "*.pem"; + } + // temporary files - if (!dir.entryList(QStringList() << "*.string_cache" << "*.packed_sheets" << "*.packed" << "*.pem", QDir::Files).isEmpty()) return true; + if (!dir.entryList(filter, QDir::Files).isEmpty()) return true; // fonts directory is not needed anymore - if (dir.cd("fonts") && dir.exists()) return true; + if (dir.exists("fonts.bnp") && dir.cd("fonts") && dir.exists()) return true; return false; } bool CConfigFile::shouldCreateDesktopShortcut() const { -#ifdef Q_OS_WIN32 const CProfile &profile = getProfile(); - return profile.desktopShortcut && !NLMISC::CFile::isExists(qToUtf8(QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Ryzom.lnk")); + if (!profile.desktopShortcut) return false; + +#ifdef Q_OS_WIN32 + return !NLMISC::CFile::isExists(qToUtf8(profile.getClientDesktopLinkFullPath())); #else return false; #endif @@ -619,42 +701,29 @@ bool CConfigFile::shouldCreateDesktopShortcut() const bool CConfigFile::shouldCreateMenuShortcut() const { -#ifdef Q_OS_WIN32 const CProfile &profile = getProfile(); - return profile.menuShortcut && !NLMISC::CFile::isExists(qToUtf8(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/Ryzom/Ryzom.lnk")); + if (!profile.menuShortcut) return false; + +#ifdef Q_OS_WIN32 + return !NLMISC::CFile::isExists(qToUtf8(profile.getClientMenuLinkFullPath())); #else return false; #endif } -QString CConfigFile::getProfileClientFullPath(int profileIndex) const -{ - const CProfile &profile = getProfile(profileIndex); - - QString path = profile.executable; - - if (!path.isEmpty()) return path; - - return getServerClientFullPath(profile.server); -} - -QString CConfigFile::getServerClientFullPath(const QString &serverId) const +QString CConfigFile::getInstallerFullPath() const { - const CServer &server = getServer(serverId); - - if (server.clientFilename.isEmpty()) return ""; - - return server.getDirectory() + "/" + server.clientFilename; + return QApplication::applicationFilePath(); } -QString CConfigFile::getServerConfigurationFullPath(const QString &serverId) const +QString CConfigFile::getInstallerMenuLinkFullPath() const { - const CServer &server = getServer(serverId); - - if (server.configurationFilename.isEmpty()) return ""; - - return server.getDirectory() + "/" + server.configurationFilename; +#ifdef Q_OS_WIN32 + return QString("%1/%2/%2 Installer.lnk").arg(QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation)).arg(QApplication::applicationName()); +#else + return ""; +#endif } QString CConfigFile::getSrcServerClientBNPFullPath() const diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.h b/code/ryzom/tools/client/ryzom_installer/src/configfile.h index dd00b94e8..cc4c02b79 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.h +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.h @@ -45,6 +45,8 @@ public: // helpers QString getDirectory() const; + QString getClientFullPath() const; + QString getConfigurationFullPath() const; }; extern const CServer NoServer; @@ -71,6 +73,9 @@ public: // helpers QString getDirectory() const; + QString getClientFullPath() const; + QString getClientDesktopLinkFullPath() const; + QString getClientMenuLinkFullPath() const; }; extern const CProfile NoProfile; @@ -135,6 +140,9 @@ public: QString getProfileDirectory() const; QString getSrcProfileDirectory() const; + QString getDesktopDirectory() const; + QString getMenuDirectory() const; + static bool has64bitsOS(); // default directories @@ -166,9 +174,8 @@ public: QString getClientArch() const; - QString getProfileClientFullPath(int profileIndex = -1) const; - QString getServerClientFullPath(const QString &serverId = "") const; - QString getServerConfigurationFullPath(const QString &serverId = "") const; + QString getInstallerFullPath() const; + QString getInstallerMenuLinkFullPath() const; QString getSrcServerClientBNPFullPath() const; diff --git a/code/ryzom/tools/client/ryzom_installer/src/filescleaner.cpp b/code/ryzom/tools/client/ryzom_installer/src/filescleaner.cpp index 79c42634a..2f310e056 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/filescleaner.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/filescleaner.cpp @@ -17,21 +17,6 @@ #include "stdpch.h" #include "filescleaner.h" #include "operation.h" -#include "utils.h" - -#include "nel/misc/big_file.h" -#include "nel/misc/callback.h" -#include "nel/misc/file.h" -#include "nel/misc/path.h" - -#include "7z.h" -#include "7zAlloc.h" -#include "7zBuf.h" -#include "7zCrc.h" - -#include "qzipreader.h" - -#include #ifdef DEBUG_NEW #define new DEBUG_NEW @@ -63,8 +48,18 @@ bool CFilesCleaner::exec() if (!dir.cd("data") && dir.exists()) return false; + QStringList filter; + filter << "*.string_cache"; + + if (dir.exists("packed_sheets.bnp")) + { + filter << "*.packed_sheets"; + filter << "*.packed"; + filter << "*.pem"; + } + // temporary files - QStringList files = dir.entryList(QStringList() << "*.string_cache" << "*.packed_sheets" << "*.packed" << "*.pem", QDir::Files); + QStringList files = dir.entryList(filter, QDir::Files); if (m_listener) { @@ -83,8 +78,8 @@ bool CFilesCleaner::exec() ++filesCount; } - // fonts directory is not needed anymore - if (dir.cd("fonts") && dir.exists()) + // fonts directory is not needed anymore if fonts.bnp exists + if (dir.exists("fonts.bnp") && dir.cd("fonts") && dir.exists()) { dir.removeRecursively(); } diff --git a/code/ryzom/tools/client/ryzom_installer/src/main.cpp b/code/ryzom/tools/client/ryzom_installer/src/main.cpp index 97ba78ce9..dfe588000 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/main.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/main.cpp @@ -21,6 +21,7 @@ #include "installdialog.h" #include "uninstalldialog.h" #include "operationdialog.h" +#include "utils.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -60,7 +61,22 @@ int main(int argc, char *argv[]) QApplication::setApplicationVersion(RYZOM_VERSION); QApplication::setWindowIcon(QIcon(":/icons/ryzom.ico")); - // TODO: if not launched from TEMP dir, copy files to TEMP, restart it and exit +#if defined(Q_OS_WIN) && !defined(_DEBUG) + QString tempPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation); + + // check if launched from TEMP directory + if (QApplication::applicationDirPath() != tempPath) + { + // copy installer and required files to TEMP directory + if (copyInstallerExecutable(tempPath)) + { + QString tempFile = tempPath + "/" + QFileInfo(QApplication::applicationFilePath()).fileName(); + + // launch copy in TEMP directory with same arguments + if (QProcess::startDetached(tempFile, QApplication::arguments())) return 0; + } + } +#endif QLocale locale = QLocale::system(); @@ -109,7 +125,7 @@ int main(int argc, char *argv[]) if (parser.isSet(uninstallOption)) { - SUninstallComponents components; + SComponents components; // add all servers by default for (int i = 0; i < config.getServersCount(); ++i) diff --git a/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp b/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp index 27bd38a32..55aa3b5bc 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/mainwindow.cpp @@ -95,7 +95,7 @@ void CMainWindow::onPlayClicked() const CServer &server = config->getServer(profile.server); // get full path of client executable - QString executable = config->getProfileClientFullPath(profileIndex); + QString executable = profile.getClientFullPath(); if (executable.isEmpty() || !QFile::exists(executable)) return; @@ -121,8 +121,9 @@ void CMainWindow::onConfigureClicked() CConfigFile *config = CConfigFile::getInstance(); const CProfile &profile = config->getProfile(profileIndex); + const CServer &server = config->getServer(profile.server); - QString executable = config->getServerConfigurationFullPath(profile.server); + QString executable = server.getConfigurationFullPath(); if (executable.isEmpty() || !QFile::exists(executable)) return; @@ -193,7 +194,7 @@ void CMainWindow::onUninstall() { CConfigFile *config = CConfigFile::getInstance(); - SUninstallComponents components; + SComponents components; // add all servers by default for (int i = 0; i < config->getServersCount(); ++i) diff --git a/code/ryzom/tools/client/ryzom_installer/src/operation.h b/code/ryzom/tools/client/ryzom_installer/src/operation.h index 4c3a88c07..4e8b016be 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operation.h +++ b/code/ryzom/tools/client/ryzom_installer/src/operation.h @@ -33,9 +33,9 @@ public: virtual bool operationShouldStop() =0; }; -struct SUninstallComponents +struct SComponents { - SUninstallComponents() + SComponents() { installer = true; } diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp index fe5c8f372..617c5f613 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp @@ -22,6 +22,7 @@ #include "config.h" #include "profilesmodel.h" #include "utils.h" +#include "nel/misc/path.h" #include "filescopier.h" #include "filesextractor.h" @@ -82,13 +83,19 @@ void COperationDialog::setOperation(OperationType operation) m_operation = operation; } -void COperationDialog::setUninstallComponents(const SUninstallComponents &components) +void COperationDialog::setUninstallComponents(const SComponents &components) { - m_components = components; + m_removeComponents = components; } void COperationDialog::processNextStep() { + if (operationShouldStop()) + { + reject(); + return; + } + switch (m_operation) { case OperationMigrate: @@ -191,21 +198,28 @@ void COperationDialog::processInstallNextStep() } } -void COperationDialog::processUpdateProfilesNextStep() +void COperationDialog::updateAddRemoveComponents() { - // TODO: check all servers are downloaded - // TODO: delete profiles directories that are not used anymore - // TODO: create shortcuts - QStringList serversToUpdate; + QStringList profilesToDelete; + QStringList profilesToAdd; CConfigFile *config = CConfigFile::getInstance(); - // append all old profiles + foreach(const CProfile &profile, config->getProfiles()) + { + // append all new profiles + profilesToAdd << profile.id; + } + foreach(const CProfile &profile, config->getBackupProfiles()) { - if (QFile::exists(profile.getDirectory())) profilesToDelete << profile.id; + // append all old profiles + profilesToDelete << profile.id; + + // remove profiles that didn't exist + profilesToAdd.removeAll(profile.id); } const CServer &defaultServer = config->getServer(); @@ -226,84 +240,118 @@ void COperationDialog::processUpdateProfilesNextStep() profilesToDelete.removeAll(profile.id); } - if (!profilesToDelete.isEmpty()) + // update components to remove + m_removeComponents.profiles << profilesToDelete; + m_removeComponents.installer = false; + + // update components to add + m_addComponents.profiles << profilesToAdd; + m_addComponents.servers << serversToUpdate; + m_addComponents.installer = false; +} + +void COperationDialog::processUpdateProfilesNextStep() +{ + // for "update profiles" operations, we set installer to false when components are updated, + // since we're not using this variable + if (m_addComponents.installer && m_removeComponents.installer) { - m_components.profiles << profilesToDelete; + updateAddRemoveComponents(); + } + // TODO: check all servers are downloaded + // TODO: delete profiles directories that are not used anymore + // TODO: create shortcuts + + if (!m_removeComponents.profiles.isEmpty()) + { // delete profiles in another thread QtConcurrent::run(this, &COperationDialog::deleteComponentsProfiles); + return; + } + if (!m_addComponents.profiles.isEmpty()) + { + // add profiles in another thread + QtConcurrent::run(this, &COperationDialog::addComponentsProfiles); return; } - // servers files to download/update - foreach(const QString &serverId, serversToUpdate) + if (!m_addComponents.servers.isEmpty()) { - const CServer &server = config->getServer(serverId); + CConfigFile *config = CConfigFile::getInstance(); + const CServer &defaultServer = config->getServer(); - // data - if (!config->areRyzomDataInstalledIn(server.getDirectory())) + // servers files to download/update + foreach(const QString &serverId, m_addComponents.servers) { - QString dataFile = config->getInstallationDirectory() + "/" + server.dataDownloadFilename; + const CServer &server = config->getServer(serverId); - // archive already downloaded - if (QFile::exists(dataFile)) + // data + if (!config->areRyzomDataInstalledIn(server.getDirectory())) { - // make server current - m_currentServerId = server.id; + QString dataFile = config->getInstallationDirectory() + "/" + server.dataDownloadFilename; + + // archive already downloaded + if (QFile::exists(dataFile)) + { + // make server current + m_currentServerId = server.id; + + // uncompress it + QtConcurrent::run(this, &COperationDialog::extractDownloadedData); + return; + } + + // data download URLs are different, can't copy data from default server + if (server.dataDownloadUrl != defaultServer.dataDownloadUrl) + { + // download it + downloadData(); + return; + } - // uncompress it - QtConcurrent::run(this, &COperationDialog::extractDownloadedData); - return; - } + // same data used - // data download URLs are different, can't copy data from default server - if (server.dataDownloadUrl != defaultServer.dataDownloadUrl) - { - // download it + // copy them // TODO - return; } - // same data used - - // copy them - // TODO - return; - } - - // client - if (!config->isRyzomClientInstalledIn(server.getDirectory())) - { - // client download URLs are different, can't copy client from default server - if (server.clientDownloadUrl == defaultServer.clientDownloadUrl) + // client + if (!config->isRyzomClientInstalledIn(server.getDirectory())) { - if (QFile::exists("")) - downloadData(); - return; + // client download URLs are different, can't copy client from default server + if (server.clientDownloadUrl == defaultServer.clientDownloadUrl) + { + if (QFile::exists("")) + downloadData(); + return; + } + } + else + { + QString clientFile = config->getInstallationDirectory() + "/" + config->expandVariables(server.clientDownloadFilename); } - } - else - { - QString clientFile = config->getInstallationDirectory() + "/" + config->expandVariables(server.clientDownloadFilename); } } + + updateAddRemoveEntry(); } void COperationDialog::processUninstallNextStep() { CConfigFile *config = CConfigFile::getInstance(); - if (!m_components.servers.isEmpty()) + if (!m_removeComponents.servers.isEmpty()) { QtConcurrent::run(this, &COperationDialog::deleteComponentsServers); } - else if (!m_components.profiles.isEmpty()) + else if (!m_removeComponents.profiles.isEmpty()) { QtConcurrent::run(this, &COperationDialog::deleteComponentsProfiles); } - else if (m_components.installer) + else if (m_removeComponents.installer) { QtConcurrent::run(this, &COperationDialog::deleteComponentsInstaller); } @@ -431,7 +479,7 @@ void COperationDialog::onProgressFail(const QString &error) void COperationDialog::onDone() { - if (!operationShouldStop()) processNextStep(); + processNextStep(); } void COperationDialog::downloadData() @@ -676,9 +724,27 @@ void COperationDialog::copyInstaller() QFile::rename(oldInstallerFullPath, newInstallerFullPath); } } - } - // TODO: create shortcuts for installer + // create menu directory if defined + QString path = config->getMenuDirectory(); + + if (!path.isEmpty()) + { + QDir dir; + + if (!dir.mkpath(path)) + { + qDebug() << "Unable to create directory" << path; + } + } + + // create installer link in menu + QString executable = newInstallerFullPath; + QString shortcut = config->getInstallerMenuLinkFullPath(); + QString desc = "Ryzom Installer"; + + createLink(executable, shortcut, "", "", desc); + } emit done(); } @@ -797,11 +863,11 @@ bool COperationDialog::createDefaultProfile() return true; } -bool COperationDialog::createClientDesktopShortcut(int profileIndex) +bool COperationDialog::createClientDesktopShortcut(const QString &profileId) { CConfigFile *config = CConfigFile::getInstance(); - const CProfile &profile = config->getProfile(profileIndex); + const CProfile &profile = config->getProfile(profileId); const CServer &server = config->getServer(profile.server); m_currentOperation = tr("Create desktop shortcut for profile %1").arg(profile.id); @@ -809,8 +875,16 @@ bool COperationDialog::createClientDesktopShortcut(int profileIndex) #ifdef Q_OS_WIN32 if (profile.desktopShortcut) { - QString shortcut = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation) + "/Ryzom.lnk"; - CreateLink(config->getProfileClientFullPath(), shortcut, QString("--profile %1 %2").arg(profile.id).arg(profile.arguments), server.getDirectory(), "Default Ryzom client"); + QString executable = profile.getClientFullPath(); + QString shortcut = profile.getClientDesktopLinkFullPath(); + QString workingDir = server.getDirectory(); + + QString arguments = QString("--profile %1").arg(profile.id); + + // append custom arguments + if (!profile.arguments.isEmpty()) arguments += QString(" %1").arg(profile.arguments); + + createLink(executable, shortcut, arguments, workingDir, profile.comments); } #endif @@ -819,11 +893,11 @@ bool COperationDialog::createClientDesktopShortcut(int profileIndex) return true; } -bool COperationDialog::createClientMenuShortcut(int profileIndex) +bool COperationDialog::createClientMenuShortcut(const QString &profileId) { CConfigFile *config = CConfigFile::getInstance(); - const CProfile &profile = config->getProfile(profileIndex); + const CProfile &profile = config->getProfile(profileId); const CServer &server = config->getServer(profile.server); m_currentOperation = tr("Create menu shortcut for profile %1").arg(profile.id); @@ -831,15 +905,16 @@ bool COperationDialog::createClientMenuShortcut(int profileIndex) #ifdef Q_OS_WIN32 if (profile.menuShortcut) { - QString path = QStandardPaths::writableLocation(QStandardPaths::ApplicationsLocation) + "/Ryzom"; + QString executable = profile.getClientFullPath(); + QString shortcut = profile.getClientMenuLinkFullPath(); + QString workingDir = server.getDirectory(); - QDir dir; + QString arguments = QString("--profile %1").arg(profile.id); - if (dir.mkpath(path)) - { - QString shortcut = path + "/Ryzom.lnk"; - CreateLink(config->getProfileClientFullPath(), shortcut, QString("--profile %1 %2").arg(profile.id).arg(profile.arguments), server.getDirectory(), "Default Ryzom client"); - } + // append custom arguments + if (!profile.arguments.isEmpty()) arguments += QString(" %1").arg(profile.arguments); + + createLink(executable, shortcut, arguments, workingDir, profile.comments); } #endif @@ -872,9 +947,9 @@ bool COperationDialog::createAddRemoveEntry() settings.setValue("Comments", ""); settings.setValue("DisplayIcon", nativeFullPath + ",0"); - settings.setValue("DisplayName", "Ryzom"); + settings.setValue("DisplayName", QApplication::applicationName()); settings.setValue("DisplayVersion", RYZOM_VERSION); - settings.setValue("EstimatedSize", 1500000); // TODO: compute real size + settings.setValue("EstimatedSize", getDirectorySize(config->getInstallationDirectory())); settings.setValue("InstallDate", QDateTime::currentDateTime().toString("Ymd")); settings.setValue("InstallLocation", config->getInstallationDirectory()); settings.setValue("MajorVersion", versionTokens[0].toInt()); @@ -898,6 +973,37 @@ bool COperationDialog::createAddRemoveEntry() return true; } +bool COperationDialog::updateAddRemoveEntry() +{ + CConfigFile *config = CConfigFile::getInstance(); + + const CServer &server = config->getServer(); + + QString oldInstallerFilename = server.clientFilenameOld; + QString newInstallerFilename = server.installerFilename; + + if (!oldInstallerFilename.isEmpty() && !newInstallerFilename.isEmpty()) + { + QString oldInstallerFullPath = config->getSrcServerDirectory() + "/" + oldInstallerFilename; + QString newInstallerFullPath = config->getInstallationDirectory() + "/" + newInstallerFilename; + + if (QFile::exists(newInstallerFullPath)) + { +#ifdef Q_OS_WIN + QSettings settings("HKEY_CURRENT_USER\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Ryzom", QSettings::NativeFormat); + QStringList versionTokens = QApplication::applicationVersion().split('.'); + + settings.setValue("DisplayVersion", QApplication::applicationVersion()); + settings.setValue("EstimatedSize", getDirectorySize(config->getInstallationDirectory())); + settings.setValue("MajorVersion", versionTokens[0].toInt()); + settings.setValue("MinorVersion", versionTokens[1].toInt()); +#endif + } + } + + return true; +} + bool COperationDialog::deleteAddRemoveEntry() { #ifdef Q_OS_WIN @@ -916,14 +1022,14 @@ void COperationDialog::deleteComponentsServers() m_currentOperationProgressFormat = tr("Deleting %1..."); emit prepare(); - emit init(0, m_components.servers.size()); + emit init(0, m_removeComponents.servers.size()); emit start(); CConfigFile *config = CConfigFile::getInstance(); int i = 0; - foreach(const QString &serverId, m_components.servers) + foreach(const QString &serverId, m_removeComponents.servers) { if (operationShouldStop()) { @@ -949,23 +1055,44 @@ void COperationDialog::deleteComponentsServers() } } - emit success(m_components.servers.size()); + emit success(m_removeComponents.servers.size()); + + // clear list of all servers to uninstall + m_removeComponents.servers.clear(); + emit done(); } +void COperationDialog::addComponentsProfiles() +{ + m_currentOperation = tr("Add profiles"); + m_currentOperationProgressFormat = tr("Adding profile %1..."); + + CConfigFile *config = CConfigFile::getInstance(); + + foreach(const QString &profileId, m_addComponents.profiles) + { + CProfile &profile = config->getProfile(profileId); + + if (profile.desktopShortcut) createClientDesktopShortcut(profile.id); + + if (profile.menuShortcut) createClientMenuShortcut(profile.id); + } +} + void COperationDialog::deleteComponentsProfiles() { m_currentOperation = tr("Delete profiles"); m_currentOperationProgressFormat = tr("Deleting profile %1..."); emit prepare(); - emit init(0, m_components.servers.size()); + emit init(0, m_removeComponents.servers.size()); CConfigFile *config = CConfigFile::getInstance(); int i = 0; - foreach(const QString &profileId, m_components.profiles) + foreach(const QString &profileId, m_removeComponents.profiles) { if (operationShouldStop()) { @@ -990,14 +1117,17 @@ void COperationDialog::deleteComponentsProfiles() } } + // TODO: delete links + // delete profile config->removeProfile(profileId); } + emit success(m_removeComponents.profiles.size()); + // clear list of all profiles to uninstall - m_components.profiles.clear(); + m_removeComponents.profiles.clear(); - emit success(m_components.servers.size()); emit done(); } @@ -1012,7 +1142,19 @@ void COperationDialog::deleteComponentsInstaller() deleteAddRemoveEntry(); - emit onProgressSuccess(m_components.servers.size()); + // delete menu + QString path = config->getMenuDirectory(); + + if (!path.isEmpty()) + { + QDir dir(path); + + dir.removeRecursively(); + } + + // TODO: + + emit onProgressSuccess(1); emit done(); } diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h index a170c30a0..bae2a8b7f 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h @@ -39,7 +39,7 @@ public: virtual ~COperationDialog(); void setOperation(OperationType operation); - void setUninstallComponents(const SUninstallComponents &components); + void setUninstallComponents(const SComponents &components); public slots: void onAbortClicked(); @@ -102,14 +102,25 @@ protected: void copyInstaller(); void uninstallOldClient(); bool createDefaultProfile(); - bool createClientDesktopShortcut(int profileIndex); - bool createClientMenuShortcut(int profileIndex); + + bool createClientDesktopShortcut(const QString &profileId); + bool createClientMenuShortcut(const QString &profileId); + bool createAddRemoveEntry(); + bool updateAddRemoveEntry(); bool deleteAddRemoveEntry(); + + void addComponentsServers(); void deleteComponentsServers(); + + void addComponentsProfiles(); void deleteComponentsProfiles(); + + void addComponentsInstaller(); void deleteComponentsInstaller(); + void updateAddRemoveComponents(); + // from CFilesCopier virtual void operationPrepare(); virtual void operationInit(qint64 current, qint64 total); @@ -133,7 +144,8 @@ protected: bool m_aborting; OperationType m_operation; - SUninstallComponents m_components; + SComponents m_addComponents; + SComponents m_removeComponents; QString m_currentServerId; }; diff --git a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp index cbfcacaf8..8a5b84b0a 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/profilesdialog.cpp @@ -103,7 +103,7 @@ void CProfilesDialog::displayProfile(int index) if (executable.isEmpty()) { - executable = CConfigFile::getInstance()->getServerClientFullPath(profile.server); + executable = profile.getClientFullPath(); } QString profileDirectory = profile.getDirectory(); @@ -216,7 +216,7 @@ void CProfilesDialog::updateExecutableVersion(int index) // file empty, use default one if (executable.isEmpty()) { - executable += CConfigFile::getInstance()->getServerClientFullPath(profile.server); + executable += CConfigFile::getInstance()->getServer(profile.server).getClientFullPath(); } // file doesn't exist @@ -264,18 +264,16 @@ void CProfilesDialog::onExecutableBrowseClicked() CProfile &profile = m_model->getProfiles()[m_currentProfileIndex]; QString executable = profile.executable; + QString defaultExecutable = CConfigFile::getInstance()->getServer(profile.server).getClientFullPath(); - if (executable.isEmpty()) - { - executable = CConfigFile::getInstance()->getServerClientFullPath(profile.server); - } + if (executable.isEmpty()) executable = defaultExecutable; executable = QFileDialog::getOpenFileName(this, tr("Please choose Ryzom client executable to launch"), executable, tr("Executables (*.exe)")); if (executable.isEmpty()) return; // don't need to save the new executable if the same as default one - if (executable == CConfigFile::getInstance()->getServerClientFullPath(profile.server)) + if (executable == defaultExecutable) { profile.executable.clear(); } diff --git a/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.cpp index 62763063b..4c61da6d5 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.cpp @@ -114,7 +114,7 @@ void CUninstallDialog::showEvent(QShowEvent *event) QtConcurrent::run(this, &CUninstallDialog::updateSizes); } -void CUninstallDialog::setSelectedComponents(const SUninstallComponents &components) +void CUninstallDialog::setSelectedComponents(const SComponents &components) { QStandardItemModel *model = qobject_cast(componentsTreeView->model()); if (model == NULL) return; @@ -150,9 +150,9 @@ void CUninstallDialog::setSelectedComponents(const SUninstallComponents &compone if (item) item->setCheckState(components.installer ? Qt::Checked : Qt::Unchecked); } -SUninstallComponents CUninstallDialog::getSelectedCompenents() const +SComponents CUninstallDialog::getSelectedCompenents() const { - SUninstallComponents res; + SComponents res; QStandardItemModel *model = qobject_cast(componentsTreeView->model()); if (model == NULL) return res; diff --git a/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.h b/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.h index 08f7f536d..f8bebace1 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.h +++ b/code/ryzom/tools/client/ryzom_installer/src/uninstalldialog.h @@ -35,8 +35,8 @@ public: CUninstallDialog(QWidget *parent = NULL); virtual ~CUninstallDialog(); - void setSelectedComponents(const SUninstallComponents &components); - SUninstallComponents getSelectedCompenents() const; + void setSelectedComponents(const SComponents &components); + SComponents getSelectedCompenents() const; signals: void updateSize(int row, const QString &text); diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp index d9ebda4c0..ba65bd2ad 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp @@ -111,7 +111,7 @@ wchar_t* qToWide(const QString &str) // Shell link, stored in the Comment field of the link // properties. -bool CreateLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc) +bool createLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc) { IShellLinkW* psl; @@ -163,7 +163,7 @@ bool CreateLink(const QString &pathObj, const QString &pathLink, const QString & // Shell link, stored in the Comment field of the link // properties. -bool ResolveLink(const QWidget &window, const QString &linkFile, QString &path) +bool resolveLink(const QWidget &window, const QString &linkFile, QString &path) { IShellLinkW* psl; WIN32_FIND_DATAW wfd; @@ -232,14 +232,65 @@ bool ResolveLink(const QWidget &window, const QString &linkFile, QString &path) #else -bool CreateLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc) +bool createLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc) { + // TODO: create .desktop file under Linux + return false; } -bool ResolveLink(const QWidget &window, const QString &pathLink, QString &pathObj) +bool resolveLink(const QWidget &window, const QString &pathLink, QString &pathObj) { return false; } #endif + +bool copyInstallerExecutable(const QString &destination) +{ + QString path = QApplication::applicationDirPath(); + + QStringList files; +#ifdef Q_OS_WIN + + // VC++ runtimes +#if _MSC_VER == 1900 + files << "msvcp140.dll"; + files << "msvcr140.dll"; +#else _MSC_VER == 1600 + files << "msvcp100.dll"; + files << "msvcr100.dll"; +#endif + +#else +#endif + + files << QFileInfo(QApplication::applicationFilePath()).fileName(); + + foreach(const QString &file, files) + { + // convert to absolute path + QString srcPath = path + "/" + file; + QString dstPath = destination + "/" + file; + + if (QFile::exists(srcPath)) + { + if (QFile::exists(dstPath)) + { + if (!QFile::remove(dstPath)) + { + qDebug() << "Unable to delete" << dstPath; + } + } + + if (!QFile::copy(srcPath, dstPath)) + { + qDebug() << "Unable to copy" << srcPath << "to" << dstPath; + + return false; + } + } + } + + return true; +} diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.h b/code/ryzom/tools/client/ryzom_installer/src/utils.h index 6c2533076..c729ba2cb 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.h +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.h @@ -48,7 +48,9 @@ QString qFromWide(const wchar_t *str); wchar_t* qToWide(const QString &str); -bool CreateLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc); -bool ResolveLink(const QWidget &window, const QString &pathLink, QString &pathObj); +bool createLink(const QString &pathObj, const QString &pathLink, const QString &arguments, const QString &workingDir, const QString &desc); +bool resolveLink(const QWidget &window, const QString &pathLink, QString &pathObj); + +bool copyInstallerExecutable(const QString &destination); #endif diff --git a/code/ryzom/tools/client/ryzom_installer/ui/operationdialog.ui b/code/ryzom/tools/client/ryzom_installer/ui/operationdialog.ui index 25a24c65a..62ae32ab4 100644 --- a/code/ryzom/tools/client/ryzom_installer/ui/operationdialog.ui +++ b/code/ryzom/tools/client/ryzom_installer/ui/operationdialog.ui @@ -38,14 +38,14 @@ - TextLabel + Operation - TextLabel + Operation progress