1
0
Эх сурвалжийг харах

CPackIFW: Internationalization Support

Changes:
- DISPLAY_NAME and DESCRIPTION in CPackIFW module now is MULTI_ARGS;
- Added internationalization support for DisplayName and Description
  properties in cmCPackIFWPackage class;
- Added documentation to CPackIFW module;
- Added release note.
Konstantin Podsvirov 8 жил өмнө
parent
commit
72ac7ad98d

+ 7 - 0
Help/release/dev/cpackifw-i18n.rst

@@ -0,0 +1,7 @@
+cpackifw-i18n
+-------------
+
+* The :module:`CPackIFW` module :command:`cpack_ifw_configure_component` and
+  :command:`cpack_ifw_configure_component_group` commands gained a
+  internationalization support for ``DISPLAY_NAME`` and ``DESCRIPTION`` options
+  to more specific configuration.

+ 37 - 9
Modules/CPackIFW.cmake

@@ -55,6 +55,33 @@
 # The :variable:`CPACK_IFW_ROOT` variable has a higher priority and overrides
 # the value of the :variable:`QTIFWDIR` variable.
 #
+# Internationalization
+# ^^^^^^^^^^^^^^^^^^^^
+#
+# Some variables and command arguments support internationalization via
+# CMake script. This is an optional feature.
+#
+# Installers created by QtIFW_ tools have built-in support for
+# internationalization and many phrases are localized to many languages,
+# but this does not apply to the description of the your components and groups
+# that will be distributed.
+#
+# Localization of the description of your components and groups is useful for
+# users of your installers.
+#
+# A localized variable or argument can contain a single default value, and a
+# set of pairs the name of the locale and the localized value.
+#
+# For example:
+#
+# .. code-block:: cmake
+#
+#    set(LOCALIZABLE_VARIABLE "Default value"
+#      en "English value"
+#      en_US "American value"
+#      en_GB "Great Britain value"
+#      )
+#
 # Variables
 # ^^^^^^^^^
 #
@@ -265,8 +292,8 @@
 #     cpack_ifw_configure_component(<compname> [COMMON] [ESSENTIAL] [VIRTUAL]
 #                         [FORCED_INSTALLATION] [REQUIRES_ADMIN_RIGHTS]
 #                         [NAME <name>]
-#                         [DISPLAY_NAME <display_name>]
-#                         [DESCRIPTION <description>]
+#                         [DISPLAY_NAME <display_name>] # Note: Internationalization supported
+#                         [DESCRIPTION <description>] # Note: Internationalization supported
 #                         [UPDATE_TEXT <update_text>]
 #                         [VERSION <version>]
 #                         [RELEASE_DATE <release_date>]
@@ -368,8 +395,8 @@
 #     cpack_ifw_configure_component_group(<groupname> [VIRTUAL]
 #                         [FORCED_INSTALLATION] [REQUIRES_ADMIN_RIGHTS]
 #                         [NAME <name>]
-#                         [DISPLAY_NAME <display_name>]
-#                         [DESCRIPTION <description>]
+#                         [DISPLAY_NAME <display_name>] # Note: Internationalization supported
+#                         [DESCRIPTION <description>] # Note: Internationalization supported
 #                         [UPDATE_TEXT <update_text>]
 #                         [VERSION <version>]
 #                         [RELEASE_DATE <release_date>]
@@ -546,8 +573,9 @@
 #
 #    cpack_add_component(myapp
 #        DISPLAY_NAME "MyApp"
-#        DESCRIPTION "My Application")
+#        DESCRIPTION "My Application") # Default description
 #    cpack_ifw_configure_component(myapp
+#        DESCRIPTION ru_RU "Мое Приложение" # Localized description
 #        VERSION "1.2.3" # Version of component
 #        SCRIPT "operations.qs")
 #    cpack_add_component(mybigplugin
@@ -835,8 +863,8 @@ macro(cpack_ifw_configure_component compname)
   string(TOUPPER ${compname} _CPACK_IFWCOMP_UNAME)
 
   set(_IFW_OPT COMMON ESSENTIAL VIRTUAL FORCED_INSTALLATION REQUIRES_ADMIN_RIGHTS)
-  set(_IFW_ARGS NAME DISPLAY_NAME DESCRIPTION VERSION RELEASE_DATE SCRIPT PRIORITY SORTING_PRIORITY UPDATE_TEXT DEFAULT)
-  set(_IFW_MULTI_ARGS DEPENDS DEPENDENCIES AUTO_DEPEND_ON LICENSES USER_INTERFACES TRANSLATIONS)
+  set(_IFW_ARGS NAME VERSION RELEASE_DATE SCRIPT PRIORITY SORTING_PRIORITY UPDATE_TEXT DEFAULT)
+  set(_IFW_MULTI_ARGS DISPLAY_NAME DESCRIPTION DEPENDS DEPENDENCIES AUTO_DEPEND_ON LICENSES USER_INTERFACES TRANSLATIONS)
   cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
 
   _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_SCRIPT)
@@ -876,8 +904,8 @@ macro(cpack_ifw_configure_component_group grpname)
   string(TOUPPER ${grpname} _CPACK_IFWGRP_UNAME)
 
   set(_IFW_OPT VIRTUAL FORCED_INSTALLATION REQUIRES_ADMIN_RIGHTS)
-  set(_IFW_ARGS NAME DISPLAY_NAME DESCRIPTION VERSION RELEASE_DATE SCRIPT PRIORITY SORTING_PRIORITY UPDATE_TEXT DEFAULT)
-  set(_IFW_MULTI_ARGS DEPENDS DEPENDENCIES AUTO_DEPEND_ON LICENSES USER_INTERFACES TRANSLATIONS)
+  set(_IFW_ARGS NAME VERSION RELEASE_DATE SCRIPT PRIORITY SORTING_PRIORITY UPDATE_TEXT DEFAULT)
+  set(_IFW_MULTI_ARGS DISPLAY_NAME DESCRIPTION DEPENDS DEPENDENCIES AUTO_DEPEND_ON LICENSES USER_INTERFACES TRANSLATIONS)
   cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})
 
   _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_SCRIPT)

+ 46 - 0
Source/CPack/IFW/cmCPackIFWCommon.cxx

@@ -11,6 +11,8 @@
 #include "cmXMLWriter.h"
 
 #include <sstream>
+#include <utility>
+#include <vector>
 
 cmCPackIFWCommon::cmCPackIFWCommon()
   : Generator(CM_NULLPTR)
@@ -72,6 +74,50 @@ bool cmCPackIFWCommon::IsVersionEqual(const char* version)
     version);
 }
 
+void cmCPackIFWCommon::ExpandListArgument(
+  const std::string& arg, std::map<std::string, std::string>& argsOut)
+{
+  std::vector<std::string> args;
+  cmSystemTools::ExpandListArgument(arg, args, false);
+  if (args.empty()) {
+    return;
+  }
+
+  std::size_t i = 0;
+  std::size_t c = args.size();
+  if (c % 2) {
+    argsOut[""] = args[i];
+    ++i;
+  }
+
+  --c;
+  for (; i < c; i += 2) {
+    argsOut[args[i]] = args[i + 1];
+  }
+}
+
+void cmCPackIFWCommon::ExpandListArgument(
+  const std::string& arg, std::multimap<std::string, std::string>& argsOut)
+{
+  std::vector<std::string> args;
+  cmSystemTools::ExpandListArgument(arg, args, false);
+  if (args.empty()) {
+    return;
+  }
+
+  std::size_t i = 0;
+  std::size_t c = args.size();
+  if (c % 2) {
+    argsOut.insert(std::pair<std::string, std::string>("", args[i]));
+    ++i;
+  }
+
+  --c;
+  for (; i < c; i += 2) {
+    argsOut.insert(std::pair<std::string, std::string>(args[i], args[i + 1]));
+  }
+}
+
 void cmCPackIFWCommon::WriteGeneratedByToStrim(cmXMLWriter& xout)
 {
   if (!this->Generator) {

+ 16 - 0
Source/CPack/IFW/cmCPackIFWCommon.h

@@ -5,6 +5,7 @@
 
 #include "cmConfigure.h" // IWYU pragma: keep
 
+#include <map>
 #include <string>
 
 class cmCPackIFWGenerator;
@@ -46,6 +47,21 @@ public:
    */
   bool IsVersionEqual(const char* version);
 
+  /** Expand the list argument containing the map of the key-value pairs.
+   *  If the number of elements is odd, then the first value is used as the
+   *  default value with an empty key.
+   *  Any values with the same keys will be permanently overwritten.
+   */
+  static void ExpandListArgument(const std::string& arg,
+                                 std::map<std::string, std::string>& argsOut);
+
+  /** Expand the list argument containing the multimap of the key-value pairs.
+   *  If the number of elements is odd, then the first value is used as the
+   *  default value with an empty key.
+   */
+  static void ExpandListArgument(
+    const std::string& arg, std::multimap<std::string, std::string>& argsOut);
+
   cmCPackIFWGenerator* Generator;
 
 protected:

+ 36 - 14
Source/CPack/IFW/cmCPackIFWPackage.cxx

@@ -15,6 +15,7 @@
 #include <map>
 #include <sstream>
 #include <stddef.h>
+#include <utility>
 
 //---------------------------------------------------------- CompareStruct ---
 cmCPackIFWPackage::CompareStruct::CompareStruct()
@@ -108,8 +109,8 @@ std::string cmCPackIFWPackage::GetComponentName(cmCPackComponent* component)
 
 void cmCPackIFWPackage::DefaultConfiguration()
 {
-  this->DisplayName = "";
-  this->Description = "";
+  this->DisplayName.clear();
+  this->Description.clear();
   this->Version = "";
   this->ReleaseDate = "";
   this->Script = "";
@@ -136,17 +137,17 @@ int cmCPackIFWPackage::ConfigureFromOptions()
 
   // Display name
   if (const char* option = this->GetOption("CPACK_PACKAGE_NAME")) {
-    this->DisplayName = option;
+    this->DisplayName[""] = option;
   } else {
-    this->DisplayName = "Your package";
+    this->DisplayName[""] = "Your package";
   }
 
   // Description
   if (const char* option =
         this->GetOption("CPACK_PACKAGE_DESCRIPTION_SUMMARY")) {
-    this->Description = option;
+    this->Description[""] = option;
   } else {
-    this->Description = "Your package description";
+    this->Description[""] = "Your package description";
   }
 
   // Version
@@ -174,10 +175,10 @@ int cmCPackIFWPackage::ConfigureFromComponent(cmCPackComponent* component)
     cmsys::SystemTools::UpperCase(component->Name) + "_";
 
   // Display name
-  this->DisplayName = component->DisplayName;
+  this->DisplayName[""] = component->DisplayName;
 
   // Description
-  this->Description = component->Description;
+  this->Description[""] = component->Description;
 
   // Version
   if (const char* optVERSION = this->GetOption(prefix + "VERSION")) {
@@ -262,8 +263,8 @@ int cmCPackIFWPackage::ConfigureFromGroup(cmCPackComponentGroup* group)
   std::string prefix = "CPACK_IFW_COMPONENT_GROUP_" +
     cmsys::SystemTools::UpperCase(group->Name) + "_";
 
-  this->DisplayName = group->DisplayName;
-  this->Description = group->Description;
+  this->DisplayName[""] = group->DisplayName;
+  this->Description[""] = group->Description;
 
   // Version
   if (const char* optVERSION = this->GetOption(prefix + "VERSION")) {
@@ -358,7 +359,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
   if (this->IsSetToEmpty(option)) {
     this->DisplayName.clear();
   } else if (const char* value = this->GetOption(option)) {
-    this->DisplayName = value;
+    this->ExpandListArgument(value, this->DisplayName);
   }
 
   // Description
@@ -366,7 +367,7 @@ int cmCPackIFWPackage::ConfigureFromPrefix(const std::string& prefix)
   if (this->IsSetToEmpty(option)) {
     this->Description.clear();
   } else if (const char* value = this->GetOption(option)) {
-    this->Description = value;
+    this->ExpandListArgument(value, this->Description);
   }
 
   // Release date
@@ -519,8 +520,29 @@ void cmCPackIFWPackage::GeneratePackageFile()
 
   xout.StartElement("Package");
 
-  xout.Element("DisplayName", this->DisplayName);
-  xout.Element("Description", this->Description);
+  // DisplayName (with translations)
+  for (std::map<std::string, std::string>::iterator it =
+         this->DisplayName.begin();
+       it != this->DisplayName.end(); ++it) {
+    xout.StartElement("DisplayName");
+    if (!it->first.empty()) {
+      xout.Attribute("xml:lang", it->first);
+    }
+    xout.Content(it->second);
+    xout.EndElement();
+  }
+
+  // Description (with translations)
+  for (std::map<std::string, std::string>::iterator it =
+         this->Description.begin();
+       it != this->Description.end(); ++it) {
+    xout.StartElement("Description");
+    if (!it->first.empty()) {
+      xout.Attribute("xml:lang", it->first);
+    }
+    xout.Content(it->second);
+    xout.EndElement();
+  }
 
   // Update text
   if (!this->UpdateText.empty()) {

+ 3 - 2
Source/CPack/IFW/cmCPackIFWPackage.h

@@ -7,6 +7,7 @@
 
 #include "cmCPackIFWCommon.h"
 
+#include <map>
 #include <set>
 #include <string>
 #include <vector>
@@ -69,10 +70,10 @@ public:
   // Configuration
 
   /// Human-readable name of the component
-  std::string DisplayName;
+  std::map<std::string, std::string> DisplayName;
 
   /// Human-readable description of the component
-  std::string Description;
+  std::map<std::string, std::string> Description;
 
   /// Version number of the component
   std::string Version;