123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296 |
- /*=========================================================================
- Library: CTK
- Copyright (c) Kitware Inc.
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0.txt
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- =========================================================================*/
- // Qt includes
- #include <QList>
- #include <QString>
- #include <QComboBox>
- #include <QUiLoader>
- #include <QApplication>
- // CTK includes
- #include "ctkCmdLineModuleManager.h"
- #include "ctkCmdLineModuleFrontendQtGui.h"
- #include "ctkCmdLineModuleBackendFunctionPointer.h"
- #include "ctkCmdLineModuleParameter.h"
- #include "ctkCmdLineModuleParameterGroup.h"
- #include "ctkCmdLineModuleDescription.h"
- #include "ctkCmdLineModuleXslTransform.h"
- #include "ctkCmdLineModuleFuture.h"
- #include "ctkTest.h"
- // ----------------------------------------------------------------------------
- struct MyImageData : public ctk::CmdLineModuleBackendFunctionPointer::ImageType
- {
- MyImageData(const QString& path = QString())
- : Path(path)
- {}
- QString Label;
- QString Path;
- };
- Q_DECLARE_METATYPE(MyImageData)
- Q_DECLARE_METATYPE(const MyImageData*)
- // ----------------------------------------------------------------------------
- namespace ctk {
- namespace CmdLineModuleBackendFunctionPointer {
- template<>
- QString GetParameterTypeName<MyImageData>()
- {
- return "image";
- }
- }}
- // ----------------------------------------------------------------------------
- class MyImageComboBox : public QComboBox
- {
- Q_OBJECT
- public:
- Q_PROPERTY(QString currentLabel READ currentLabel WRITE setCurrentLabel)
- Q_PROPERTY(QString currentPath READ currentPath WRITE setCurrentPath)
- Q_PROPERTY(const MyImageData* currentImage READ currentImage)
- MyImageComboBox(QWidget* parent = 0)
- : QComboBox(parent)
- {
- imageData << MyImageData("/path/to/image1")
- << MyImageData("/path/to/image2")
- << MyImageData("/path/to/image3");
- this->addItem("Image 1");
- this->addItem("Image 2");
- this->addItem("Image 3");
- }
- QString currentLabel() const
- {
- return this->imageData.at(this->currentIndex()).Label;
- }
- void setCurrentLabel(const QString& label)
- {
- for(int i = 0; i < imageData.size(); ++i)
- {
- if (imageData[i].Label == label)
- {
- this->setCurrentIndex(i);
- break;
- }
- }
- }
- QString currentPath() const
- {
- return this->imageData.at(this->currentIndex()).Path;
- }
- void setCurrentPath(const QString& path)
- {
- this->imageData[this->currentIndex()].Path = path;
- }
- const MyImageData* currentImage() const
- {
- return &this->imageData.at(this->currentIndex());
- }
- private:
- QList<MyImageData> imageData;
- };
- // ----------------------------------------------------------------------------
- class MyQtGuiFrontend : public ctkCmdLineModuleFrontendQtGui
- {
- public:
- MyQtGuiFrontend(const ctkCmdLineModuleReference& moduleRef)
- : ctkCmdLineModuleFrontendQtGui(moduleRef)
- {}
- QUiLoader* uiLoader() const
- {
- struct MyUiLoader : public QUiLoader {
- QStringList availableWidgets() const
- {
- return QUiLoader::availableWidgets() << "MyImageComboBox";
- }
- QWidget* createWidget(const QString& className, QWidget* parent, const QString& name)
- {
- if (className == "MyImageComboBox")
- {
- MyImageComboBox* comboBox = new MyImageComboBox(parent);
- comboBox->setObjectName(name);
- comboBox->setCurrentIndex(1);
- return comboBox;
- }
- return QUiLoader::createWidget(className, parent, name);
- }
- };
- static MyUiLoader myUiLoader;
- return &myUiLoader;
- }
- ctkCmdLineModuleXslTransform* xslTransform() const
- {
- static bool initialized = false;
- ctkCmdLineModuleXslTransform* transform = ctkCmdLineModuleFrontendQtGui::xslTransform();
- if (!initialized)
- {
- transform->bindVariable("imageInputWidget", "MyImageComboBox");
- transform->bindVariable("imageValueProperty", "currentLabel");
- static QFile extraXsl(":/MyImageComboBoxTest.xsl");
- transform->setXslExtraTransformation(&extraXsl);
- initialized = true;
- }
- return transform;
- }
- QVariant value(const QString ¶meter, int role = LocalResourceRole) const
- {
- if (role == UserRole)
- {
- ctkCmdLineModuleParameter param = this->moduleReference().description().parameter(parameter);
- if (param.channel() == "input" && param.tag() == "image")
- {
- return this->customValue(parameter, "currentImage");
- }
- return QVariant();
- }
- else if (role == LocalResourceRole)
- {
- return this->customValue(parameter, "currentPath");
- }
- else
- {
- return ctkCmdLineModuleFrontendQtGui::value(parameter, role);
- }
- }
- void setValue(const QString ¶meter, const QVariant &value, int role = DisplayRole)
- {
- if (role == LocalResourceRole)
- {
- this->setCustomValue(parameter, value, "currentPath");
- }
- else
- {
- ctkCmdLineModuleFrontendQtGui::setValue(parameter, value, role);
- }
- }
- };
- // ----------------------------------------------------------------------------
- class MyFpBackend : public ctkCmdLineModuleBackendFunctionPointer
- {
- protected:
- QList<QVariant> arguments(ctkCmdLineModuleFrontend *frontend) const
- {
- QList<QVariant> args;
- foreach(ctkCmdLineModuleParameter param, frontend->parameters())
- {
- QVariant arg = frontend->value(param.name(), ctkCmdLineModuleFrontend::UserRole);
- if (!arg.isValid())
- {
- arg = frontend->value(param.name());
- }
- args << arg;
- }
- return args;
- }
- };
- // ----------------------------------------------------------------------------
- QString CustomImageDataPath;
- void CustomImageTypeModule(const MyImageData* imageData)
- {
- CustomImageDataPath = imageData->Path;
- }
- // ----------------------------------------------------------------------------
- class ctkCmdLineModuleQtCustomizationTester: public QObject
- {
- Q_OBJECT
- private Q_SLOTS:
- void testCustomization();
- };
- // ----------------------------------------------------------------------------
- void ctkCmdLineModuleQtCustomizationTester::testCustomization()
- {
- qRegisterMetaType<const MyImageData*>("const MyImageData*");
- ctkCmdLineModuleManager moduleManager;
- MyFpBackend fpBackend;
- fpBackend.registerFunctionPointer("Image Type Customization", CustomImageTypeModule);
- moduleManager.registerBackend(&fpBackend);
- QUrl url = fpBackend.registeredFunctionPointers().front();
- moduleManager.registerModule(url);
- ctkCmdLineModuleReference moduleRef = moduleManager.moduleReference(url);
- ctkCmdLineModuleFrontend* fpFrontend = new MyQtGuiFrontend(moduleRef);
- // force the creation of the frontend gui
- fpFrontend->guiHandle();
- QString expectedImageValue = "/path/to/image2";
- QString actualImageValue = fpFrontend->value("param0").toString();
- QCOMPARE(actualImageValue, expectedImageValue);
- // get a custom QVariant value holding the custom widget
- QCOMPARE(fpFrontend->value("param0", ctkCmdLineModuleFrontend::UserRole).value<const MyImageData*>()->Path,
- expectedImageValue);
- // now set the property for the "LocalResourceRole" (the default property) to something else
- expectedImageValue = "/tmp/path/to/image2";
- fpFrontend->setValue("param0", expectedImageValue, ctkCmdLineModuleFrontend::LocalResourceRole);
- QCOMPARE(fpFrontend->value("param0").toString(), expectedImageValue);
- QVERIFY(CustomImageDataPath.isEmpty());
- // run the module (function pointer) and check that is gets the tmp path
- ctkCmdLineModuleFuture future = moduleManager.run(fpFrontend);
- QTest::qSleep(500);
- QApplication::processEvents();
- future.waitForFinished();
- QCOMPARE(CustomImageDataPath, expectedImageValue);
- }
- // ----------------------------------------------------------------------------
- CTK_TEST_MAIN(ctkCmdLineModuleQtCustomizationTest)
- #include "moc_ctkCmdLineModuleQtCustomizationTest.cpp"
|