ctkCmdLineModuleQtCustomizationTest.cpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. /*=========================================================================
  2. Library: CTK
  3. Copyright (c) Kitware Inc.
  4. Licensed under the Apache License, Version 2.0 (the "License");
  5. you may not use this file except in compliance with the License.
  6. You may obtain a copy of the License at
  7. http://www.apache.org/licenses/LICENSE-2.0.txt
  8. Unless required by applicable law or agreed to in writing, software
  9. distributed under the License is distributed on an "AS IS" BASIS,
  10. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  11. See the License for the specific language governing permissions and
  12. limitations under the License.
  13. =========================================================================*/
  14. // Qt includes
  15. #include <QList>
  16. #include <QString>
  17. #include <QComboBox>
  18. #include <QUiLoader>
  19. #include <QApplication>
  20. // CTK includes
  21. #include "ctkCmdLineModuleManager.h"
  22. #include "ctkCmdLineModuleFrontendQtGui.h"
  23. #include "ctkCmdLineModuleBackendFunctionPointer.h"
  24. #include "ctkCmdLineModuleParameter.h"
  25. #include "ctkCmdLineModuleParameterGroup.h"
  26. #include "ctkCmdLineModuleDescription.h"
  27. #include "ctkCmdLineModuleXslTransform.h"
  28. #include "ctkCmdLineModuleFuture.h"
  29. #include "ctkTest.h"
  30. // ----------------------------------------------------------------------------
  31. struct MyImageData : public ctk::CmdLineModuleBackendFunctionPointer::ImageType
  32. {
  33. MyImageData(const QString& path = QString())
  34. : Path(path)
  35. {}
  36. QString Path;
  37. };
  38. Q_DECLARE_METATYPE(MyImageData)
  39. Q_DECLARE_METATYPE(const MyImageData*)
  40. // ----------------------------------------------------------------------------
  41. namespace ctk {
  42. namespace CmdLineModuleBackendFunctionPointer {
  43. template<>
  44. QString GetParameterTypeName<MyImageData>()
  45. {
  46. return "image";
  47. }
  48. }}
  49. // ----------------------------------------------------------------------------
  50. class MyImageComboBox : public QComboBox
  51. {
  52. Q_OBJECT
  53. public:
  54. Q_PROPERTY(QString currentValue READ currentValue WRITE setCurrentValue)
  55. Q_PROPERTY(const MyImageData* currentImage READ currentImage)
  56. MyImageComboBox(QWidget* parent = 0)
  57. : QComboBox(parent)
  58. {
  59. imageData << MyImageData("/path/to/image1")
  60. << MyImageData("/path/to/image2")
  61. << MyImageData("/path/to/image3");
  62. this->addItem("Image 1");
  63. this->addItem("Image 2");
  64. this->addItem("Image 3");
  65. }
  66. QString currentValue() const
  67. {
  68. return this->imageData.at(this->currentIndex()).Path;
  69. }
  70. void setCurrentValue(const QString& path)
  71. {
  72. this->imageData[this->currentIndex()].Path = path;
  73. }
  74. const MyImageData* currentImage() const
  75. {
  76. return &this->imageData.at(this->currentIndex());
  77. }
  78. private:
  79. QList<MyImageData> imageData;
  80. };
  81. // ----------------------------------------------------------------------------
  82. class MyQtGuiFrontend : public ctkCmdLineModuleFrontendQtGui
  83. {
  84. public:
  85. MyQtGuiFrontend(const ctkCmdLineModuleReference& moduleRef)
  86. : ctkCmdLineModuleFrontendQtGui(moduleRef)
  87. {}
  88. QUiLoader* uiLoader() const
  89. {
  90. struct MyUiLoader : public QUiLoader {
  91. QStringList availableWidgets() const
  92. {
  93. return QUiLoader::availableWidgets() << "MyImageComboBox";
  94. }
  95. QWidget* createWidget(const QString& className, QWidget* parent, const QString& name)
  96. {
  97. if (className == "MyImageComboBox")
  98. {
  99. MyImageComboBox* comboBox = new MyImageComboBox(parent);
  100. comboBox->setObjectName(name);
  101. comboBox->setCurrentIndex(1);
  102. return comboBox;
  103. }
  104. return QUiLoader::createWidget(className, parent, name);
  105. }
  106. };
  107. static MyUiLoader myUiLoader;
  108. return &myUiLoader;
  109. }
  110. ctkCmdLineModuleXslTransform* xslTransform() const
  111. {
  112. static bool initialized = false;
  113. ctkCmdLineModuleXslTransform* transform = ctkCmdLineModuleFrontendQtGui::xslTransform();
  114. if (!initialized)
  115. {
  116. transform->bindVariable("imageInputWidget", "MyImageComboBox");
  117. static QFile extraXsl(":/MyImageComboBoxTest.xsl");
  118. transform->setXslExtraTransformation(&extraXsl);
  119. initialized = true;
  120. }
  121. return transform;
  122. }
  123. QVariant value(const QString &parameter, int role) const
  124. {
  125. if (role == UserRole)
  126. {
  127. ctkCmdLineModuleParameter param = this->moduleReference().description().parameter(parameter);
  128. if (param.channel() == "input" && param.tag() == "image")
  129. {
  130. return this->customValue(parameter, "currentImage");
  131. }
  132. return QVariant();
  133. }
  134. return ctkCmdLineModuleFrontendQtGui::value(parameter, role);
  135. }
  136. };
  137. // ----------------------------------------------------------------------------
  138. class MyFpBackend : public ctkCmdLineModuleBackendFunctionPointer
  139. {
  140. protected:
  141. QList<QVariant> arguments(ctkCmdLineModuleFrontend *frontend) const
  142. {
  143. QList<QVariant> args;
  144. foreach(ctkCmdLineModuleParameter param, frontend->parameters())
  145. {
  146. QVariant arg = frontend->value(param.name(), ctkCmdLineModuleFrontend::UserRole);
  147. if (!arg.isValid())
  148. {
  149. arg = frontend->value(param.name());
  150. }
  151. args << arg;
  152. }
  153. return args;
  154. }
  155. };
  156. // ----------------------------------------------------------------------------
  157. QString CustomImageDataPath;
  158. void CustomImageTypeModule(const MyImageData* imageData)
  159. {
  160. CustomImageDataPath = imageData->Path;
  161. }
  162. // ----------------------------------------------------------------------------
  163. class ctkCmdLineModuleQtCustomizationTester: public QObject
  164. {
  165. Q_OBJECT
  166. private Q_SLOTS:
  167. void testCustomization();
  168. };
  169. // ----------------------------------------------------------------------------
  170. void ctkCmdLineModuleQtCustomizationTester::testCustomization()
  171. {
  172. qRegisterMetaType<const MyImageData*>("const MyImageData*");
  173. ctkCmdLineModuleManager moduleManager;
  174. MyFpBackend fpBackend;
  175. fpBackend.registerFunctionPointer("Image Type Customization", CustomImageTypeModule);
  176. moduleManager.registerBackend(&fpBackend);
  177. QUrl url = fpBackend.registeredFunctionPointers().front();
  178. moduleManager.registerModule(url);
  179. ctkCmdLineModuleReference moduleRef = moduleManager.moduleReference(url);
  180. ctkCmdLineModuleFrontend* fpFrontend = new MyQtGuiFrontend(moduleRef);
  181. // force the creation of the frontend gui
  182. fpFrontend->guiHandle();
  183. QString expectedImageValue = "/path/to/image2";
  184. QCOMPARE(fpFrontend->value("param0").toString(), expectedImageValue);
  185. // get a custom QVariant value holding the custom widget
  186. QCOMPARE(fpFrontend->value("param0", ctkCmdLineModuleFrontend::UserRole).value<const MyImageData*>()->Path,
  187. expectedImageValue);
  188. // now set the property for the "LocalResourceRole" (the default property) to something else
  189. expectedImageValue = "/tmp/path/to/image2";
  190. fpFrontend->setValue("param0", expectedImageValue);
  191. QCOMPARE(fpFrontend->value("param0").toString(), expectedImageValue);
  192. QVERIFY(CustomImageDataPath.isEmpty());
  193. // run the module (function pointer) and check that is gets the tmp path
  194. ctkCmdLineModuleFuture future = moduleManager.run(fpFrontend);
  195. QTest::qSleep(500);
  196. QApplication::processEvents();
  197. future.waitForFinished();
  198. QCOMPARE(CustomImageDataPath, expectedImageValue);
  199. }
  200. // ----------------------------------------------------------------------------
  201. CTK_TEST_MAIN(ctkCmdLineModuleQtCustomizationTest)
  202. #include "moc_ctkCmdLineModuleQtCustomizationTest.cpp"