diff --git a/code/CMakeModules/nel.cmake b/code/CMakeModules/nel.cmake index a7adf48c6..941351315 100644 --- a/code/CMakeModules/nel.cmake +++ b/code/CMakeModules/nel.cmake @@ -246,11 +246,12 @@ MACRO(NL_SETUP_DEFAULT_OPTIONS) ### OPTION(WITH_SYMBOLS "Keep debug symbols in binaries" OFF) - IF(WIN32) + # only enable STLport for VC++ 2010 and less + IF(WIN32 AND MSVC_VERSION LESS 1600) OPTION(WITH_STLPORT "With STLport support." ON ) - ELSE(WIN32) + ELSE() OPTION(WITH_STLPORT "With STLport support." OFF) - ENDIF(WIN32) + ENDIF() OPTION(BUILD_DASHBOARD "Build to the CDash dashboard" OFF) diff --git a/code/ryzom/tools/client/ryzom_installer/res/resources.qrc b/code/ryzom/tools/client/ryzom_installer/res/resources.qrc index 0e7224f4e..66d8f502e 100644 --- a/code/ryzom/tools/client/ryzom_installer/res/resources.qrc +++ b/code/ryzom/tools/client/ryzom_installer/res/resources.qrc @@ -5,4 +5,7 @@ ryzom.ico + + template.desktop + diff --git a/code/ryzom/tools/client/ryzom_installer/res/template.desktop b/code/ryzom/tools/client/ryzom_installer/res/template.desktop new file mode 100644 index 000000000..83c42f5a6 --- /dev/null +++ b/code/ryzom/tools/client/ryzom_installer/res/template.desktop @@ -0,0 +1,10 @@ +[Desktop Entry] +Version=1.0 +Name=$NAME +Type=Application +GenericName=MMORPG +Exec=$COMMAND +Icon=$ICON +Terminal=false +Hidden=false +Categories=Game;RolePlaying; diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp index 2167707c9..63980e5fe 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.cpp @@ -60,32 +60,109 @@ QString CProfile::getClientFullPath() const return s.getClientFullPath(); } -QString CProfile::getClientDesktopLinkFullPath() const +QString CProfile::getClientDesktopShortcutFullPath() const { #ifdef Q_OS_WIN32 return CConfigFile::getInstance()->getDesktopDirectory() + "/" + name + ".lnk"; -#else +#elif defined(Q_OS_MAC) return ""; +#else + return CConfigFile::getInstance()->getDesktopDirectory() + "/" + name + ".desktop"; #endif } -QString CProfile::getClientMenuLinkFullPath() const +QString CProfile::getClientMenuShortcutFullPath() const { #ifdef Q_OS_WIN32 return CConfigFile::getInstance()->getMenuDirectory() + "/" + name + ".lnk"; -#else +#elif defined(Q_OS_MAC) return ""; +#else + return CConfigFile::getInstance()->getMenuDirectory() + "/" + name + ".desktop"; #endif } +void CProfile::createShortcuts() const +{ + const CServer &s = CConfigFile::getInstance()->getServer(server); + + QString executable = getClientFullPath(); + QString workingDir = s.getDirectory(); + + QString arguments = QString("--profile %1").arg(id); + + // append custom arguments + if (!arguments.isEmpty()) arguments += QString(" %1").arg(arguments); + + QString icon; + +#ifdef Q_OS_WIN32 + icon = executable; +#else + // TODO: Linux icon +#endif + + if (desktopShortcut) + { + QString shortcut = getClientDesktopShortcutFullPath(); + + // create desktop shortcut + createLink(shortcut, name, executable, arguments, icon, workingDir); + } + + if (menuShortcut) + { + QString shortcut = getClientMenuShortcutFullPath(); + + // create menu shortcut + createLink(shortcut, name, executable, arguments, icon, workingDir); + } +} + +void CProfile::deleteShortcuts() const +{ + // delete desktop shortcut + QString link = getClientDesktopShortcutFullPath(); + + if (QFile::exists(link)) QFile::remove(link); + + // delete menu shortcut + link = getClientMenuShortcutFullPath(); + + if (QFile::exists(link)) QFile::remove(link); +} + +void CProfile::updateShortcuts() const +{ + deleteShortcuts(); + createShortcuts(); +} + CConfigFile *CConfigFile::s_instance = NULL; CConfigFile::CConfigFile(QObject *parent):QObject(parent), m_defaultServerIndex(0), m_defaultProfileIndex(0), m_use64BitsClient(false), m_shouldUninstallOldClient(true) { s_instance = this; - m_language = QLocale::system().name().left(2); // only keep language ISO 639 code - m_defaultConfigPath = QApplication::applicationDirPath() + "/installer.ini"; + // only keep language ISO 639 code + m_language = QLocale::system().name().left(2); + + // it won't be found if run with uninstall flag, but since we already have a local installer.ini... + QString configFile = getCurrentDirectory() + "/installer.ini"; + + if (!QFile::exists(configFile)) + { + configFile = QApplication::applicationDirPath() + "/installer.ini"; + + if (!QFile::exists(configFile)) + { + configFile.clear(); + } + } + + m_defaultConfigPath = configFile; + + // the config file we'll write m_configPath = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/installer.ini"; } @@ -482,6 +559,11 @@ QString CConfigFile::expandVariables(const QString &str) const res.replace("$TIMESTAMP", QString::number(QDateTime::currentDateTime().toTime_t())); res.replace("$LANG", m_language); res.replace("$ARCH", getClientArch()); + res.replace("$PRODUCT_NAME", m_productName); + res.replace("$PRODUCT_PUBLISHER", m_productPublisher); + res.replace("$PRODUCT_ABOUT_URL", m_productAboutUrl); + res.replace("$PRODUCT_HELP_URL", m_productHelpUrl); + res.replace("$PRODUCT_COMMENTS", m_productComments); return res; } @@ -634,9 +716,6 @@ bool CConfigFile::isRyzomClientInstalledIn(const QString &directory) const // directory doesn't exist if (!dir.exists()) return false; - // client_default.cfg doesn't exist - if (!dir.exists("client_default.cfg")) return false; - // current server CServer server = getServer(); @@ -649,9 +728,18 @@ bool CConfigFile::isRyzomClientInstalledIn(const QString &directory) const // check if old client is defined and exists if (!dir.exists(clientFilename)) return false; - } - // TODO: more checks + // client 2.1- + } + else + { + // client 3.0+ + + // client_default.cfg doesn't exist + if (!dir.exists("client_default.cfg")) return false; + + // TODO: more checks + } return true; } @@ -692,11 +780,9 @@ bool CConfigFile::shouldCreateDesktopShortcut() const if (!profile.desktopShortcut) return false; -#ifdef Q_OS_WIN32 - return !NLMISC::CFile::isExists(qToUtf8(profile.getClientDesktopLinkFullPath())); -#else - return false; -#endif + QString shortcut = profile.getClientDesktopShortcutFullPath(); + + return !shortcut.isEmpty() && !NLMISC::CFile::isExists(qToUtf8(shortcut)); } bool CConfigFile::shouldCreateMenuShortcut() const @@ -705,11 +791,9 @@ bool CConfigFile::shouldCreateMenuShortcut() const if (!profile.menuShortcut) return false; -#ifdef Q_OS_WIN32 - return !NLMISC::CFile::isExists(qToUtf8(profile.getClientMenuLinkFullPath())); -#else - return false; -#endif + QString shortcut = profile.getClientMenuShortcutFullPath(); + + return !shortcut.isEmpty() && !NLMISC::CFile::isExists(qToUtf8(shortcut)); } QString CConfigFile::getInstallerFullPath() const @@ -876,14 +960,9 @@ OperationStep CConfigFile::getInstallNextStep() const return CopyProfileFiles; } - if (shouldCreateDesktopShortcut()) + if (shouldCreateDesktopShortcut() || shouldCreateMenuShortcut()) { - return CreateDesktopShortcut; - } - - if (shouldCreateMenuShortcut()) - { - return CreateMenuShortcut; + return CreateProfileShortcuts; } #ifdef Q_OS_WIN diff --git a/code/ryzom/tools/client/ryzom_installer/src/configfile.h b/code/ryzom/tools/client/ryzom_installer/src/configfile.h index cc4c02b79..ed1768c6c 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/configfile.h +++ b/code/ryzom/tools/client/ryzom_installer/src/configfile.h @@ -74,8 +74,12 @@ public: // helpers QString getDirectory() const; QString getClientFullPath() const; - QString getClientDesktopLinkFullPath() const; - QString getClientMenuLinkFullPath() const; + QString getClientDesktopShortcutFullPath() const; + QString getClientMenuShortcutFullPath() const; + + void createShortcuts() const; + void deleteShortcuts() const; + void updateShortcuts() const; }; extern const CProfile NoProfile; diff --git a/code/ryzom/tools/client/ryzom_installer/src/operation.h b/code/ryzom/tools/client/ryzom_installer/src/operation.h index 5ea4326e1..5cf03f3e1 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operation.h +++ b/code/ryzom/tools/client/ryzom_installer/src/operation.h @@ -64,8 +64,7 @@ enum OperationStep CopyInstaller, UninstallOldClient, CreateProfile, - CreateDesktopShortcut, - CreateMenuShortcut, + CreateProfileShortcuts, CreateAddRemoveEntry, Done }; diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp index b82b46b5d..80b8c8f29 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.cpp @@ -175,12 +175,8 @@ void COperationDialog::processInstallNextStep() createDefaultProfile(); break; - case CreateDesktopShortcut: - createClientDesktopShortcut(0); - break; - - case CreateMenuShortcut: - createClientMenuShortcut(0); + case CreateProfileShortcuts: + createProfileShortcuts(0); break; case CreateAddRemoveEntry: @@ -238,6 +234,9 @@ void COperationDialog::updateAddRemoveComponents() // remove profiles that still exist profilesToDelete.removeAll(profile.id); + + // delete all shortcuts, they'll be recreated later + profile.deleteShortcuts(); } // update components to remove @@ -260,10 +259,9 @@ void COperationDialog::processUpdateProfilesNextStep() { updateAddRemoveComponents(); } + // TODO: check all servers are downloaded // TODO: delete profiles directories that are not used anymore - // TODO: create shortcuts - if (!m_removeComponents.profiles.isEmpty()) { @@ -279,9 +277,10 @@ void COperationDialog::processUpdateProfilesNextStep() return; } + CConfigFile *config = CConfigFile::getInstance(); + if (!m_addComponents.servers.isEmpty()) { - CConfigFile *config = CConfigFile::getInstance(); const CServer &defaultServer = config->getServer(); // servers files to download/update @@ -338,6 +337,12 @@ void COperationDialog::processUpdateProfilesNextStep() } } + // recreate shortcuts + foreach(const CProfile &profile, config->getProfiles()) + { + profile.createShortcuts(); + } + updateAddRemoveEntry(); } @@ -747,9 +752,16 @@ void COperationDialog::copyInstaller() // create installer link in menu QString executable = newInstallerFullPath; QString shortcut = config->getInstallerMenuLinkFullPath(); - QString desc = "Ryzom Installer"; + QString name = "Ryzom Installer"; + QString icon; - createLink(executable, shortcut, "", "", desc); +#ifdef Q_OS_WIN32 + icon = executable; +#else + // TODO: Linux icon +#endif + + createLink(shortcut, name, executable, "", icon, ""); } emit done(); @@ -869,60 +881,15 @@ bool COperationDialog::createDefaultProfile() return true; } -bool COperationDialog::createClientDesktopShortcut(const QString &profileId) +bool COperationDialog::createProfileShortcuts(const QString &profileId) { CConfigFile *config = CConfigFile::getInstance(); 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); + m_currentOperation = tr("Create shortcuts for profile %1").arg(profile.id); -#ifdef Q_OS_WIN32 - if (profile.desktopShortcut) - { - 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 - - emit done(); - - return true; -} - -bool COperationDialog::createClientMenuShortcut(const QString &profileId) -{ - CConfigFile *config = CConfigFile::getInstance(); - - 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); - -#ifdef Q_OS_WIN32 - if (profile.menuShortcut) - { - QString executable = profile.getClientFullPath(); - QString shortcut = profile.getClientMenuLinkFullPath(); - 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 + profile.createShortcuts(); emit done(); @@ -1059,6 +1026,17 @@ void COperationDialog::deleteComponentsServers() return; } } + + // delete all links to clients + for (int i = 0; i < config->getProfilesCount(); ++i) + { + const CProfile &profile = config->getProfile(i); + + if (profile.server == serverId) + { + profile.deleteShortcuts(); + } + } } emit success(m_removeComponents.servers.size()); @@ -1080,9 +1058,7 @@ void COperationDialog::addComponentsProfiles() { const CProfile &profile = config->getProfile(profileId); - if (profile.desktopShortcut) createClientDesktopShortcut(profile.id); - - if (profile.menuShortcut) createClientMenuShortcut(profile.id); + profile.createShortcuts(); } } @@ -1123,7 +1099,7 @@ void COperationDialog::deleteComponentsProfiles() } } - // TODO: delete links + profile.deleteShortcuts(); // delete profile config->removeProfile(profileId); diff --git a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h index 091b77278..e9966c4d2 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h +++ b/code/ryzom/tools/client/ryzom_installer/src/operationdialog.h @@ -103,8 +103,7 @@ protected: void uninstallOldClient(); bool createDefaultProfile(); - bool createClientDesktopShortcut(const QString &profileId); - bool createClientMenuShortcut(const QString &profileId); + bool createProfileShortcuts(const QString &profileId); bool createAddRemoveEntry(); bool updateAddRemoveEntry(); diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp index ba65bd2ad..1e3c324a7 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.cpp +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.cpp @@ -97,21 +97,7 @@ wchar_t* qToWide(const QString &str) #ifdef Q_OS_WIN32 -// CreateLink - Uses the Shell's IShellLink and IPersistFile interfaces -// to create and store a shortcut to the specified object. -// -// Returns the result of calling the member functions of the interfaces. -// -// Parameters: -// lpszPathObj - Address of a buffer that contains the path of the object, -// including the file name. -// lpszPathLink - Address of a buffer that contains the path where the -// Shell link is to be stored, including the file name. -// lpszDesc - Address of a buffer that contains a description of the -// 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 &link, const QString &name, const QString &executable, const QString &arguments, const QString &icon, const QString &workingDir) { IShellLinkW* psl; @@ -123,8 +109,9 @@ bool createLink(const QString &pathObj, const QString &pathLink, const QString & IPersistFile* ppf; // Set the path to the shortcut target and add the description. - psl->SetPath(qToWide(QDir::toNativeSeparators(pathObj))); - psl->SetDescription(qToWide(desc)); + psl->SetPath(qToWide(QDir::toNativeSeparators(executable))); + psl->SetIconLocation(qToWide(QDir::toNativeSeparators(icon)), 0); + psl->SetDescription(qToWide(name)); psl->SetArguments(qToWide(arguments)); psl->SetWorkingDirectory(qToWide(QDir::toNativeSeparators(workingDir))); @@ -138,7 +125,7 @@ bool createLink(const QString &pathObj, const QString &pathLink, const QString & // for success. // Save the link by calling IPersistFile::Save. - hres = ppf->Save(qToWide(QDir::toNativeSeparators(pathLink)), TRUE); + hres = ppf->Save(qToWide(QDir::toNativeSeparators(link)), TRUE); ppf->Release(); } psl->Release(); @@ -146,23 +133,6 @@ bool createLink(const QString &pathObj, const QString &pathLink, const QString & return SUCCEEDED(hres); } -// ResolveIt - Uses the Shell's IShellLink and IPersistFile interfaces -// to retrieve the path and description from an existing shortcut. -// -// Returns the result of calling the member functions of the interfaces. -// -// Parameters: -// hwnd - A handle to the parent window. The Shell uses this window to -// display a dialog box if it needs to prompt the user for more -// information while resolving the link. -// lpszLinkFile - Address of a buffer that contains the path of the link, -// including the file name. -// lpszPath - Address of a buffer that receives the path of the link -// target, including the file name. -// lpszDesc - Address of a buffer that receives the description of the -// Shell link, stored in the Comment field of the link -// properties. - bool resolveLink(const QWidget &window, const QString &linkFile, QString &path) { IShellLinkW* psl; @@ -232,11 +202,35 @@ 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 &link, const QString &name, const QString &executable, const QString &arguments, const QString &icon, const QString &workingDir) { - // TODO: create .desktop file under Linux + // open template + QFile file(":/templates/template.desktop"); - return false; + if (!file.open(QFile::ReadOnly)) return false; + + QString data = QString::fromUtf8(file.readAll()); + + file.close(); + + // build command + QString command = executable; + if (!arguments.isEmpty()) command += " " + arguments; + + // replace strings + data.replace("$NAME", name); + data.replace("$COMMAND", command); + data.replace("$ICON", icon); + + // write file + file.setFileName(link); + + if (!file.open(QFile::WriteOnly)) return false; + + file.write(data.toUtf8()); + file.close(); + + return true; } bool resolveLink(const QWidget &window, const QString &pathLink, QString &pathObj) diff --git a/code/ryzom/tools/client/ryzom_installer/src/utils.h b/code/ryzom/tools/client/ryzom_installer/src/utils.h index c729ba2cb..8072f69d6 100644 --- a/code/ryzom/tools/client/ryzom_installer/src/utils.h +++ b/code/ryzom/tools/client/ryzom_installer/src/utils.h @@ -48,7 +48,7 @@ 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 createLink(const QString &link, const QString &name, const QString &executable, const QString &arguments, const QString &icon, const QString &workingDir); bool resolveLink(const QWidget &window, const QString &pathLink, QString &pathObj); bool copyInstallerExecutable(const QString &destination);