ctkCmdLineModuleXmlToQtUi.xsl 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <xsl:stylesheet version="2.0"
  3. xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  4. xmlns:xs="http://www.w3.org/2001/XMLSchema"
  5. xmlns:fn="http://www.w3.org/2005/xpath-functions"
  6. xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
  7. xmlns:err="http://www.w3.org/2005/xqt-errors"
  8. xmlns:ctk="http://www.commontk.org"
  9. exclude-result-prefixes="xs xdt err fn">
  10. <xsl:output method="xml" indent="yes"/>
  11. <!--
  12. ===================================================================
  13. Utility XSLT 2.0 functions
  14. ===================================================================
  15. -->
  16. <!-- Map xml parameter element names (types) to the proper QtDesigner UI element. -->
  17. <xsl:function name="ctk:mapTypeToQtDesigner">
  18. <xsl:param name="cliType"/>
  19. <xsl:choose>
  20. <xsl:when test="$cliType='boolean'">bool</xsl:when>
  21. <xsl:when test="$cliType='integer'">number</xsl:when>
  22. <xsl:when test="$cliType='float'">double</xsl:when>
  23. <xsl:when test="$cliType=('point', 'region', 'image', 'file', 'directory', 'geometry', 'integer-vector', 'double-vector', 'float-vector', 'string-vector', 'integer-enumeration', 'double-enumeration', 'float-enumeration', 'string-enumeration')">string</xsl:when>
  24. <xsl:otherwise><xsl:value-of select="$cliType"/></xsl:otherwise>
  25. </xsl:choose>
  26. </xsl:function>
  27. <!-- Map xml parameter element names (types) to C++ types. -->
  28. <xsl:function name="ctk:mapTypeToCpp">
  29. <xsl:param name="cliType"/>
  30. <xsl:choose>
  31. <xsl:when test="$cliType=('integer', 'integer-enumeration')">int</xsl:when>
  32. <xsl:when test="$cliType='boolean'">bool</xsl:when>
  33. <xsl:when test="$cliType=('string', 'string-enumeration', 'image', 'file', 'directory', 'geometry')">std::string</xsl:when>
  34. <xsl:when test="$cliType='integer-vector'">std::vector&lt;int&gt;</xsl:when>
  35. <xsl:when test="$cliType=('double-vector', 'point', 'region')">std::vector&lt;double&gt;</xsl:when>
  36. <xsl:when test="$cliType='float-vector'">std::vector&lt;float&gt;</xsl:when>
  37. <xsl:when test="$cliType='string-vector'">std::vector&lt;std::string&gt;</xsl:when>
  38. <xsl:when test="$cliType='float-enumeration'">float</xsl:when>
  39. <xsl:when test="$cliType='double-enumeration'">double</xsl:when>
  40. <xsl:otherwise><xsl:value-of select="$cliType"/></xsl:otherwise>
  41. </xsl:choose>
  42. </xsl:function>
  43. <!-- Map xml parameter element names (types) to the Qt widget property containing
  44. the current value. The property type should match the Qt C++ type above
  45. (or be convertible to it). -->
  46. <xsl:function name="ctk:mapTypeToQtValueProperty">
  47. <xsl:param name="cliType"/>
  48. <xsl:choose>
  49. <xsl:when test="$cliType='boolean'">checked</xsl:when>
  50. <xsl:when test="$cliType= ('point', 'region')">coordinates</xsl:when>
  51. <xsl:when test="$cliType= ('image', 'file', 'directory', 'geometry')">currentPath</xsl:when>
  52. <xsl:when test="$cliType= ('string', 'integer-vector', 'float-vector', 'double-vector', 'string-vector')">text</xsl:when>
  53. <xsl:when test="$cliType= ('integer-enumeration', 'float-enumeration', 'double-enumeration', 'string-enumeration')">currentText</xsl:when>
  54. <xsl:otherwise>value</xsl:otherwise>
  55. </xsl:choose>
  56. </xsl:function>
  57. <!--
  58. ===================================================================
  59. Default templates for suppressing output if no more specific template exists
  60. ===================================================================
  61. -->
  62. <!-- suppress text and attribute nodes not covered in subsequent template rule -->
  63. <xsl:template match="text()|@*"/>
  64. <!-- suppress elements not covered in "connections" mode -->
  65. <xsl:template match="*" mode="connections"/>
  66. <!-- suppress elements not covered in "signals" mode -->
  67. <xsl:template match="*" mode="signals"/>
  68. <!-- This guarantees that elements that don't match the dynamicProperties mode don't get output -->
  69. <xsl:template match="*" mode="dynamicProperties"/>
  70. <!--
  71. ===================================================================
  72. Templates for generating connections between generated widgets
  73. ===================================================================
  74. -->
  75. <xsl:template match="parameters/*[name()=('image','file','directory','geometry')]" mode="connections">
  76. <connection>
  77. <sender><xsl:value-of select="name"/>BrowseButton</sender>
  78. <signal>clicked()</signal>
  79. <receiver>parameter:<xsl:value-of select="name"/></receiver>
  80. <slot>browse()</slot>
  81. </connection>
  82. </xsl:template>
  83. <!--
  84. ===================================================================
  85. Utility templates
  86. ===================================================================
  87. -->
  88. <xsl:template match="parameters/label">
  89. <property name="title">
  90. <string><xsl:value-of select="text()"/></string>
  91. </property>
  92. </xsl:template>
  93. <!-- Add a tooltip property to a widget -->
  94. <xsl:template match="description">
  95. <property name="toolTip">
  96. <string><xsl:value-of select="text()"/></string>
  97. </property>
  98. </xsl:template>
  99. <!-- Set the default value by generating a Qt widget specific property which holds
  100. the current value -->
  101. <xsl:template match="default">
  102. <property name="{ctk:mapTypeToQtValueProperty(name(..))}">
  103. <xsl:element name="{ctk:mapTypeToQtDesigner(name(..))}"><xsl:value-of select="text()"/></xsl:element>
  104. </property>
  105. </xsl:template>
  106. <!-- Set Qt widget (spinbox) specific properties for applying constraints of scalar parameters -->
  107. <xsl:template match="constraints/*[name()=('minimum','maximum')]">
  108. <property name="{name()}">
  109. <xsl:element name="{ctk:mapTypeToQtDesigner(name(../..))}"><xsl:value-of select="text()"/></xsl:element>
  110. </property>
  111. </xsl:template>
  112. <xsl:template match="constraints/step">
  113. <property name="singleStep">
  114. <xsl:element name="{ctk:mapTypeToQtDesigner(name(../..))}"><xsl:value-of select="text()"/></xsl:element>
  115. </property>
  116. <!-- Also add the 'step' information under the original name -->
  117. <property name="parameter:step">
  118. <string><xsl:value-of select="text()"/></string>
  119. </property>
  120. </xsl:template>
  121. <!-- A named template which will be called from each parameter (integer, float, image, etc.) element.
  122. It assumes that it will be called from an enclosing Qt grid layout element and adds a label item -->
  123. <xsl:template name="gridItemWithLabel">
  124. <item row="{position()-1}" column="0">
  125. <widget class="QLabel">
  126. <property name="sizePolicy">
  127. <sizepolicy hsizetype="Fixed" vsizetype="Preferred">
  128. <horstretch>0</horstretch>
  129. <verstretch>0</verstretch>
  130. </sizepolicy>
  131. </property>
  132. <property name="text">
  133. <string><xsl:value-of select="./label"/></string>
  134. </property>
  135. </widget>
  136. </item>
  137. </xsl:template>
  138. <!-- General template for adding dynamic Qt properties to widgets -->
  139. <xsl:template match="*" mode="dynamicProperty">
  140. <property name="parameter:{name()}">
  141. <string><xsl:value-of select="text()"/></string>
  142. </property>
  143. </xsl:template>
  144. <!-- Exclude certain elements from the set of dynamic properties -->
  145. <xsl:template match="*[not(name()=('name', 'constraints'))]" mode="dynamicProperties">
  146. <xsl:apply-templates select="." mode="dynamicProperty"/>
  147. </xsl:template>
  148. <!-- A named template for adding properties common to all Qt widgets -->
  149. <xsl:template name="commonWidgetProperties">
  150. <xsl:apply-templates select="description"/> <!-- tooltip -->
  151. <xsl:if test="@hidden='true'"> <!-- widget visibility -->
  152. <property name="visible">
  153. <bool>false</bool>
  154. </property>
  155. </xsl:if>
  156. <property name="parameter:cppType">
  157. <string><xsl:value-of select="ctk:mapTypeToCpp(name())"/></string>
  158. </property>
  159. <property name="parameter:valueProperty">
  160. <string><xsl:value-of select="ctk:mapTypeToQtValueProperty(name())"/></string>
  161. </property>
  162. <!-- add additional (optional) information as properties -->
  163. <xsl:apply-templates select="default"/>
  164. <xsl:apply-templates select="constraints"/>
  165. <xsl:apply-templates select="./child::*" mode="dynamicProperties"/>
  166. </xsl:template>
  167. <!-- A named template for creating a QtDesigner stringlist property -->
  168. <xsl:template name="createQtDesignerStringListProperty">
  169. <property name="nameFilters">
  170. <stringlist>
  171. <xsl:for-each select="tokenize(@fileExtensions, ',')">
  172. <string><xsl:value-of select="normalize-space(.)"/></string>
  173. </xsl:for-each>
  174. </stringlist>
  175. </property>
  176. </xsl:template>
  177. <!--
  178. ===================================================================
  179. Match elements from the XML description
  180. ===================================================================
  181. -->
  182. <!-- start matching at 'executable' element -->
  183. <xsl:template match="/executable">
  184. <xsl:variable name="moduleTitle"><xsl:value-of select="title"/></xsl:variable>
  185. <ui version="4.0" >
  186. <class><xsl:value-of select="translate(normalize-space($moduleTitle), ' ', '')"/></class>
  187. <widget class="QWidget" name="executable:{normalize-space($moduleTitle)}">
  188. <layout class="QVBoxLayout">
  189. <!-- This will generate QGroupBox items with the specific widgets -->
  190. <xsl:apply-templates select="parameters"/>
  191. <!-- Add a spacer at the bottom -->
  192. <item>
  193. <spacer name="verticalSpacer">
  194. <property name="orientation">
  195. <enum>Qt::Vertical</enum>
  196. </property>
  197. </spacer>
  198. </item>
  199. </layout>
  200. </widget>
  201. <connections>
  202. <xsl:apply-templates mode="connections" select="parameters/*"/>
  203. </connections>
  204. </ui>
  205. </xsl:template>
  206. <!-- Match the 'parameters' element and create the parameter groups (QGroupBox) -->
  207. <xsl:template match="parameters">
  208. <xsl:variable name="groupLabel"><xsl:value-of select="label"/></xsl:variable>
  209. <item>
  210. <widget class="ctkCollapsibleGroupBox" name="paramGroup:{$groupLabel}">
  211. <xsl:apply-templates select="./label"/>
  212. <xsl:apply-templates select="./description"/>
  213. <property name="checked">
  214. <bool><xsl:value-of select="not(@advanced)"></xsl:value-of></bool>
  215. </property>
  216. <layout class="QGridLayout">
  217. <xsl:apply-templates select="./description/following-sibling::*"/>
  218. </layout>
  219. </widget>
  220. </item>
  221. </xsl:template>
  222. <!--
  223. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  224. BOOLEAN parameter (default: QCheckbox)
  225. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  226. -->
  227. <xsl:template match="parameters/boolean">
  228. <xsl:call-template name="gridItemWithLabel"/>
  229. <item row="{position()-1}" column="1">
  230. <widget class="QCheckBox" name="parameter:{name}">
  231. <xsl:call-template name="commonWidgetProperties"/>
  232. <property name="text">
  233. <string/>
  234. </property>
  235. </widget>
  236. </item>
  237. </xsl:template>
  238. <!--
  239. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  240. INTEGER parameter (default: QSpinBox)
  241. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  242. -->
  243. <xsl:template match="parameters/integer">
  244. <xsl:call-template name="gridItemWithLabel"/>
  245. <item row="{position()-1}" column="1">
  246. <widget class="QSpinBox" name="parameter:{name}">
  247. <xsl:if test="not(constraints)">
  248. <property name="minimum">
  249. <number>-999999999</number>
  250. </property>
  251. <property name="maximum">
  252. <number>999999999</number>
  253. </property>
  254. </xsl:if>
  255. <xsl:call-template name="commonWidgetProperties"/>
  256. </widget>
  257. </item>
  258. </xsl:template>
  259. <!--
  260. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  261. DOUBLE, FLOAT parameter (default: QDoubleSpinBox)
  262. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  263. -->
  264. <xsl:template match="parameters/*[name()=('double','float')]">
  265. <xsl:call-template name="gridItemWithLabel"/>
  266. <item row="{position()-1}" column="1">
  267. <widget class="QDoubleSpinBox" name="parameter:{name}">
  268. <property name="decimals">
  269. <number>6</number>
  270. </property>
  271. <xsl:if test="not(constraints)">
  272. <property name="minimum">
  273. <double>-999999999</double>
  274. </property>
  275. <property name="maximum">
  276. <double>999999999</double>
  277. </property>
  278. </xsl:if>
  279. <xsl:call-template name="commonWidgetProperties"/>
  280. </widget>
  281. </item>
  282. </xsl:template>
  283. <!--
  284. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  285. INTEGER-VECTOR, DOUBLE-VECTOR, FLOAT-VECTOR, STRING-VECTOR parameter (default: QLineEdit)
  286. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  287. -->
  288. <xsl:template match="parameters/*[name()=('integer-vector', 'float-vector', 'double-vector', 'string-vector')]">
  289. <xsl:call-template name="gridItemWithLabel"/>
  290. <item row="{position()-1}" column="1">
  291. <widget class="QLineEdit" name="parameter:{name}">
  292. <xsl:call-template name="commonWidgetProperties"/>
  293. </widget>
  294. </item>
  295. </xsl:template>
  296. <!--
  297. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  298. INTEGER-ENUMERATION, DOUBLE-ENUMERATION, FLOAT-ENUMERATION, STRING-ENUMERATION parameter (default: QComboBox)
  299. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  300. -->
  301. <xsl:template match="parameters/*[name()=('integer-enumeration', 'float-enumeration', 'double-enumeration', 'string-enumeration')]">
  302. <xsl:call-template name="gridItemWithLabel"/>
  303. <item row="{position()-1}" column="1">
  304. <widget class="QComboBox" name="parameter:{name}">
  305. <xsl:call-template name="commonWidgetProperties"/>
  306. <xsl:for-each select="element">
  307. <item>
  308. <property name="text">
  309. <string><xsl:value-of select="text()"/></string>
  310. </property>
  311. </item>
  312. </xsl:for-each>
  313. </widget>
  314. </item>
  315. </xsl:template>
  316. <!--
  317. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  318. IMAGE, FILE, GEOMETRY parameter (default: ctkPathLineEdit)
  319. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  320. -->
  321. <xsl:template match="parameters/*[name()=('image', 'file', 'geometry')]">
  322. <xsl:call-template name="gridItemWithLabel"/>
  323. <item row="{position()-1}" column="1">
  324. <layout class="QHBoxLayout">
  325. <item>
  326. <widget class="ctkPathLineEdit" name="parameter:{name}">
  327. <xsl:call-template name="commonWidgetProperties"/>
  328. <xsl:call-template name="createQtDesignerStringListProperty"/>
  329. </widget>
  330. </item>
  331. <item>
  332. <widget class="QPushButton" name="{name}BrowseButton">
  333. <property name="text">
  334. <string>Browse...</string>
  335. </property>
  336. </widget>
  337. </item>
  338. </layout>
  339. </item>
  340. </xsl:template>
  341. <!--
  342. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  343. DIRECTORY parameter (default: ctkPathLineEdit)
  344. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  345. -->
  346. <xsl:template match="parameters/directory">
  347. <xsl:call-template name="gridItemWithLabel"/>
  348. <item row="{position()-1}" column="1">
  349. <layout class="QHBoxLayout">
  350. <item>
  351. <widget class="ctkPathLineEdit" name="parameter:{name}">
  352. <xsl:call-template name="commonWidgetProperties"/>
  353. <property name="options">
  354. <set>ctkPathLineEdit::ShowDirsOnly</set>
  355. </property>
  356. </widget>
  357. </item>
  358. <item>
  359. <widget class="QPushButton" name="{name}BrowseButton">
  360. <property name="text">
  361. <string>Browse...</string>
  362. </property>
  363. </widget>
  364. </item>
  365. </layout>
  366. </item>
  367. </xsl:template>
  368. <!--
  369. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  370. POINT, REGION parameter (default: ctkCoordinatesWidget)
  371. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  372. -->
  373. <xsl:template match="parameters/*[name()=('point', 'region')]">
  374. <xsl:call-template name="gridItemWithLabel"/>
  375. <item row="{position()-1}" column="1">
  376. <widget class="ctkCoordinatesWidget" name="parameter:{name}">
  377. <xsl:call-template name="commonWidgetProperties"/>
  378. </widget>
  379. </item>
  380. </xsl:template>
  381. <!--
  382. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  383. NOT IMPLEMENTED YET
  384. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  385. -->
  386. <xsl:template match="parameters/*" priority="-1">
  387. <xsl:call-template name="gridItemWithLabel"/>
  388. <item row="{position()-1}" column="1">
  389. <widget class="QLabel" name="{name}">
  390. <property name="text">
  391. <string>&lt;html&gt;&lt;head&gt;&lt;meta name="qrichtext" content="1" /&gt;&lt;style type="text/css"&gt;p, li { white-space: pre-wrap; }&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;p style="margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"&gt;&lt;span style=" color:#ff0000;">Element '<xsl:value-of select="name()"/>' not supported yet.&lt;/span&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
  392. </property>
  393. <property name="textFormat">
  394. <enum>Qt::RichText</enum>
  395. </property>
  396. </widget>
  397. </item>
  398. </xsl:template>
  399. </xsl:stylesheet>