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

Merge topic 'wix-shortcut-properties'

6cc01c14 CPackWIX: Add release notes for the wix-shortcut-properties topic.
135febf0 CPackWIX: Enhance CMake CPack WIX generated installer.
e6731f48 CPackWIX: Add new CPACK_STARTUP_SHORTCUTS property.
279605f5 CPackWIX: Add installed file properties for the creation of shortcuts.
53d7daff CPackWIX: Refactor start menu and desktop shortcut creation.
dc0f3fb4 CPackWIX: Explicitly list CPack WIX headers for IDE convenience.
Brad King 10 жил өмнө
parent
commit
cb16c7844d

+ 22 - 0
CMakeCPackOptions.cmake.in

@@ -87,4 +87,26 @@ if("${CPACK_GENERATOR}" STREQUAL "WIX")
   if(patch MATCHES "^[0-9]+$" AND patch LESS 65535)
     set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION}.${patch}")
   endif()
+
+  set(CPACK_WIX_PROPERTY_ARPURLINFOABOUT "http://www.cmake.org")
+
+  set(CPACK_WIX_PROPERTY_ARPCONTACT "@CPACK_PACKAGE_CONTACT@")
+
+  set(CPACK_WIX_PROPERTY_ARPCOMMENTS
+    "CMake is a cross-platform, open-source build system."
+  )
+
+  set(CPACK_WIX_PRODUCT_ICON
+    "@CMake_SOURCE_DIR@/Utilities/Release/CMakeLogo.ico"
+  )
+
+  set_property(INSTALL "@CMAKE_DOC_DIR@/html/index.html" PROPERTY
+    CPACK_START_MENU_SHORTCUTS "CMake Documentation"
+  )
+
+  set_property(INSTALL "cmake.org.html" PROPERTY
+    CPACK_START_MENU_SHORTCUTS "CMake Web Site"
+  )
+
+  set(CPACK_WIX_LIGHT_EXTRA_FLAGS "-dcl:high")
 endif()

+ 3 - 0
Help/manual/cmake-properties.7.rst

@@ -320,8 +320,11 @@ Properties on Installed Files
 .. toctree::
    :maxdepth: 1
 
+   /prop_inst/CPACK_DESKTOP_SHORTCUTS.rst
    /prop_inst/CPACK_NEVER_OVERWRITE.rst
    /prop_inst/CPACK_PERMANENT.rst
+   /prop_inst/CPACK_START_MENU_SHORTCUTS.rst
+   /prop_inst/CPACK_STARTUP_SHORTCUTS.rst
    /prop_inst/CPACK_WIX_ACL.rst
 
 

+ 7 - 0
Help/prop_inst/CPACK_DESKTOP_SHORTCUTS.rst

@@ -0,0 +1,7 @@
+CPACK_DESKTOP_SHORTCUTS
+-----------------------
+
+Species a list of shortcut names that should be created on the Desktop
+for this file.
+
+The property is currently only supported by the WIX generator.

+ 7 - 0
Help/prop_inst/CPACK_STARTUP_SHORTCUTS.rst

@@ -0,0 +1,7 @@
+CPACK_STARTUP_SHORTCUTS
+-----------------------
+
+Species a list of shortcut names that should be created in the Startup folder
+for this file.
+
+The property is currently only supported by the WIX generator.

+ 7 - 0
Help/prop_inst/CPACK_START_MENU_SHORTCUTS.rst

@@ -0,0 +1,7 @@
+CPACK_START_MENU_SHORTCUTS
+--------------------------
+
+Species a list of shortcut names that should be created in the Start Menu
+for this file.
+
+The property is currently only supported by the WIX generator.

+ 9 - 0
Help/release/dev/wix-shortcut-properties.rst

@@ -0,0 +1,9 @@
+wix-shortcut-properties
+-----------------------
+
+* The CPack WIX generator learned the new
+  :prop_inst:`CPACK_START_MENU_SHORTCUTS`,
+  :prop_inst:`CPACK_DESKTOP_SHORTCUTS` and
+  :prop_inst:`CPACK_STARTUP_SHORTCUTS` installed file properties which can
+  be used to install shorcuts in the Start Menu, on the Desktop and
+  in the Startup Folder respectively.

+ 11 - 0
Source/CMakeLists.txt

@@ -638,14 +638,25 @@ endif()
 if(WIN32)
   set(CPACK_SRCS ${CPACK_SRCS}
     CPack/WiX/cmCPackWIXGenerator.cxx
+    CPack/WiX/cmCPackWIXGenerator.h
     CPack/WiX/cmWIXAccessControlList.cxx
+    CPack/WiX/cmWIXAccessControlList.h
     CPack/WiX/cmWIXDirectoriesSourceWriter.cxx
+    CPack/WiX/cmWIXDirectoriesSourceWriter.h
     CPack/WiX/cmWIXFeaturesSourceWriter.cxx
+    CPack/WiX/cmWIXFeaturesSourceWriter.h
     CPack/WiX/cmWIXFilesSourceWriter.cxx
+    CPack/WiX/cmWIXFilesSourceWriter.h
     CPack/WiX/cmWIXPatch.cxx
+    CPack/WiX/cmWIXPatch.h
     CPack/WiX/cmWIXPatchParser.cxx
+    CPack/WiX/cmWIXPatchParser.h
     CPack/WiX/cmWIXRichTextFormatWriter.cxx
+    CPack/WiX/cmWIXRichTextFormatWriter.h
+    CPack/WiX/cmWIXShortcut.cxx
+    CPack/WiX/cmWIXShortcut.h
     CPack/WiX/cmWIXSourceWriter.cxx
+    CPack/WiX/cmWIXSourceWriter.h
   )
 endif()
 

+ 123 - 93
Source/CPack/WiX/cmCPackWIXGenerator.cxx

@@ -33,7 +33,6 @@
 #include <rpc.h> // for GUID generation
 
 cmCPackWIXGenerator::cmCPackWIXGenerator():
-  HasDesktopShortcuts(false),
   Patch(0)
 {
 
@@ -490,18 +489,16 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
 
   featureDefinitions.EndElement("Feature");
 
-  bool hasShortcuts = false;
+  std::set<cmWIXShortcuts::Type> emittedShortcutTypes;
 
-  shortcut_map_t globalShortcuts;
+  cmWIXShortcuts globalShortcuts;
   if(Components.empty())
     {
     AddComponentsToFeature(toplevel, "ProductFeature",
       directoryDefinitions, fileDefinitions, featureDefinitions,
       globalShortcuts);
-    if(globalShortcuts.size())
-      {
-      hasShortcuts = true;
-      }
+
+    globalShortcuts.AddShortcutTypes(emittedShortcutTypes);
     }
   else
     {
@@ -516,33 +513,29 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
 
       std::string componentFeatureId = "CM_C_" + component.Name;
 
-      shortcut_map_t featureShortcuts;
+      cmWIXShortcuts featureShortcuts;
       AddComponentsToFeature(componentPath, componentFeatureId,
         directoryDefinitions, fileDefinitions,
         featureDefinitions, featureShortcuts);
-      if(featureShortcuts.size())
-        {
-        hasShortcuts = true;
-        }
 
-      if(featureShortcuts.size())
+      featureShortcuts.AddShortcutTypes(emittedShortcutTypes);
+
+      if(!CreateShortcuts(component.Name, componentFeatureId,
+        featureShortcuts, false, fileDefinitions, featureDefinitions))
         {
-        if(!CreateStartMenuShortcuts(component.Name, componentFeatureId,
-          featureShortcuts, fileDefinitions, featureDefinitions))
-          {
-          return false;
-          }
+        return false;
         }
       }
     }
 
-  if(hasShortcuts)
+  bool emitUninstallShortcut = emittedShortcutTypes.find(
+    cmWIXShortcuts::START_MENU) != emittedShortcutTypes.end();
+
+  if(!CreateShortcuts(std::string(), "ProductFeature",
+      globalShortcuts, emitUninstallShortcut,
+      fileDefinitions, featureDefinitions))
     {
-    if(!CreateStartMenuShortcuts(std::string(), "ProductFeature",
-        globalShortcuts, fileDefinitions, featureDefinitions))
-      {
-      return false;
-      }
+    return false;
     }
 
   featureDefinitions.EndElement("Fragment");
@@ -551,17 +544,25 @@ bool cmCPackWIXGenerator::CreateWiXSourceFiles()
   directoryDefinitions.EndInstallationPrefixDirectory(
     installRootSize);
 
-  if(hasShortcuts)
+  if(emittedShortcutTypes.find(cmWIXShortcuts::START_MENU) !=
+      emittedShortcutTypes.end())
     {
     directoryDefinitions.EmitStartMenuFolder(
       GetOption("CPACK_WIX_PROGRAM_MENU_FOLDER"));
     }
 
-  if(this->HasDesktopShortcuts)
+  if(emittedShortcutTypes.find(cmWIXShortcuts::DESKTOP) !=
+      emittedShortcutTypes.end())
     {
     directoryDefinitions.EmitDesktopFolder();
     }
 
+  if(emittedShortcutTypes.find(cmWIXShortcuts::STARTUP) !=
+      emittedShortcutTypes.end())
+    {
+    directoryDefinitions.EmitStartupFolder();
+    }
+
   directoryDefinitions.EndElement("Directory");
   directoryDefinitions.EndElement("Fragment");
 
@@ -649,7 +650,7 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
   cmWIXDirectoriesSourceWriter& directoryDefinitions,
   cmWIXFilesSourceWriter& fileDefinitions,
   cmWIXFeaturesSourceWriter& featureDefinitions,
-  shortcut_map_t& shortcutMap)
+  cmWIXShortcuts& shortcuts)
 {
   featureDefinitions.BeginElement("FeatureRef");
   featureDefinitions.AddAttribute("Id", featureId);
@@ -682,21 +683,82 @@ bool cmCPackWIXGenerator::AddComponentsToFeature(
     rootPath, "INSTALL_ROOT",
     directoryDefinitions, fileDefinitions, featureDefinitions,
     cpackPackageExecutablesList, cpackPackageDesktopLinksList,
-    shortcutMap);
+    shortcuts);
 
   featureDefinitions.EndElement("FeatureRef");
 
   return true;
 }
 
-bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
+bool cmCPackWIXGenerator::CreateShortcuts(
+  std::string const& cpackComponentName,
+  std::string const& featureId,
+  cmWIXShortcuts const& shortcuts,
+  bool emitUninstallShortcut,
+  cmWIXFilesSourceWriter& fileDefinitions,
+  cmWIXFeaturesSourceWriter& featureDefinitions)
+{
+  if(!shortcuts.empty(cmWIXShortcuts::START_MENU))
+    {
+    if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::START_MENU,
+      cpackComponentName, featureId, "",
+      shortcuts, emitUninstallShortcut,
+      fileDefinitions, featureDefinitions))
+      {
+      return false;
+      }
+    }
+
+  if(!shortcuts.empty(cmWIXShortcuts::DESKTOP))
+    {
+    if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::DESKTOP,
+      cpackComponentName, featureId, "DESKTOP",
+      shortcuts, false,
+      fileDefinitions, featureDefinitions))
+      {
+      return false;
+      }
+    }
+
+  if(!shortcuts.empty(cmWIXShortcuts::STARTUP))
+    {
+    if(!this->CreateShortcutsOfSpecificType(cmWIXShortcuts::STARTUP,
+      cpackComponentName, featureId, "STARTUP",
+      shortcuts, false,
+      fileDefinitions, featureDefinitions))
+      {
+      return false;
+      }
+    }
+
+  return true;
+}
+
+bool cmCPackWIXGenerator::CreateShortcutsOfSpecificType(
+  cmWIXShortcuts::Type type,
   std::string const& cpackComponentName,
   std::string const& featureId,
-  shortcut_map_t& shortcutMap,
+  std::string const& idPrefix,
+  cmWIXShortcuts const& shortcuts,
+  bool emitUninstallShortcut,
   cmWIXFilesSourceWriter& fileDefinitions,
   cmWIXFeaturesSourceWriter& featureDefinitions)
 {
-  bool thisHasDesktopShortcuts = false;
+  std::string directoryId;
+  switch(type)
+    {
+    case cmWIXShortcuts::START_MENU:
+      directoryId = "PROGRAM_MENU_FOLDER";
+      break;
+    case cmWIXShortcuts::DESKTOP:
+      directoryId = "DesktopFolder";
+      break;
+    case cmWIXShortcuts::STARTUP:
+      directoryId = "StartupFolder";
+      break;
+    default:
+      return false;
+    }
 
   featureDefinitions.BeginElement("FeatureRef");
   featureDefinitions.AddAttribute("Id", featureId);
@@ -720,80 +782,42 @@ bool cmCPackWIXGenerator::CreateStartMenuShortcuts(
       idSuffix += cpackComponentName;
     }
 
-  std::string componentId = "CM_SHORTCUT" + idSuffix;
+  std::string componentId = "CM_SHORTCUT";
+  if(idPrefix.size())
+    {
+    componentId += "_" + idPrefix;
+    }
+
+  componentId += idSuffix;
 
   fileDefinitions.BeginElement("DirectoryRef");
-  fileDefinitions.AddAttribute("Id", "PROGRAM_MENU_FOLDER");
+  fileDefinitions.AddAttribute("Id", directoryId);
 
   fileDefinitions.BeginElement("Component");
   fileDefinitions.AddAttribute("Id", componentId);
   fileDefinitions.AddAttribute("Guid", "*");
 
-  for(shortcut_map_t::const_iterator
-    i = shortcutMap.begin(); i != shortcutMap.end(); ++i)
-    {
-    std::string const& id = i->first;
-    cmWIXShortcut const& shortcut = i->second;
+  std::string registryKey = std::string("Software\\") +
+    cpackVendor + "\\" + cpackPackageName;
 
-    fileDefinitions.EmitShortcut(id, shortcut, false);
+  shortcuts.EmitShortcuts(type, registryKey,
+    cpackComponentName, fileDefinitions);
 
-    if(shortcut.desktop)
-      {
-      thisHasDesktopShortcuts = true;
-      }
+  if(type == cmWIXShortcuts::START_MENU)
+    {
+    fileDefinitions.EmitRemoveFolder(
+      "CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix);
     }
 
-  if(cpackComponentName.empty())
+  if(emitUninstallShortcut)
     {
     fileDefinitions.EmitUninstallShortcut(cpackPackageName);
     }
 
-  fileDefinitions.EmitRemoveFolder(
-    "CM_REMOVE_PROGRAM_MENU_FOLDER" + idSuffix);
-
-  std::string registryKey =
-    std::string("Software\\") + cpackVendor + "\\" + cpackPackageName;
-
-  fileDefinitions.EmitStartMenuShortcutRegistryValue(
-    registryKey, cpackComponentName);
-
   fileDefinitions.EndElement("Component");
   fileDefinitions.EndElement("DirectoryRef");
 
   featureDefinitions.EmitComponentRef(componentId);
-
-  if(thisHasDesktopShortcuts)
-    {
-    this->HasDesktopShortcuts = true;
-    componentId = "CM_DESKTOP_SHORTCUT" + idSuffix;
-
-    fileDefinitions.BeginElement("DirectoryRef");
-    fileDefinitions.AddAttribute("Id", "DesktopFolder");
-    fileDefinitions.BeginElement("Component");
-    fileDefinitions.AddAttribute("Id", componentId);
-    fileDefinitions.AddAttribute("Guid", "*");
-
-    for(shortcut_map_t::const_iterator
-      i = shortcutMap.begin(); i != shortcutMap.end(); ++i)
-      {
-      std::string const& id = i->first;
-      cmWIXShortcut const& shortcut = i->second;
-
-      if (!shortcut.desktop)
-        continue;
-
-      fileDefinitions.EmitShortcut(id, shortcut, true);
-      }
-
-    fileDefinitions.EmitDesktopShortcutRegistryValue(
-      registryKey, cpackComponentName);
-
-    fileDefinitions.EndElement("Component");
-    fileDefinitions.EndElement("DirectoryRef");
-
-    featureDefinitions.EmitComponentRef(componentId);
-    }
-
   featureDefinitions.EndElement("FeatureRef");
 
   return true;
@@ -852,9 +876,9 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
   cmWIXDirectoriesSourceWriter& directoryDefinitions,
   cmWIXFilesSourceWriter& fileDefinitions,
   cmWIXFeaturesSourceWriter& featureDefinitions,
-  const std::vector<std::string>& packageExecutables,
-  const std::vector<std::string>& desktopExecutables,
-  shortcut_map_t& shortcutMap)
+  std::vector<std::string> const& packageExecutables,
+  std::vector<std::string> const& desktopExecutables,
+  cmWIXShortcuts& shortcuts)
 {
   cmsys::Directory dir;
   dir.Load(topdir.c_str());
@@ -929,7 +953,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
         featureDefinitions,
         packageExecutables,
         desktopExecutables,
-        shortcutMap);
+        shortcuts);
 
       this->Patch->ApplyFragment(subDirectoryId, directoryDefinitions);
       directoryDefinitions.EndElement("Directory");
@@ -939,6 +963,11 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
       cmInstalledFile const* installedFile =
         this->GetInstalledFile(relativePath);
 
+      if(installedFile)
+        {
+        shortcuts.CreateFromProperties(id, directoryId, *installedFile);
+        }
+
       std::string componentId = fileDefinitions.EmitComponentFile(
         directoryId, id, fullPath, *(this->Patch), installedFile);
 
@@ -952,9 +981,10 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
         if(cmSystemTools::LowerCase(fileName) ==
             cmSystemTools::LowerCase(executableName) + ".exe")
           {
-          cmWIXShortcut &shortcut = shortcutMap[id];
-          shortcut.textLabel= textLabel;
+          cmWIXShortcut shortcut;
+          shortcut.label= textLabel;
           shortcut.workingDirectoryId = directoryId;
+          shortcuts.insert(cmWIXShortcuts::START_MENU, id, shortcut);
 
           if(desktopExecutables.size() &&
              std::find(desktopExecutables.begin(),
@@ -962,7 +992,7 @@ void cmCPackWIXGenerator::AddDirectoryAndFileDefinitons(
                        executableName)
              != desktopExecutables.end())
             {
-              shortcut.desktop = true;
+              shortcuts.insert(cmWIXShortcuts::DESKTOP, id, shortcut);
             }
           }
         }

+ 17 - 9
Source/CPack/WiX/cmCPackWIXGenerator.h

@@ -65,7 +65,6 @@ protected:
 private:
   typedef std::map<std::string, std::string> id_map_t;
   typedef std::map<std::string, size_t> ambiguity_map_t;
-  typedef std::map<std::string, cmWIXShortcut> shortcut_map_t;
   typedef std::set<std::string> extension_set_t;
 
   bool InitializeWiXConfiguration();
@@ -99,12 +98,23 @@ private:
     cmWIXDirectoriesSourceWriter& directoryDefinitions,
     cmWIXFilesSourceWriter& fileDefinitions,
     cmWIXFeaturesSourceWriter& featureDefinitions,
-    shortcut_map_t& shortcutMap);
+    cmWIXShortcuts& shortcuts);
 
-  bool CreateStartMenuShortcuts(
+  bool CreateShortcuts(
     std::string const& cpackComponentName,
     std::string const& featureId,
-    shortcut_map_t& shortcutMap,
+    cmWIXShortcuts const& shortcuts,
+    bool emitUninstallShortcut,
+    cmWIXFilesSourceWriter& fileDefinitions,
+    cmWIXFeaturesSourceWriter& featureDefinitions);
+
+  bool CreateShortcutsOfSpecificType(
+    cmWIXShortcuts::Type type,
+    std::string const& cpackComponentName,
+    std::string const& featureId,
+    std::string const& idPrefix,
+    cmWIXShortcuts const& shortcuts,
+    bool emitUninstallShortcut,
     cmWIXFilesSourceWriter& fileDefinitions,
     cmWIXFeaturesSourceWriter& featureDefinitions);
 
@@ -126,9 +136,9 @@ private:
     cmWIXDirectoriesSourceWriter& directoryDefinitions,
     cmWIXFilesSourceWriter& fileDefinitions,
     cmWIXFeaturesSourceWriter& featureDefinitions,
-    const std::vector<std::string>& pkgExecutables,
-    const std::vector<std::string>& desktopExecutables,
-    shortcut_map_t& shortcutMap);
+    std::vector<std::string> const& packageExecutables,
+    std::vector<std::string> const& desktopExecutables,
+    cmWIXShortcuts& shortcuts);
 
   bool RequireOption(std::string const& name, std::string& value) const;
 
@@ -165,8 +175,6 @@ private:
   extension_set_t CandleExtensions;
   extension_set_t LightExtensions;
 
-  bool HasDesktopShortcuts;
-
   std::string CPackTopLevel;
 
   cmWIXPatch* Patch;

+ 8 - 0
Source/CPack/WiX/cmWIXDirectoriesSourceWriter.cxx

@@ -41,6 +41,14 @@ void cmWIXDirectoriesSourceWriter::EmitDesktopFolder()
   EndElement("Directory");
 }
 
+void cmWIXDirectoriesSourceWriter::EmitStartupFolder()
+{
+  BeginElement("Directory");
+  AddAttribute("Id", "StartupFolder");
+  AddAttribute("Name", "Startup");
+  EndElement("Directory");
+}
+
 size_t cmWIXDirectoriesSourceWriter::BeginInstallationPrefixDirectory(
   std::string const& programFilesFolderId,
   std::string const& installRootString)

+ 2 - 0
Source/CPack/WiX/cmWIXDirectoriesSourceWriter.h

@@ -32,6 +32,8 @@ public:
 
   void EmitDesktopFolder();
 
+  void EmitStartupFolder();
+
   size_t BeginInstallationPrefixDirectory(
       std::string const& programFilesFolderId,
       std::string const& installRootString);

+ 9 - 27
Source/CPack/WiX/cmWIXFilesSourceWriter.cxx

@@ -1,6 +1,6 @@
 /*============================================================================
   CMake - Cross Platform Makefile Generator
-  Copyright 2014 Kitware, Inc.
+  Copyright 2014-2015 Kitware, Inc.
 
   Distributed under the OSI-approved BSD License (the "License");
   see accompanying file Copyright.txt for details.
@@ -28,26 +28,22 @@ cmWIXFilesSourceWriter::cmWIXFilesSourceWriter(cmCPackLog* logger,
 void cmWIXFilesSourceWriter::EmitShortcut(
   std::string const& id,
   cmWIXShortcut const& shortcut,
-  bool desktop)
+  std::string const& shortcutPrefix,
+  size_t shortcutIndex)
 {
-  std::string shortcutId;
+  std::stringstream shortcutId;
+  shortcutId << shortcutPrefix << id;
 
-  if(desktop)
+  if(shortcutIndex > 0)
     {
-    shortcutId = "CM_DS";
+    shortcutId << "_"  << shortcutIndex;
     }
-  else
-    {
-    shortcutId = "CM_S";
-    }
-
-  shortcutId += id;
 
   std::string fileId = std::string("CM_F") + id;
 
   BeginElement("Shortcut");
-  AddAttribute("Id", shortcutId);
-  AddAttribute("Name", shortcut.textLabel);
+  AddAttribute("Id", shortcutId.str());
+  AddAttribute("Name", shortcut.label);
   std::string target = "[#" + fileId + "]";
   AddAttribute("Target", target);
   AddAttribute("WorkingDirectory", shortcut.workingDirectoryId);
@@ -62,20 +58,6 @@ void cmWIXFilesSourceWriter::EmitRemoveFolder(std::string const& id)
   EndElement("RemoveFolder");
 }
 
-void cmWIXFilesSourceWriter::EmitStartMenuShortcutRegistryValue(
-  std::string const& registryKey,
-  std::string const& cpackComponentName)
-{
-  EmitInstallRegistryValue(registryKey, cpackComponentName, std::string());
-}
-
-void cmWIXFilesSourceWriter::EmitDesktopShortcutRegistryValue(
-  std::string const& registryKey,
-  std::string const& cpackComponentName)
-{
-  EmitInstallRegistryValue(registryKey, cpackComponentName, "_desktop");
-}
-
 void cmWIXFilesSourceWriter::EmitInstallRegistryValue(
   std::string const& registryKey,
   std::string const& cpackComponentName,

+ 6 - 14
Source/CPack/WiX/cmWIXFilesSourceWriter.h

@@ -1,6 +1,6 @@
 /*============================================================================
   CMake - Cross Platform Makefile Generator
-  Copyright 2014 Kitware, Inc.
+  Copyright 2014-2015 Kitware, Inc.
 
   Distributed under the OSI-approved BSD License (the "License");
   see accompanying file Copyright.txt for details.
@@ -31,17 +31,15 @@ public:
   void EmitShortcut(
       std::string const& id,
       cmWIXShortcut const& shortcut,
-      bool desktop);
+      std::string const& shortcutPrefix,
+      size_t shortcutIndex);
 
   void EmitRemoveFolder(std::string const& id);
 
-  void EmitStartMenuShortcutRegistryValue(
-    std::string const& registryKey,
-    std::string const& cpackComponentName);
-
-  void EmitDesktopShortcutRegistryValue(
+  void EmitInstallRegistryValue(
     std::string const& registryKey,
-    std::string const& cpackComponentName);
+    std::string const& cpackComponentName,
+    std::string const& suffix);
 
   void EmitUninstallShortcut(std::string const& packageName);
 
@@ -56,12 +54,6 @@ public:
     std::string const& filePath,
     cmWIXPatch &patch,
     cmInstalledFile const* installedFile);
-
-private:
-  void EmitInstallRegistryValue(
-    std::string const& registryKey,
-    std::string const& cpackComponentName,
-    std::string const& suffix);
 };
 
 

+ 125 - 0
Source/CPack/WiX/cmWIXShortcut.cxx

@@ -0,0 +1,125 @@
+/*============================================================================
+  CMake - Cross Platform Makefile Generator
+  Copyright 2015 Kitware, Inc.
+
+  Distributed under the OSI-approved BSD License (the "License");
+  see accompanying file Copyright.txt for details.
+
+  This software is distributed WITHOUT ANY WARRANTY; without even the
+  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+  See the License for more information.
+============================================================================*/
+
+#include "cmWIXShortcut.h"
+
+#include "cmWIXFilesSourceWriter.h"
+
+void cmWIXShortcuts::insert(
+  Type type, std::string const& id, cmWIXShortcut const& shortcut)
+{
+  this->Shortcuts[type][id].push_back(shortcut);
+}
+
+bool cmWIXShortcuts::empty(Type type) const
+{
+  return this->Shortcuts.find(type) == this->Shortcuts.end();
+}
+
+bool cmWIXShortcuts::EmitShortcuts(
+  Type type,
+  std::string const& registryKey,
+  std::string const& cpackComponentName,
+  cmWIXFilesSourceWriter& fileDefinitions) const
+{
+  shortcut_type_map_t::const_iterator i = this->Shortcuts.find(type);
+
+  if(i == this->Shortcuts.end())
+    {
+    return false;
+    }
+
+  shortcut_id_map_t const& id_map = i->second;
+
+  std::string shortcutPrefix;
+  std::string registrySuffix;
+
+  switch(type)
+    {
+    case START_MENU:
+      shortcutPrefix = "CM_S";
+      break;
+    case DESKTOP:
+      shortcutPrefix = "CM_DS";
+      registrySuffix = "_desktop";
+      break;
+    case STARTUP:
+      shortcutPrefix = "CM_SS";
+      registrySuffix = "_startup";
+      break;
+    default:
+      return false;
+    }
+
+  for(shortcut_id_map_t::const_iterator j = id_map.begin();
+    j != id_map.end(); ++j)
+    {
+    std::string const& id = j->first;
+    shortcut_list_t const& shortcutList = j->second;
+
+    for(size_t shortcutListIndex = 0;
+      shortcutListIndex < shortcutList.size(); ++shortcutListIndex)
+      {
+      cmWIXShortcut const& shortcut = shortcutList[shortcutListIndex];
+      fileDefinitions.EmitShortcut(id, shortcut,
+        shortcutPrefix, shortcutListIndex);
+      }
+    }
+
+  fileDefinitions.EmitInstallRegistryValue(
+    registryKey, cpackComponentName, registrySuffix);
+
+  return true;
+}
+
+void cmWIXShortcuts::AddShortcutTypes(std::set<Type>& types)
+{
+  for(shortcut_type_map_t::const_iterator i = this->Shortcuts.begin();
+    i != this->Shortcuts.end(); ++i)
+    {
+    types.insert(i->first);
+    }
+}
+
+void cmWIXShortcuts::CreateFromProperties(
+  std::string const& id,
+  std::string const& directoryId,
+  cmInstalledFile const& installedFile)
+{
+  CreateFromProperty("CPACK_START_MENU_SHORTCUTS",
+    START_MENU, id, directoryId, installedFile);
+
+  CreateFromProperty("CPACK_DESKTOP_SHORTCUTS",
+    DESKTOP, id, directoryId, installedFile);
+
+  CreateFromProperty("CPACK_STARTUP_SHORTCUTS",
+    STARTUP, id, directoryId, installedFile);
+}
+
+void cmWIXShortcuts::CreateFromProperty(
+  std::string const& propertyName,
+  Type type,
+  std::string const& id,
+  std::string const& directoryId,
+  cmInstalledFile const& installedFile)
+{
+  std::vector<std::string> list;
+  installedFile.GetPropertyAsList(propertyName, list);
+
+  for(size_t i = 0; i < list.size(); ++i)
+    {
+    cmWIXShortcut shortcut;
+    shortcut.label = list[i];
+    shortcut.workingDirectoryId = directoryId;
+    insert(type, id, shortcut);
+    }
+}

+ 53 - 9
Source/CPack/WiX/cmWIXShortcut.h

@@ -1,6 +1,6 @@
 /*============================================================================
   CMake - Cross Platform Makefile Generator
-  Copyright 2014 Kitware, Inc.
+  Copyright 2014-2015 Kitware, Inc.
 
   Distributed under the OSI-approved BSD License (the "License");
   see accompanying file Copyright.txt for details.
@@ -10,20 +10,64 @@
   See the License for more information.
 ============================================================================*/
 
-#ifndef cmWIXFilesShortcut_h
-#define cmWIXFilesShortcut_h
+#ifndef cmWIXShortcut_h
+#define cmWIXShortcut_h
 
 #include <string>
+#include <map>
+#include <set>
+#include <vector>
+
+#include <cmInstalledFile.h>
+
+class cmWIXFilesSourceWriter;
 
 struct cmWIXShortcut
 {
-  cmWIXShortcut()
-    :desktop(false)
-    {}
-
-  std::string textLabel;
+  std::string label;
   std::string workingDirectoryId;
-  bool desktop;
+};
+
+class cmWIXShortcuts
+{
+public:
+  enum Type
+  {
+    START_MENU,
+    DESKTOP,
+    STARTUP
+  };
+
+  typedef std::vector<cmWIXShortcut> shortcut_list_t;
+  typedef std::map<std::string, shortcut_list_t> shortcut_id_map_t;
+
+  void insert(Type type, std::string const& id, cmWIXShortcut const& shortcut);
+
+  bool empty(Type type) const;
+
+  bool EmitShortcuts(
+    Type type,
+    std::string const& registryKey,
+    std::string const& cpackComponentName,
+    cmWIXFilesSourceWriter& fileDefinitions) const;
+
+  void AddShortcutTypes(std::set<Type>& types);
+
+  void CreateFromProperties(std::string const& id,
+    std::string const& directoryId, cmInstalledFile const& installedFile);
+
+private:
+  typedef std::map<Type, shortcut_id_map_t> shortcut_type_map_t;
+
+  void CreateFromProperty(
+    std::string const& propertyName,
+    Type type,
+    std::string const& id,
+    std::string const& directoryId,
+    cmInstalledFile const& installedFile);
+
+  shortcut_type_map_t Shortcuts;
+  shortcut_id_map_t EmptyIdMap;
 };
 
 #endif