pax_global_header00006660000000000000000000000064152462260570014523gustar00rootroot0000000000000052 comment=bfd3a5f1c414bc424893f4c9100bb652f79645b2 ctk-2026.09.02/000077500000000000000000000000001524622605700127065ustar00rootroot00000000000000ctk-2026.09.02/.pre-commit-config.yaml000066400000000000000000000005231524622605700171670ustar00rootroot00000000000000repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: "v4.4.0" hooks: - id: check-added-large-files args: ['--maxkb=1024'] - id: check-case-conflict - id: check-merge-conflict - id: check-symlinks - id: end-of-file-fixer - id: mixed-line-ending - id: trailing-whitespace exclude: "\\.(svg|vtk|vtp)$" ctk-2026.09.02/Applications/000077500000000000000000000000001524622605700153345ustar00rootroot00000000000000ctk-2026.09.02/Applications/Testing/000077500000000000000000000000001524622605700167515ustar00rootroot00000000000000ctk-2026.09.02/Applications/Testing/CMakeLists.txt000066400000000000000000000000261524622605700215070ustar00rootroot00000000000000add_subdirectory(Cpp) ctk-2026.09.02/Applications/Testing/Cpp/000077500000000000000000000000001524622605700174735ustar00rootroot00000000000000ctk-2026.09.02/Applications/Testing/Cpp/CMakeLists.txt000066400000000000000000000041051524622605700222330ustar00rootroot00000000000000## Query / Retrieve Testing if(CTK_APP_ctkDICOMQuery AND CTK_APP_ctkDICOMRetrieve) # # create a dcm query/retrieve service config file that points to the build dir # set(DCMQRSCP_STORE_DIR ${CTK_BINARY_DIR}/Testing/Temporary) set(ctkDICOMRetrieve_STORE_DIR ${CTK_BINARY_DIR}/Testing/Temporary/ctkDICOMRetrieveStorage) set(DCMQRSCP_CONFIG ${CTK_BINARY_DIR}/Testing/Temporary/dcmqrscp.cfg) if(UNIX) set(DCMQRSCP_HOSTNAME "localhost") else() cmake_host_system_information(RESULT DCMQRSCP_HOSTNAME QUERY HOSTNAME) endif() configure_file( dcmqrscp.cfg.in ${DCMQRSCP_CONFIG} ) set(ctkDICOMQuery_DB_FILE ${CTK_BINARY_DIR}/Testing/Temporary/ctkDICOMApplicationTest1.db) # # find the helper executables # find_program(DCMTK_DCMQRSCP_EXECUTABLE dcmqrscp PATHS ${DCMTK_DIR}/bin PATH_SUFFIXES ${CMAKE_CONFIGURATION_TYPES} NO_DEFAULT_PATH ) find_program(DCMTK_STORESCU_EXECUTABLE storescu PATHS ${DCMTK_DIR}/bin PATH_SUFFIXES ${CMAKE_CONFIGURATION_TYPES} NO_DEFAULT_PATH ) # # Add Tests # ctk_add_executable_utf8(ctkDICOMApplicationTest1 ctkDICOMApplicationTest1.cpp) target_link_libraries(ctkDICOMApplicationTest1 CTKCore Qt${CTK_QT_VERSION}::Core ) include_directories( ${CTKCore_SOURCE_DIR} ${CTKCore_BINARY_DIR} ) set(testname ctkDICOMApplicationTest1) add_test( NAME ${testname} COMMAND $ ${DCMTK_DCMQRSCP_EXECUTABLE} ${DCMQRSCP_CONFIG} ${CTKData_DIR}/Data/DICOM/MRHEAD/000055.IMA ${CTKData_DIR}/Data/DICOM/MRHEAD/000056.IMA ${DCMTK_STORESCU_EXECUTABLE} $ ${ctkDICOMQuery_DB_FILE} $ ${ctkDICOMRetrieve_STORE_DIR} ) set_property(TEST ${testname} PROPERTY ENVIRONMENT_MODIFICATION "${CTK_TEST_LAUNCH_BUILD_ENVIRONMENT_MODIFICATION}") set_property(TEST ${testname} PROPERTY RESOURCE_LOCK "dcmqrscp") endif() ctk-2026.09.02/Applications/Testing/Cpp/ctkDICOMApplicationTest1.cpp000066400000000000000000000233011524622605700246400ustar00rootroot00000000000000/*========================================================================= 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 #include #include #include // CTK includes #include "ctkCoreTestingMacros.h" // STD includes #include #include // // This test performs a full dicom store, query, and retrieve. // // To recreate the parts, from the CTK-superbuild directory, run: // // // ./DCMTK-build/bin/dcmqrscp -c ./CTK-build/Testing/Temporary/dcmqrscp.cfg -d -v // // ./DCMTK-build/bin/bin/storescu -aec CTK_AE -aet CTK_AE localhost 11112 ./CTKData/Data/DICOM/MRHEAD/*.IMA // // ./DCMTK-build/bin/bin/findscu -aet CTK_AE -aec COMMONTK -P -k 0010,0010=\* localhost 11112 patqry.dcm // // ./CTK-build/bin/ctkDICOMQuery /tmp/test.db CTK_AE CTK_AE localhost 11112 // // // ./CTK-build/bin/ctkDICOMRetrieve 1.2.840.113619.2.135.3596.6358736.5118.1115807980.182 /tmp/hoot CTK_AE 11113 CTK_AE localhost 11112 CTK_CLIENT_AE /* // // As invoked by ctest: // // % ./CTK-build/bin/CTKApplicationCppTests ctkDICOMApplicationTest1 \ // ./DCMTK-build/bin/bin/dcmqrscp ./CTK-build/Testing/Temporary/dcmqrscp.cfg \ // ./CTKData/Data/DICOM/MRHEAD/000055.IMA \ // ./CTKData/Data/DICOM/MRHEAD/000056.IMA \ // ./DCMTK-build/bin/bin/storescu \ // ./CTK-build/bin/ctkDICOMQuery \ // ./CTK-build/Testing/Temporary/ctkDICOMApplicationTest1.db \ // ./CTK-build/bin/ctkDICOMRetrieve \ // ./CTK-build/Testing/Temporary/ctkDICOMRetrieveStorage // */ namespace { //----------------------------------------------------------------------------- enum WaitType { WaitForStarted, //!< Blocks until the process has started WaitForFinished, //!< Blocks until the process has finished }; //----------------------------------------------------------------------------- int wait_for_finished(QTextStream& out, const QString& type, QProcess* process, bool kill=false) { try { QString programName = QFileInfo(process->program()).baseName(); if (kill) { process->kill(); } process->waitForFinished(); out << "------------------------------------------------------------------------------\n"; out << "------------------------------------------------------------------------------\n"; out << "------------------------------------------------------------------------------\n"; out << type << " " << programName << " Finished.\n"; out << "Process Killed: " << (kill ? "yes" : "no") << "\n"; out << "Process ExitCode: "; if (process->exitCode() == QProcess::NormalExit) { out << "NormalExit (" << static_cast(QProcess::NormalExit) << ")\n"; } else { out << "CrashExit (" << static_cast(QProcess::CrashExit) << ")\n"; } if (process->exitCode() == QProcess::CrashExit) { out << "Process State: "; switch(static_cast(process->error())) { #define _QProcessErrorToString(ERROR) \ case QProcess::ERROR: \ out << #ERROR << " (" << static_cast(QProcess::ERROR) << ")\n"; \ break; _QProcessErrorToString(FailedToStart); _QProcessErrorToString(Crashed); _QProcessErrorToString(Timedout); _QProcessErrorToString(WriteError); _QProcessErrorToString(ReadError); _QProcessErrorToString(UnknownError); #undef _QProcessErrorToString } } out << "Standard Output:\n"; out << process->readAllStandardOutput(); out << "Standard Error:\n"; out << process->readAllStandardError(); if (kill) { return EXIT_SUCCESS; } else { return process->exitStatus() == QProcess::NormalExit ? process->exitCode() : EXIT_FAILURE; } } catch (const std::exception& e) { out << "ERROR: exception ocurred in wait_for_finished(): " << e.what(); return EXIT_FAILURE; } } //----------------------------------------------------------------------------- int run_process( QTextStream& out, const QString& type, WaitType wait_type, QProcess* process, const QString& exectuable, const QStringList& arguments) { try { QString programName = QFileInfo(exectuable).baseName(); out << "------------------------------------------------------------------------------\n"; if (type == "server") { out << " ____ _____ ______ _______ ____ " << "\n"; out << " / ___|| ____| _ \\ \\ / / ____| _ \\ " << "\n"; out << " \\___ \\| _| | |_) \\ \\ / /| _| | |_) |" << "\n"; out << " ___) | |___| _ < \\ V / | |___| _ < " << "\n"; out << " |____/|_____|_| \\_\\ \\_/ |_____|_| \\_\\" << "\n"; } else if (type == "client") { out << " ____ _ ___ _____ _ _ _____ " << "\n"; out << " / ___| | |_ _| ____| \\ | |_ _|" << "\n"; out << "| | | | | || _| | \\| | | | " << "\n"; out << "| |___| |___ | || |___| |\\ | | | " << "\n"; out << " \\____|_____|___|_____|_| \\_| |_| " << "\n"; } out << "------------------------------------------------------------------------------\n"; out << "starting " << type << " " << exectuable << "\n"; out << "with args " << arguments.join(" ") << "\n"; process->start(exectuable, arguments); switch(wait_type) { case WaitForStarted: process->waitForStarted(); out << programName << " Started.\n"; return process->state() == QProcess::Running ? EXIT_SUCCESS : EXIT_FAILURE; case WaitForFinished: return wait_for_finished(out, type, process); default: return EXIT_FAILURE; } } catch (const std::exception& e) { out << "ERROR: exception ocurred in run_process(): " << e.what(); return EXIT_FAILURE; } } } // end of anonymous namespace //----------------------------------------------------------------------------- int main(int argc, char * argv []) { QCoreApplication app(argc, argv); QTextStream out(stdout); QStringList arguments = app.arguments(); QString testName = arguments.takeFirst(); if (arguments.count() != 9) { std::cerr << "ERROR: invalid or missing arguments.\n\n" << "Usage: " << qPrintable(testName) << " " " " " " " " " " " \n"; return EXIT_FAILURE; } QString dcmqrscp_exe (argv[1]); QString dcmqrscp_cfg (argv[2]); QString dicomData1 (argv[3]); QString dicomData2 (argv[4]); QString storescu_exe (argv[5]); QString ctkDICOMQuery_exe (argv[6]); QString ctkDICOMQuery_db_file (argv[7]); QString ctkDICOMRetrieve_exe (argv[8]); QString ctkDICOMRetrieve_directory (argv[9]); // // first, start the server process // QProcess *dcmqrscp = new QProcess(0); { CHECK_EXIT_SUCCESS( run_process(out, "server", WaitForStarted, dcmqrscp, dcmqrscp_exe, { "--config", dcmqrscp_cfg, "--debug", "--verbose", "11112" })); } // // now push some dicom data in using storescu // QProcess *storescu = new QProcess(0); { CHECK_EXIT_SUCCESS( run_process(out, "client", WaitForFinished, storescu, storescu_exe, { "-aec", "CTK_AE", "-aet", "CTK_AE", "localhost", "11112", dicomData1, dicomData2, })); } // // now query the server to see if the data arrived okay // - our database file will be updated with metadata from the query // QProcess *ctkDICOMQuery = new QProcess(0); { // Usage: // ctkDICOMQuery database callingAETitle calledAETitle host port CHECK_EXIT_SUCCESS( run_process(out, "client", WaitForFinished, ctkDICOMQuery, ctkDICOMQuery_exe, { ctkDICOMQuery_db_file, "CTK_AE", "CTK_AE", "localhost", "11112" })); } // // now do a retrieve into our download directory // // this is the study id of the dicom files we load from CTKData QString studyUID("1.2.840.113619.2.135.3596.6358736.5118.1115807980.182"); QProcess *ctkDICOMRetrieve = new QProcess(0); { // Usage: // ctkDICOMRetrieve StudyUID OutputDirectory callingAETitle calledAETitle host calledPort moveDestinationAETitle CHECK_EXIT_SUCCESS( run_process(out, "client", WaitForFinished, ctkDICOMRetrieve, ctkDICOMRetrieve_exe, { studyUID, ctkDICOMRetrieve_directory, "CTK_AE", "CTK_AE", "localhost", "11112", "CTK_CLIENT_AE" })); } // // clients are finished, now kill server and print output // CHECK_EXIT_SUCCESS( wait_for_finished(out, "server", dcmqrscp, /*kill=*/true)); return EXIT_SUCCESS; } ctk-2026.09.02/Applications/Testing/Cpp/dcmqrscp.cfg.in000066400000000000000000000060731524622605700224030ustar00rootroot00000000000000#----------------------------------------------------------------------- # # Example configuration file for the dcmqrdb and dcmqrti applications. # # - this file is specialized for use as a local 'pacs' simulator for testing # ctkDICOM* applications # - the location of the dicom store is configured by cmake to be in the build tree # #----------------------------------------------------------------------- # Global Configuration Parameters NetworkType = "tcp" NetworkTCPPort = 11112 MaxPDUSize = 16384 MaxAssociations = 16 Display = "no" HostTable BEGIN # # The HostTable defines symbolic names for collections of network # DICOM Application Entities. A symbolic name can represent a single # application entity or it can represent a group of application entities. # Each DICOM application entity is defined by a triple consisting of # Application Entity Title, host name and TCP/IP port number. # # Entry Format: SymbolicName = ( AETitle, HostName, Portnumber ), ... | # SymbolicName = SymbolicName, ... # # NOTE: in the current implementation you cannot substitute an IP address # for a hostname. # #ctk = (ACME1, acmehost1, 5678) #acme2 = (ACME2, acmehost2, 5678) #acmeCTcompany = acme1, acme2 #united1 = (UNITED1, unitedhost1, 104) #united2 = (UNITED2, unitedhost2, 104) #unitedMRcompany = united1, united2 # commontk = (CTK_AE,@DCMQRSCP_HOSTNAME@,11112) commontk_client = (CTK_CLIENT_AE, @DCMQRSCP_HOSTNAME@, 11113) # HostTable END VendorTable BEGIN # # The VendorTable is used by the dcmqrdb and dcmqrti applications. # You can give a vendor name (r.h.s. entry below) to the dcmqrti # program and it will talk to all hosts and AEs of the vendor. # The dcmqrdb program can use the vendor table to restrict move destination # to hosts belonging to a vendor. # Also, the dcmqrti and dcmqrdb programs use the name defined on the left hand side # as the vendor name to display above images. # # The format: # VendorName = SymbolicName # The symbolic name should be defined in the HostTable. # #"Acme CT Company" = acmeCTcompany #"United MR Company" = unitedMRcompany "The Common Toolkit" = commontk "The Common Toolkit Client" = commontk_client # VendorTable END AETable BEGIN # # Each row of the AETable defines an Application Entities (AE) Title known # to the dcmqrdb application. Each AE Title represents a separate # image database located in the specified file system directory (storage area). # Each AE Title has read/write, quota and peer access restrictions. # # Entry Format: AETitle StorageArea Access Quota Peers # AccessFormat: R | RW | W # Quota Format: ( maxStudies, maxBytesPerStudy ) # Peers Format: ( Hostname, AETitle, Portnumber ), ... | # Entry in HostTable | # ANY # #COMMON /home/dicom/db/COMMON R (200, 1024mb) ANY #ACME_STORE /home/dicom/db/ACME_STORE RW (9, 1024mb) acmeCTcompany #UNITED_STORE /home/dicom/db/UNITED_STORE RW (9, 1024mb) unitedMRcompany CTK_AE @DCMQRSCP_STORE_DIR@ RW (200, 1024mb) commontk # AETable END ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/000077500000000000000000000000001524622605700231135ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/CMakeLists.txt000066400000000000000000000030041524622605700256500ustar00rootroot00000000000000project(ctkCommandLineModuleExplorer) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkCommandLineModuleExplorerMain.cpp ctkCmdLineModuleExplorerConstants.cpp ctkCmdLineModuleExplorerDirectorySettings.cpp ctkCmdLineModuleExplorerGeneralModuleSettings.cpp ctkCmdLineModuleExplorerMainWindow.h ctkCmdLineModuleExplorerMainWindow.cpp ctkCmdLineModuleExplorerModulesSettings.cpp ctkCmdLineModuleExplorerOutputText.cpp ctkCmdLineModuleExplorerProgressListWidget.cpp ctkCmdLineModuleExplorerProgressWidget.cpp ctkCmdLineModuleExplorerShowXmlAction.cpp ctkCmdLineModuleExplorerTabList.cpp ctkCmdLineModuleExplorerTreeWidget.cpp ctkCmdLineModuleExplorerUtils.cpp ) # UI files set(KIT_UI_FORMS ctkCmdLineModuleExplorerDirectorySettings.ui ctkCmdLineModuleExplorerGeneralModuleSettings.ui ctkCmdLineModuleExplorerMainWindow.ui ctkCmdLineModuleExplorerModulesSettings.ui ctkCmdLineModuleExplorerProgressWidget.ui ) # Resources set(KIT_resources resources/ctkCmdLineModuleExplorer.qrc ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES}) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerConstants.cpp000066400000000000000000000023351524622605700324230ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerConstants.h" const QString ctkCmdLineModuleExplorerConstants::KEY_SEARCH_PATHS = "ModuleSearchPaths"; const QString ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES = "RegisteredModules"; const QString ctkCmdLineModuleExplorerConstants::KEY_MAX_PARALLEL_MODULES = "MaxParallelModules"; const QString ctkCmdLineModuleExplorerConstants::KEY_XML_TIMEOUT_SECONDS = "XmlTimeoutSeconds"; ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerConstants.h000066400000000000000000000022661524622605700320730ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERCONSTANTS_H #define CTKCMDLINEMODULEEXPLORERCONSTANTS_H #include struct ctkCmdLineModuleExplorerConstants { static const QString KEY_SEARCH_PATHS; static const QString KEY_REGISTERED_MODULES; static const QString KEY_MAX_PARALLEL_MODULES; static const QString KEY_XML_TIMEOUT_SECONDS; }; #endif // CTKCMDLINEMODULEEXPLORERCONSTANTS_H ctkCmdLineModuleExplorerDirectorySettings.cpp000066400000000000000000000033271524622605700340570ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerDirectorySettings.h" #include "ctkCmdLineModuleExplorerConstants.h" #include #include #include ctkCmdLineModuleExplorerDirectorySettings::ctkCmdLineModuleExplorerDirectorySettings(ctkCmdLineModuleDirectoryWatcher *directoryWatcher) : DirectoryWatcher(directoryWatcher) { this->setupUi(this); this->PathListButtonsWidget->init(this->PathListWidget); this->registerProperty(ctkCmdLineModuleExplorerConstants::KEY_SEARCH_PATHS, this->PathListWidget, "paths", SIGNAL(pathsChanged(QStringList,QStringList))); } void ctkCmdLineModuleExplorerDirectorySettings::applySettings() { QVariant newSearchPaths = this->propertyValue(ctkCmdLineModuleExplorerConstants::KEY_SEARCH_PATHS); this->DirectoryWatcher->setDirectories(newSearchPaths.toStringList()); ctkSettingsPanel::applySettings(); } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerDirectorySettings.h000066400000000000000000000030241524622605700335750ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERDIRECTORYSETTINGS_H #define CTKCMDLINEMODULEEXPLORERDIRECTORYSETTINGS_H #include #include "ui_ctkCmdLineModuleExplorerDirectorySettings.h" class ctkCmdLineModuleDirectoryWatcher; /** * \class ctkCmdLineModuleExplorerDirectorySettings * \brief Example application settings panel. */ class ctkCmdLineModuleExplorerDirectorySettings : public ctkSettingsPanel, public Ui::ctkCmdLineModuleExplorerDirectorySettings { Q_OBJECT public: ctkCmdLineModuleExplorerDirectorySettings(ctkCmdLineModuleDirectoryWatcher* directoryWatcher); void applySettings(); private: ctkCmdLineModuleDirectoryWatcher* DirectoryWatcher; }; #endif // CTKCMDLINEMODULEEXPLORERDIRECTORYSETTINGS_H ctkCmdLineModuleExplorerDirectorySettings.ui000066400000000000000000000061031524622605700337050ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer ctkCmdLineModuleExplorerDirectorySettings 0 0 400 300 Search Paths 6 0 0 0 Module Search Paths true Qt::Vertical Qt::Vertical 20 40 Qt::ElideMiddle ctkPathListWidget::DirectoriesOnly The following list of paths will be searched for executables which provide a XML parameter description when called with a "--xml" command line argument: true ctkPathListButtonsWidget QWidget
ctkPathListButtonsWidget.h
ctkPathListWidget QListView
ctkPathListWidget.h
ctkCmdLineModuleExplorerGeneralModuleSettings.cpp000066400000000000000000000037201524622605700346330ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerGeneralModuleSettings.h" #include "ctkCmdLineModuleManager.h" #include "ctkCmdLineModuleExplorerConstants.h" #include #include ctkCmdLineModuleExplorerGeneralModuleSettings::ctkCmdLineModuleExplorerGeneralModuleSettings(ctkCmdLineModuleManager* cmdLineModuleManager) : CmdLineModuleManager(cmdLineModuleManager) { this->setupUi(this); this->registerProperty(ctkCmdLineModuleExplorerConstants::KEY_MAX_PARALLEL_MODULES, this->MaxParallelModules, "value", SIGNAL(valueChanged(int))); this->registerProperty(ctkCmdLineModuleExplorerConstants::KEY_XML_TIMEOUT_SECONDS, this->XmlTimeout, "value", SIGNAL(valueChanged(int))); } void ctkCmdLineModuleExplorerGeneralModuleSettings::applySettings() { int maxParallelModules = this->propertyValue(ctkCmdLineModuleExplorerConstants::KEY_MAX_PARALLEL_MODULES).toInt(); QThreadPool::globalInstance()->setMaxThreadCount(maxParallelModules); int timeout = this->propertyValue(ctkCmdLineModuleExplorerConstants::KEY_XML_TIMEOUT_SECONDS).toInt(); this->CmdLineModuleManager->setTimeOutForXMLRetrieval(timeout*1000); } ctkCmdLineModuleExplorerGeneralModuleSettings.h000066400000000000000000000026671524622605700343110ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERGENERALMODULESETTINGS_H #define CTKCMDLINEMODULEEXPLORERGENERALMODULESETTINGS_H #include #include "ui_ctkCmdLineModuleExplorerGeneralModuleSettings.h" class ctkCmdLineModuleManager; class ctkCmdLineModuleExplorerGeneralModuleSettings : public ctkSettingsPanel, public Ui::ctkCmdLineModuleExplorerGeneralModuleSettings { Q_OBJECT public: ctkCmdLineModuleExplorerGeneralModuleSettings(ctkCmdLineModuleManager* cmdLineModuleManager); void applySettings(); private: ctkCmdLineModuleManager* CmdLineModuleManager; }; #endif // CTKCMDLINEMODULEEXPLORERGENERALMODULESETTINGS_H ctkCmdLineModuleExplorerGeneralModuleSettings.ui000066400000000000000000000062331524622605700344700ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer ctkCmdLineModuleExplorerGeneralModuleSettings 0 0 400 300 Module Settings 6 0 0 0 Run Settings Qt::Horizontal 40 20 0 0 60 16777215 1 999 Maximum parallel running modules: Qt::Vertical 20 40 XML retrieval timeout (in seconds): -1 999999999 30 ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerMainWindow.cpp000066400000000000000000000413211524622605700325210ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerMainWindow.h" #include "ui_ctkCmdLineModuleExplorerMainWindow.h" #include "ctkCmdLineModuleExplorerGeneralModuleSettings.h" #include "ctkCmdLineModuleExplorerDirectorySettings.h" #include "ctkCmdLineModuleExplorerModulesSettings.h" #include "ctkCmdLineModuleExplorerTabList.h" #include "ctkCmdLineModuleExplorerProgressWidget.h" #include "ctkCmdLineModuleExplorerConstants.h" #include "ctkCmdLineModuleUtils.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //----------------------------------------------------------------------------- ctkCLModuleExplorerMainWindow::ctkCLModuleExplorerMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::ctkCmdLineModuleExplorerMainWindow), defaultModuleFrontendFactory(NULL), moduleManager(ctkCmdLineModuleManager::WEAK_VALIDATION, QStandardPaths::writableLocation(QStandardPaths::CacheLocation)), directoryWatcher(&moduleManager), settingsDialog(NULL) { ui->setupUi(this); settings.restoreState(this->objectName(), *this); if (!settings.contains(ctkCmdLineModuleExplorerConstants::KEY_MAX_PARALLEL_MODULES)) { settings.setValue(ctkCmdLineModuleExplorerConstants::KEY_MAX_PARALLEL_MODULES, QThread::idealThreadCount()); } QThreadPool::globalInstance()->setMaxThreadCount(settings.value(ctkCmdLineModuleExplorerConstants::KEY_MAX_PARALLEL_MODULES, QThread::idealThreadCount()).toInt()); if (!settings.contains(ctkCmdLineModuleExplorerConstants::KEY_XML_TIMEOUT_SECONDS)) { settings.setValue(ctkCmdLineModuleExplorerConstants::KEY_XML_TIMEOUT_SECONDS, QVariant(30)); } moduleManager.setTimeOutForXMLRetrieval( settings.value(ctkCmdLineModuleExplorerConstants::KEY_XML_TIMEOUT_SECONDS, QVariant(30) ).toInt() * 1000); // Frontends moduleFrontendFactories << new ctkCmdLineModuleFrontendFactoryQtGui; moduleFrontendFactories << new ctkCmdLineModuleFrontendFactoryQtWebKit; defaultModuleFrontendFactory = moduleFrontendFactories.front(); ui->modulesTreeWidget->setModuleFrontendFactories(moduleFrontendFactories, moduleFrontendFactories.front()); ui->modulesSearchBox->setClearIcon(QIcon(":/icons/clear.png")); connect(ui->modulesSearchBox, SIGNAL(textChanged(QString)), ui->modulesTreeWidget, SLOT(setFilter(QString))); // Backends ctkCmdLineModuleBackendFunctionPointer* backendFunctionPointer = new ctkCmdLineModuleBackendFunctionPointer; moduleBackends.push_back(backendFunctionPointer); xmlCheckerBackEnd = new ctkCmdLineModuleBackendXMLChecker; moduleBackends.push_back(xmlCheckerBackEnd); moduleBackends.push_back(new ctkCmdLineModuleBackendLocalProcess); for(int i = 0; i < moduleBackends.size(); ++i) { moduleManager.registerBackend(moduleBackends[i]); } tabList.reset(new ctkCmdLineModuleExplorerTabList(ui->mainTabWidget)); // If a module is registered via the ModuleManager, add it to the tree connect(&moduleManager, SIGNAL(moduleRegistered(ctkCmdLineModuleReference)), ui->modulesTreeWidget, SLOT(addModuleItem(ctkCmdLineModuleReference))); connect(&moduleManager, SIGNAL(moduleUnregistered(ctkCmdLineModuleReference)), ui->modulesTreeWidget, SLOT(removeModuleItem(ctkCmdLineModuleReference))); // React to specific frontend creations connect(ui->modulesTreeWidget, SIGNAL(moduleFrontendCreated(ctkCmdLineModuleFrontend*)), tabList.data(), SLOT(addTab(ctkCmdLineModuleFrontend*))); // React to tab-changes connect(tabList.data(), SIGNAL(tabActivated(ctkCmdLineModuleFrontend*)), SLOT(moduleTabActivated(ctkCmdLineModuleFrontend*))); connect(tabList.data(), SIGNAL(tabActivated(ctkCmdLineModuleFrontend*)), ui->progressListWidget, SLOT(setCurrentProgressWidget(ctkCmdLineModuleFrontend*))); connect(tabList.data(), SIGNAL(tabClosed(ctkCmdLineModuleFrontend*)), ui->outputText, SLOT(frontendRemoved(ctkCmdLineModuleFrontend*))); connect(tabList.data(), SIGNAL(tabClosed(ctkCmdLineModuleFrontend*)), ui->progressListWidget, SLOT(removeProgressWidget(ctkCmdLineModuleFrontend*))); connect(ui->progressListWidget, SIGNAL(progressWidgetClicked(ctkCmdLineModuleFrontend*)), tabList.data(), SLOT(setActiveTab(ctkCmdLineModuleFrontend*))); connect(ui->ClearButton, SIGNAL(clicked()), ui->progressListWidget, SLOT(clearList())); connect(ui->m_CheckXMLButton, SIGNAL(pressed()), this, SLOT(checkXMLPressed())); // Listen to future events for the currently active tab // Due to Qt bug 12152, we cannot listen to the "paused" signal because it is // not emitted directly when the QFuture is paused. Instead, it is emitted after // resuming the future, after the "resume" signal has been emitted... we use // a polling approach instead. pollPauseTimer.setInterval(300); connect(&pollPauseTimer, SIGNAL(timeout()), SLOT(checkModulePaused())); connect(¤tFutureWatcher, SIGNAL(resumed()), SLOT(currentModuleResumed())); connect(¤tFutureWatcher, SIGNAL(canceled()), SLOT(currentModuleCanceled())); connect(¤tFutureWatcher, SIGNAL(finished()), SLOT(currentModuleFinished())); foreach(QUrl fpModule, backendFunctionPointer->registeredFunctionPointers()) { moduleManager.registerModule(fpModule); } // Register persistent modules QFuture future = QtConcurrent::mapped(settings.value(ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES).toStringList(), ctkCmdLineModuleConcurrentRegister(&moduleManager, true)); future.waitForFinished(); ctkCmdLineModuleUtils::messageBoxModuleRegistration(future, moduleManager.validationMode()); // Start watching directories directoryWatcher.setDebug(true); directoryWatcher.setDirectories(settings.value(ctkCmdLineModuleExplorerConstants::KEY_SEARCH_PATHS).toStringList()); moduleTabActivated(NULL); pollPauseTimer.start(); } //----------------------------------------------------------------------------- ctkCLModuleExplorerMainWindow::~ctkCLModuleExplorerMainWindow() { qDeleteAll(moduleBackends); qDeleteAll(moduleFrontendFactories); settings.saveState(*this, this->objectName()); if (settingsDialog) { settings.saveState(*settingsDialog, settingsDialog->objectName()); } } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::addModule(const QUrl &location) { moduleManager.registerModule(location); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::closeEvent(QCloseEvent *event) { QList runningFrontends; foreach (ctkCmdLineModuleFrontend* frontend, this->tabList->tabs()) { if (frontend->isRunning()) { runningFrontends << frontend; } } if (!runningFrontends.empty()) { QMessageBox::StandardButton button = QMessageBox::warning(QApplication::activeWindow(), //: %1 is the number of running modules tr("Closing %1 running modules").arg(runningFrontends.size()), tr("Some modules are still running.\n" "Closing the application will cancel all current computations."), QMessageBox::Ok | QMessageBox::Cancel); if (button == QMessageBox::Ok) { QFutureSynchronizer futureSync; futureSync.setCancelOnWait(true); foreach(ctkCmdLineModuleFrontend* frontend, runningFrontends) { if (frontend->future().canCancel()) { futureSync.addFuture(frontend->future()); } } futureSync.waitForFinished(); event->accept(); QMainWindow::closeEvent(event); return; } else { event->ignore(); return; } } event->accept(); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionRun_triggered() { ctkCmdLineModuleFrontend* moduleFrontend = this->tabList->activeTab(); Q_ASSERT(moduleFrontend); ui->actionRun->setEnabled(false); qobject_cast(moduleFrontend->guiHandle())->setEnabled(false); ctkCmdLineModuleFuture future = moduleManager.run(moduleFrontend); ui->progressListWidget->addProgressWidget(moduleFrontend, future); ui->progressListWidget->setCurrentProgressWidget(moduleFrontend); ui->actionPause->setEnabled(future.canPause() && future.isRunning()); ui->actionPause->setChecked(future.isPaused()); ui->actionCancel->setEnabled(future.canCancel() && future.isRunning()); this->currentFutureWatcher.setFuture(future); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionPause_toggled(bool toggled) { this->currentFutureWatcher.setPaused(toggled); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionCancel_triggered() { this->currentFutureWatcher.cancel(); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionOptions_triggered() { if (settingsDialog == NULL) { settingsDialog = new ctkSettingsDialog(this); settings.restoreState(settingsDialog->objectName(), *settingsDialog); settingsDialog->setSettings(&settings); ctkSettingsPanel* generalModulePanel = new ctkCmdLineModuleExplorerGeneralModuleSettings(&moduleManager); settingsDialog->addPanel(generalModulePanel); settingsDialog->addPanel(new ctkCmdLineModuleExplorerDirectorySettings(&directoryWatcher), generalModulePanel); settingsDialog->addPanel(new ctkCmdLineModuleExplorerModulesSettings(&moduleManager), generalModulePanel); } settingsDialog->exec(); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionLoad_triggered() { QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Load modules...")); this->setCursor(Qt::BusyCursor); QFuture future = QtConcurrent::mapped(fileNames, ctkCmdLineModuleConcurrentRegister(&this->moduleManager)); future.waitForFinished(); this->unsetCursor(); ctkCmdLineModuleUtils::messageBoxModuleRegistration(future, this->moduleManager.validationMode()); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionQuit_triggered() { this->close(); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionReset_triggered() { this->tabList->activeTab()->resetValues(); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionClear_Cache_triggered() { moduleManager.clearCache(); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::on_actionReload_Modules_triggered() { this->setCursor(Qt::BusyCursor); QList urls; QList moduleRefs = this->moduleManager.moduleReferences(); foreach (ctkCmdLineModuleReference ref, moduleRefs) { urls.push_back(ref.location()); } foreach (ctkCmdLineModuleReference ref, moduleRefs) { this->moduleManager.unregisterModule(ref); } QFuture future = QtConcurrent::mapped(urls, ctkCmdLineModuleConcurrentRegister(&this->moduleManager)); future.waitForFinished(); this->unsetCursor(); ctkCmdLineModuleUtils::messageBoxModuleRegistration(future, this->moduleManager.validationMode()); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::checkModulePaused() { if (this->currentFutureWatcher.future().isPaused()) { if (!ui->actionPause->isChecked()) { ui->actionPause->setChecked(true); } } else { if (ui->actionPause->isChecked()) { ui->actionPause->setChecked(false); } } } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::currentModuleResumed() { ui->actionPause->setChecked(false); } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::currentModuleCanceled() { ctkCmdLineModuleFrontend* frontend = this->tabList->activeTab(); if (frontend) { ui->actionCancel->setEnabled(false); ui->actionPause->setEnabled(false); ui->actionRun->setEnabled(true); QWidget* widget = qobject_cast(frontend->guiHandle()); if (widget) { widget->setEnabled(true); } } } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::currentModuleFinished() { ctkCmdLineModuleFrontend* frontend = this->tabList->activeTab(); if (frontend) { ui->actionCancel->setEnabled(false); ui->actionPause->setEnabled(false); ui->actionRun->setEnabled(true); QWidget* widget = qobject_cast(frontend->guiHandle()); if (widget) { widget->setEnabled(true); } } } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::checkXMLPressed() { xmlCheckerBackEnd->setXML(ui->m_XMLToValidate->toPlainText()); QUrl url(QString("xmlchecker://should call ctkCmdLineModuleBackendXMLChecker")); qDebug() << "ctkCLModuleExplorerMainWindow::checkXMLPressed validating:\n" << ui->m_XMLToValidate->toPlainText(); ctkCmdLineModuleManager::ValidationMode previousMode = moduleManager.validationMode(); try { ctkCmdLineModuleReference ref = moduleManager.moduleReference(url); if (ref) { moduleManager.unregisterModule(ref); } moduleManager.setValidationMode(ctkCmdLineModuleManager::STRICT_VALIDATION); moduleManager.registerModule(url); moduleManager.setValidationMode(previousMode); } catch (ctkException& except) { moduleManager.setValidationMode(previousMode); QWidget* widget = QApplication::activeModalWidget(); if (widget == NULL) widget = QApplication::activeWindow(); QMessageBox::critical(widget, tr("Failed while checking XML:"), except.message()); } } //----------------------------------------------------------------------------- void ctkCLModuleExplorerMainWindow::moduleTabActivated(ctkCmdLineModuleFrontend *module) { if (module == NULL) { ui->actionRun->setEnabled(false); ui->actionPause->setEnabled(false); ui->actionCancel->setEnabled(false); ui->actionReset->setEnabled(false); ui->outputText->setActiveFrontend(NULL); currentFutureWatcher.setFuture(ctkCmdLineModuleFuture()); } else { ui->actionRun->setEnabled(!module->isRunning()); ui->actionPause->setEnabled(module->future().canPause() && module->isRunning()); ui->actionPause->blockSignals(true); ui->actionPause->setChecked(module->isPaused()); ui->actionPause->blockSignals(false); ui->actionCancel->setEnabled(module->future().canCancel() && module->isRunning()); ui->actionReset->setEnabled(true); ui->outputText->setActiveFrontend(module); currentFutureWatcher.setFuture(module->future()); } } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerMainWindow.h000066400000000000000000000057021524622605700321710ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCLIPLUGINEXPLORERMAINWINDOW_H #define CTKCLIPLUGINEXPLORERMAINWINDOW_H #include #include #include #include #include #include #include class ctkCmdLineModuleExplorerTabList; class ctkCmdLineModuleReference; class ctkCmdLineModuleResult; class ctkSettingsDialog; class ctkCmdLineModuleBackendXMLChecker; namespace Ui { class ctkCmdLineModuleExplorerMainWindow; } /** * \class ctkCLModuleExplorerMainWindow * \brief Example application main window. */ class ctkCLModuleExplorerMainWindow : public QMainWindow { Q_OBJECT public: explicit ctkCLModuleExplorerMainWindow(QWidget *parent = 0); ~ctkCLModuleExplorerMainWindow(); void addModule(const QUrl &location); protected: void closeEvent(QCloseEvent* event); protected Q_SLOTS: void on_actionRun_triggered(); void on_actionPause_toggled(bool toggled); void on_actionCancel_triggered(); void on_actionOptions_triggered(); void on_actionLoad_triggered(); void on_actionQuit_triggered(); void on_actionReset_triggered(); void on_actionClear_Cache_triggered(); void on_actionReload_Modules_triggered(); void checkModulePaused(); void currentModuleResumed(); void currentModuleCanceled(); void currentModuleFinished(); void moduleTabActivated(ctkCmdLineModuleFrontend* module); void checkXMLPressed(); private: QScopedPointer ui; QScopedPointer tabList; ctkCmdLineModuleFrontendFactory* defaultModuleFrontendFactory; QList moduleFrontendFactories; QList moduleBackends; ctkCmdLineModuleManager moduleManager; QTimer pollPauseTimer; QFutureWatcher currentFutureWatcher; QHash frontendToOutputMap; ctkCmdLineModuleDirectoryWatcher directoryWatcher; ctkSettings settings; ctkSettingsDialog* settingsDialog; ctkCmdLineModuleBackendXMLChecker* xmlCheckerBackEnd; }; #endif // CTKCLIPLUGINEXPLORERMAINWINDOW_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerMainWindow.ui000066400000000000000000000331771524622605700323660ustar00rootroot00000000000000 ctkCmdLineModuleExplorerMainWindow 0 0 1126 933 CTK Command Line Module Explorer QMainWindow::AllowNestedDocks|QMainWindow::AllowTabbedDocks|QMainWindow::AnimatedDocks 0 -1 Qt::ElideMiddle true true 0 0 1126 22 &File &Module toolBar TopToolBarArea false 0 0 false QDockWidget::NoDockWidgetFeatures Modules 1 2 0 QAbstractItemView::NoEditTriggers Qt::ElideMiddle true true QDockWidget::NoDockWidgetFeatures Progress Information 1 0 0 2 6 0 0 0 Qt::Horizontal 40 20 Clear QFrame::NoFrame true 0 0 250 144 0 0 Qt::Horizontal Qt::Vertical 20 64 QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Qt::BottomDockWidgetArea|Qt::RightDockWidgetArea|Qt::TopDockWidgetArea Output 8 0 true 0 0 QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable XML Checker 1 Qt::Horizontal 40 20 Check Qt::Horizontal true 0 0 230 108 0 :/icons/run.png:/icons/run.png Run Run module Ctrl+R :/icons/stop.png:/icons/stop.png &Cancel Cancel module Ctrl+C &Load Modules... Load module Ctrl+L E&xit true :/icons/pause.png:/icons/pause.png &Pause Pause module Ctrl+P &Options... Reset Reset to default values Clear Cache Reload Modules ctkSearchBox QLineEdit
ctkSearchBox.h
ctkCmdLineModuleExplorerOutputText QTextEdit
ctkCmdLineModuleExplorerOutputText.h
ctkCmdLineModuleExplorerProgressListWidget QWidget
ctkCmdLineModuleExplorerProgressListWidget.h
1
ctkCmdLineModuleExplorerTreeWidget QTreeView
ctkCmdLineModuleExplorerTreeWidget.h
ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerModulesSettings.cpp000066400000000000000000000121261524622605700335770ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerModulesSettings.h" #include "ctkCmdLineModuleExplorerConstants.h" #include "ctkCmdLineModuleExplorerUtils.h" #include "ctkCmdLineModuleExplorerShowXmlAction.h" #include "ctkCmdLineModuleUtils.h" #include "ui_ctkCmdLineModuleExplorerModulesSettings.h" #include #include #include #include #include #include ctkCmdLineModuleExplorerModulesSettings::ctkCmdLineModuleExplorerModulesSettings(ctkCmdLineModuleManager *moduleManager) : ui(new Ui::ctkCmdLineModuleExplorerModulesSettings) , ModuleManager(moduleManager) , ShowXmlAction(new ctkCmdLineModuleExplorerShowXmlAction(this)) , ModulesRegistered(false) { ui->setupUi(this); ui->PathListButtonsWidget->init(ui->PathListWidget); ui->PathListWidget->addAction(this->ShowXmlAction); ui->PathListWidget->setContextMenuPolicy(Qt::ActionsContextMenu); this->ShowXmlAction->setEnabled(false); connect(ui->PathListWidget, SIGNAL(currentPathChanged(QString,QString)), SLOT(pathSelected(QString))); connect(ui->PathListWidget, SIGNAL(pathsChanged(QStringList,QStringList)), SLOT(pathsAdded(QStringList))); this->registerProperty(ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES, ui->PathListWidget, "paths", SIGNAL(pathsChanged(QStringList,QStringList))); } ctkCmdLineModuleExplorerModulesSettings::~ctkCmdLineModuleExplorerModulesSettings() { delete ui; } void ctkCmdLineModuleExplorerModulesSettings::applySettings() { QStringList oldModules = this->previousPropertyValue(ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES).toStringList(); QStringList newModules = this->propertyValue(ctkCmdLineModuleExplorerConstants::KEY_REGISTERED_MODULES).toStringList(); QStringList removedModules; QStringList addedModules = newModules; foreach(const QString& oldModule, oldModules) { if (!newModules.contains(oldModule)) { removedModules << oldModule; } else { addedModules.removeAll(oldModule); } } this->setCursor(Qt::BusyCursor); QFuture future1 = QtConcurrent::mapped(removedModules, ctkCmdLineModuleConcurrentUnRegister(this->ModuleManager)); QFuture future2 = QtConcurrent::mapped(addedModules, ctkCmdLineModuleConcurrentRegister(this->ModuleManager, true)); ctkSettingsPanel::applySettings(); future1.waitForFinished(); /* QFutureSynchronizer sync; sync.addFuture(future1); sync.addFuture(future2); sync.waitForFinished(); */ this->ModulesRegistered = true; this->pathsAdded(addedModules); this->ModulesRegistered = false; this->unsetCursor(); future2.waitForFinished(); ctkCmdLineModuleUtils::messageBoxModuleRegistration(future2, this->ModuleManager->validationMode()); } void ctkCmdLineModuleExplorerModulesSettings::pathSelected(const QString &path) { this->ShowXmlAction->setEnabled(!path.isEmpty()); ctkCmdLineModuleReference moduleRef = this->ModuleManager->moduleReference(QUrl::fromLocalFile(path)); this->ShowXmlAction->setModuleReference(moduleRef); } void ctkCmdLineModuleExplorerModulesSettings::pathsAdded(const QStringList &paths) { // Check the validity of the entries foreach(const QString& path, paths) { ctkCmdLineModuleReference moduleRef = this->ModuleManager->moduleReference(QUrl::fromLocalFile(path)); if (!moduleRef || !moduleRef.xmlValidationErrorString().isEmpty()) { QStandardItem* item = ui->PathListWidget->item(path); if (this->WarningIcon.isNull()) { this->WarningIcon = ctkCmdLineModuleExplorerUtils::createIconOverlay( item->icon().pixmap(item->icon().availableSizes().front()), QApplication::style()->standardPixmap(QStyle::SP_MessageBoxWarning)); } QString toolTip = path + "\n\n" + tr("Warning") + ":\n\n"; if (moduleRef) { item->setIcon(this->WarningIcon); toolTip += moduleRef.xmlValidationErrorString(); } else if (this->ModulesRegistered) { item->setIcon(this->WarningIcon); toolTip += tr("No XML output available."); } else { toolTip = path; } item->setToolTip(toolTip); } } } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerModulesSettings.h000066400000000000000000000033071524622605700332450ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERMODULESSETTINGS_H #define CTKCMDLINEMODULEEXPLORERMODULESSETTINGS_H #include #include class ctkCmdLineModuleManager; class ctkCmdLineModuleExplorerShowXmlAction; namespace Ui { class ctkCmdLineModuleExplorerModulesSettings; } class ctkCmdLineModuleExplorerModulesSettings : public ctkSettingsPanel { Q_OBJECT public: explicit ctkCmdLineModuleExplorerModulesSettings(ctkCmdLineModuleManager* moduleManager); ~ctkCmdLineModuleExplorerModulesSettings(); void applySettings(); private: Q_SLOT void pathSelected(const QString& path); Q_SLOT void pathsAdded(const QStringList& paths); Ui::ctkCmdLineModuleExplorerModulesSettings *ui; ctkCmdLineModuleManager* ModuleManager; ctkCmdLineModuleExplorerShowXmlAction* ShowXmlAction; QIcon WarningIcon; bool ModulesRegistered; }; #endif // CTKCMDLINEMODULEEXPLORERMODULESSETTINGS_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerModulesSettings.ui000066400000000000000000000047551524622605700334430ustar00rootroot00000000000000 ctkCmdLineModuleExplorerModulesSettings 0 0 400 300 Registered Modules 6 0 0 0 Registered Modules ctkPathListWidget::FilesOnly ctkPathListWidget::Executable|ctkPathListWidget::Exists|ctkPathListWidget::Readable true Qt::Vertical Qt::Vertical 20 40 ctkPathListButtonsWidget QWidget
ctkPathListButtonsWidget.h
ctkPathListWidget QListView
ctkPathListWidget.h
ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerOutputText.cpp000066400000000000000000000075631524622605700326240ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerOutputText.h" #include "ctkCmdLineModuleFrontend.h" #include "ctkCmdLineModuleFuture.h" #include "ctkCmdLineModuleFutureWatcher.h" ctkCmdLineModuleExplorerOutputText::ctkCmdLineModuleExplorerOutputText(QWidget* parent) : QTextEdit(parent) , CurrentWatcher(NULL) , CurrentFrontend(NULL) { } ctkCmdLineModuleExplorerOutputText::~ctkCmdLineModuleExplorerOutputText() { qDeleteAll(this->FrontendToWatcherMap); } void ctkCmdLineModuleExplorerOutputText::setActiveFrontend(ctkCmdLineModuleFrontend* moduleFrontend) { if (this->CurrentFrontend == moduleFrontend) return; if (this->CurrentFrontend) { if (this->CurrentWatcher) { this->CurrentWatcher->disconnect(); } this->CurrentFrontend->disconnect(); // save the current output text this->FrontendToOutputMap[this->CurrentFrontend] = this->toHtml(); this->clear(); } this->CurrentFrontend = moduleFrontend; if (moduleFrontend) { // restore previous content this->setHtml(this->FrontendToOutputMap[moduleFrontend]); QTextCursor endCursor = this->textCursor(); endCursor.movePosition(QTextCursor::End); this->setTextCursor(endCursor); this->CurrentWatcher = FrontendToWatcherMap[moduleFrontend]; if (this->CurrentWatcher == NULL) { this->CurrentWatcher = new ctkCmdLineModuleFutureWatcher; this->FrontendToWatcherMap[moduleFrontend] = this->CurrentWatcher; } connect(this->CurrentFrontend, SIGNAL(started()), SLOT(frontendStarted())); connect(this->CurrentWatcher, SIGNAL(outputDataReady()), SLOT(outputDataReady())); connect(this->CurrentWatcher, SIGNAL(errorDataReady()), SLOT(errorDataReady())); this->CurrentWatcher->setFuture(moduleFrontend->future()); // if the frontend is already finished get any output we have not yet fetched if (moduleFrontend->future().isFinished()) { this->outputDataReady(); this->errorDataReady(); } } else { if (this->CurrentWatcher) { this->CurrentWatcher->disconnect(); this->CurrentWatcher = NULL; } if (this->CurrentFrontend) { this->CurrentFrontend->disconnect(); this->CurrentFrontend = NULL; } this->clear(); } } void ctkCmdLineModuleExplorerOutputText::frontendRemoved(ctkCmdLineModuleFrontend *frontend) { delete this->FrontendToWatcherMap[frontend]; this->FrontendToWatcherMap.remove(frontend); this->FrontendToOutputMap.remove(frontend); } void ctkCmdLineModuleExplorerOutputText::frontendStarted() { this->clear(); this->FrontendToOutputMap[this->CurrentFrontend].clear(); this->CurrentWatcher->setFuture(this->CurrentFrontend->future()); } void ctkCmdLineModuleExplorerOutputText::outputDataReady() { QByteArray newOutput = this->CurrentWatcher->readPendingOutputData(); this->setTextColor(QColor(Qt::black)); this->insertPlainText(newOutput.data()); } void ctkCmdLineModuleExplorerOutputText::errorDataReady() { QByteArray newOutput = this->CurrentWatcher->readPendingErrorData(); this->setTextColor(QColor(Qt::darkRed)); this->insertPlainText(newOutput.data()); } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerOutputText.h000066400000000000000000000033031524622605700322550ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLOREROUTPUTTEXT_H #define CTKCMDLINEMODULEEXPLOREROUTPUTTEXT_H #include class ctkCmdLineModuleFrontend; class ctkCmdLineModuleFutureWatcher; class ctkCmdLineModuleExplorerOutputText : public QTextEdit { Q_OBJECT public: ctkCmdLineModuleExplorerOutputText(QWidget* parent = 0); ~ctkCmdLineModuleExplorerOutputText(); public Q_SLOTS: void setActiveFrontend(ctkCmdLineModuleFrontend* frontend); void frontendRemoved(ctkCmdLineModuleFrontend* frontend); private Q_SLOTS: void frontendStarted(); void outputDataReady(); void errorDataReady(); private: ctkCmdLineModuleFutureWatcher* CurrentWatcher; ctkCmdLineModuleFrontend* CurrentFrontend; QHash FrontendToWatcherMap; QHash FrontendToOutputMap; }; #endif // CTKCMDLINEMODULEEXPLOREROUTPUTTEXT_H ctkCmdLineModuleExplorerProgressListWidget.cpp000066400000000000000000000105111524622605700341670ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerProgressListWidget.h" #include "ctkCmdLineModuleExplorerProgressWidget.h" #include "ctkCmdLineModuleFrontend.h" #include "ctkCmdLineModuleReference.h" #include "ctkCmdLineModuleDescription.h" #include ctkCmdLineModuleExplorerProgressListWidget::ctkCmdLineModuleExplorerProgressListWidget(QWidget *parent) : QWidget(parent) , CurrentWidget(NULL) { QVBoxLayout* progressLayout = new QVBoxLayout(); progressLayout->setContentsMargins(0, 0, 0, 0); this->setLayout(progressLayout); } void ctkCmdLineModuleExplorerProgressListWidget::addProgressWidget(ctkCmdLineModuleFrontend *frontend, const ctkCmdLineModuleFuture &future) { ctkCmdLineModuleExplorerProgressWidget* progressWidget = FrontendToProgressWidgetMap[frontend]; if (progressWidget == NULL) { progressWidget = new ctkCmdLineModuleExplorerProgressWidget(); FrontendToProgressWidgetMap[frontend] = progressWidget; ProgressWidgetToFrontendMap[progressWidget] = frontend; connect(progressWidget, SIGNAL(clicked()), SLOT(progressWidgetClicked())); connect(progressWidget, SIGNAL(destroyed(QObject*)), SLOT(progressWidgetDestroyed(QObject*))); this->layout()->addWidget(progressWidget); } progressWidget->setHighlightStyle(false); progressWidget->setTitle(frontend->moduleReference().description().title()); progressWidget->setFuture(future); } void ctkCmdLineModuleExplorerProgressListWidget::progressWidgetDestroyed(QObject* widget) { ctkCmdLineModuleExplorerProgressWidget* progressWidget = static_cast(widget); if (CurrentWidget == progressWidget) { CurrentWidget = NULL; } ctkCmdLineModuleFrontend* frontend = ProgressWidgetToFrontendMap.take(progressWidget); FrontendToProgressWidgetMap.remove(frontend); } void ctkCmdLineModuleExplorerProgressListWidget::removeProgressWidget(ctkCmdLineModuleFrontend *frontend) { if (FrontendToProgressWidgetMap.contains(frontend)) { FrontendToProgressWidgetMap[frontend]->deleteLater(); } } void ctkCmdLineModuleExplorerProgressListWidget::setCurrentProgressWidget(ctkCmdLineModuleFrontend *frontend) { if (frontend == NULL && CurrentWidget != NULL) { CurrentWidget->setHighlightStyle(false); CurrentWidget = NULL; return; } if (CurrentWidget != NULL) { CurrentWidget->setHighlightStyle(false); CurrentWidget = NULL; } ctkCmdLineModuleExplorerProgressWidget* progressWidget = FrontendToProgressWidgetMap[frontend]; if (progressWidget) { progressWidget->setHighlightStyle(true); CurrentWidget = progressWidget; } } void ctkCmdLineModuleExplorerProgressListWidget::progressWidgetClicked() { ctkCmdLineModuleExplorerProgressWidget* progressWidget = static_cast(this->sender()); ctkCmdLineModuleFrontend* frontend = ProgressWidgetToFrontendMap[progressWidget]; Q_ASSERT(frontend); this->setCurrentProgressWidget(frontend); emit progressWidgetClicked(frontend); } void ctkCmdLineModuleExplorerProgressListWidget::clearList() { QList widgetsToRemove; QHashIterator iter(FrontendToProgressWidgetMap); while (iter.hasNext()) { iter.next(); if (!iter.key()->isRunning()) { widgetsToRemove.push_back(iter.value()); } } foreach(ctkCmdLineModuleExplorerProgressWidget* widget, widgetsToRemove) { widget->deleteLater(); } } ctkCmdLineModuleExplorerProgressListWidget.h000066400000000000000000000037561524622605700336510ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERPROGRESSLISTWIDGET_H #define CTKCMDLINEMODULEEXPLORERPROGRESSLISTWIDGET_H #include #include class ctkCmdLineModuleFrontend; class ctkCmdLineModuleFuture; class ctkCmdLineModuleExplorerProgressWidget; class ctkCmdLineModuleExplorerProgressListWidget : public QWidget { Q_OBJECT public: explicit ctkCmdLineModuleExplorerProgressListWidget(QWidget *parent = 0); void addProgressWidget(ctkCmdLineModuleFrontend* frontend, const ctkCmdLineModuleFuture& future); signals: void progressWidgetClicked(ctkCmdLineModuleFrontend* frontend); public slots: void removeProgressWidget(ctkCmdLineModuleFrontend* frontend); void setCurrentProgressWidget(ctkCmdLineModuleFrontend* frontend); void progressWidgetClicked(); void clearList(); private slots: void progressWidgetDestroyed(QObject* progressWidget); private: QHash FrontendToProgressWidgetMap; QHash ProgressWidgetToFrontendMap; ctkCmdLineModuleExplorerProgressWidget* CurrentWidget; }; #endif // CTKCMDLINEMODULEEXPLORERPROGRESSLISTWIDGET_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerProgressWidget.cpp000066400000000000000000000116251524622605700334210ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include #include #include "ctkCmdLineModuleExplorerProgressWidget.h" #include "ui_ctkCmdLineModuleExplorerProgressWidget.h" ctkCmdLineModuleExplorerProgressWidget::ctkCmdLineModuleExplorerProgressWidget(QWidget *parent) : QWidget(parent) , ui(new Ui::ctkCmdLineModuleExplorerProgressWidget) { ui->setupUi(this); ui->RemoveButton->setIcon(QApplication::style()->standardIcon(QStyle::SP_TitleBarCloseButton)); // Due to Qt bug 12152, we cannot listen to the "paused" signal because it is // not emitted directly when the QFuture is paused. Instead, it is emitted after // resuming the future, after the "resume" signal has been emitted... we use // a polling approach instead. PollPauseTimer.setInterval(300); connect(&PollPauseTimer, SIGNAL(timeout()), SLOT(checkModulePaused())); connect(&FutureWatcher, SIGNAL(started()), SLOT(moduleStarted())); connect(&FutureWatcher, SIGNAL(canceled()), SLOT(moduleCanceled())); connect(&FutureWatcher, SIGNAL(finished()), SLOT(moduleFinished())); connect(&FutureWatcher, SIGNAL(resumed()), SLOT(moduleResumed())); connect(&FutureWatcher, SIGNAL(progressRangeChanged(int,int)), SLOT(moduleProgressRangeChanged(int,int))); connect(&FutureWatcher, SIGNAL(progressTextChanged(QString)), ui->ProgressText, SLOT(setText(QString))); connect(&FutureWatcher, SIGNAL(progressValueChanged(int)), ui->ProgressBar, SLOT(setValue(int))); connect(ui->CancelButton, SIGNAL(clicked()), &this->FutureWatcher, SLOT(cancel())); PollPauseTimer.start(); } ctkCmdLineModuleExplorerProgressWidget::~ctkCmdLineModuleExplorerProgressWidget() { delete ui; } void ctkCmdLineModuleExplorerProgressWidget::setFuture(const ctkCmdLineModuleFuture &future) { ui->PauseButton->setEnabled(future.canPause()); ui->CancelButton->setEnabled(future.canCancel()); ui->RemoveButton->setEnabled(!future.isRunning()); FutureWatcher.setFuture(future); } void ctkCmdLineModuleExplorerProgressWidget::setTitle(const QString &title) { ui->ProgressTitle->setText(title); } void ctkCmdLineModuleExplorerProgressWidget::setHighlightStyle(bool highlight) { QPalette::ColorRole labelRole = highlight ? QPalette::NoRole : QPalette::Midlight; ui->ProgressTitle->setForegroundRole(labelRole); ui->ProgressText->setForegroundRole(labelRole); ui->ProgressBar->setEnabled(highlight); } void ctkCmdLineModuleExplorerProgressWidget::mouseReleaseEvent(QMouseEvent*) { emit clicked(); } void ctkCmdLineModuleExplorerProgressWidget::on_PauseButton_toggled(bool toggled) { this->FutureWatcher.setPaused(toggled); } void ctkCmdLineModuleExplorerProgressWidget::on_RemoveButton_clicked() { this->deleteLater(); } void ctkCmdLineModuleExplorerProgressWidget::moduleStarted() { this->ui->ProgressBar->setMaximum(0); } void ctkCmdLineModuleExplorerProgressWidget::moduleCanceled() { this->ui->PauseButton->setEnabled(false); this->ui->PauseButton->setChecked(false); this->ui->CancelButton->setEnabled(false); this->ui->RemoveButton->setEnabled(true); } void ctkCmdLineModuleExplorerProgressWidget::moduleFinished() { this->ui->PauseButton->setEnabled(false); this->ui->PauseButton->setChecked(false); this->ui->CancelButton->setEnabled(false); this->ui->RemoveButton->setEnabled(true); } void ctkCmdLineModuleExplorerProgressWidget::checkModulePaused() { if (this->FutureWatcher.future().isPaused()) { if (!ui->PauseButton->isChecked()) { ui->PauseButton->setChecked(true); } } else { if (ui->PauseButton->isChecked()) { ui->PauseButton->setChecked(false); } } } void ctkCmdLineModuleExplorerProgressWidget::moduleResumed() { this->ui->PauseButton->setChecked(false); } void ctkCmdLineModuleExplorerProgressWidget::moduleProgressRangeChanged(int progressMin, int progressMax) { this->ui->ProgressBar->setMinimum(progressMin); this->ui->ProgressBar->setMaximum(progressMax); } void ctkCmdLineModuleExplorerProgressWidget::moduleProgressTextChanged(const QString& progressText) { Q_UNUSED(progressText) } void ctkCmdLineModuleExplorerProgressWidget::moduleProgressValueChanged(int progressValue) { Q_UNUSED(progressValue) } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerProgressWidget.h000066400000000000000000000043551524622605700330700ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERPROGRESSWIDGET_H #define CTKCMDLINEMODULEEXPLORERPROGRESSWIDGET_H #include "ctkCmdLineModuleResult.h" #include "ctkCmdLineModuleFutureWatcher.h" #include #include #include class ctkCmdLineModuleFuture; namespace Ui { class ctkCmdLineModuleExplorerProgressWidget; } /** * \class ctkCmdLineModuleExplorerProgressWidget * \brief Example application progress update widget. */ class ctkCmdLineModuleExplorerProgressWidget : public QWidget { Q_OBJECT public: ctkCmdLineModuleExplorerProgressWidget(QWidget *parent = 0); ~ctkCmdLineModuleExplorerProgressWidget(); void setFuture(const ctkCmdLineModuleFuture& future); void setTitle(const QString& title); void setHighlightStyle(bool highlight); Q_SIGNALS: void clicked(); protected: void mouseReleaseEvent(QMouseEvent*); private Q_SLOTS: void on_PauseButton_toggled(bool toggled); void on_RemoveButton_clicked(); void checkModulePaused(); void moduleStarted(); void moduleCanceled(); void moduleFinished(); void moduleResumed(); void moduleProgressRangeChanged(int progressMin, int progressMax); void moduleProgressTextChanged(const QString& progressText); void moduleProgressValueChanged(int progressValue); private: Ui::ctkCmdLineModuleExplorerProgressWidget *ui; ctkCmdLineModuleFutureWatcher FutureWatcher; QTimer PollPauseTimer; }; #endif // CTKCMDLINEMODULEEXPLORERPROGRESSWIDGET_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerProgressWidget.ui000066400000000000000000000063671524622605700332630ustar00rootroot00000000000000 ctkCmdLineModuleExplorerProgressWidget 0 0 400 83 Progress 2 0 0 0 0 TextLabel 0 Pause :/icons/pause.png:/icons/pause.png true true Cancel :/icons/stop.png:/icons/stop.png true Remove true TextLabel Qt::Vertical QSizePolicy::Fixed 20 4 Qt::Horizontal ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerShowXmlAction.cpp000066400000000000000000000051131524622605700332030ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerShowXmlAction.h" #include "ctkCmdLineModuleDescription.h" #include "ctkCmdLineModuleXmlException.h" #include #include #include #include #include #include #include #include ctkCmdLineModuleExplorerShowXmlAction::ctkCmdLineModuleExplorerShowXmlAction(QObject *parent) : QAction(parent) { this->setText(tr("Show XML Description")); connect(this, SIGNAL(triggered()), SLOT(run())); } void ctkCmdLineModuleExplorerShowXmlAction::setModuleReference(const ctkCmdLineModuleReference& ref) { this->ModuleRef = ref; } void ctkCmdLineModuleExplorerShowXmlAction::run() { QDialog* dialog = new QDialog(); try { dialog->setWindowTitle(this->ModuleRef.description().title()); } catch (const ctkCmdLineModuleXmlException&) { dialog->setWindowTitle(this->ModuleRef.location().toString()); } dialog->setLayout(new QVBoxLayout()); QHBoxLayout* buttonLayout = new QHBoxLayout(); buttonLayout->addStretch(1); QPushButton* closeButton = new QPushButton(tr("Close"), dialog); buttonLayout->addWidget(closeButton); QTextEdit* textEdit = new QTextEdit(dialog); textEdit->setPlainText(this->ModuleRef.rawXmlDescription().data()); QLabel* statusLabel = new QLabel(dialog); statusLabel->setWordWrap(true); if (this->ModuleRef.xmlValidationErrorString().isEmpty()) { statusLabel->setText(tr("No validation errors.")); } else { statusLabel->setText(this->ModuleRef.xmlValidationErrorString()); } dialog->layout()->addWidget(statusLabel); dialog->layout()->addWidget(textEdit); dialog->layout()->addItem(buttonLayout); connect(closeButton, SIGNAL(clicked()), dialog, SLOT(close())); dialog->resize(800, 600); dialog->show(); } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerShowXmlAction.h000066400000000000000000000024621524622605700326540ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERSHOWXMLACTION_H #define CTKCMDLINEMODULEEXPLORERSHOWXMLACTION_H #include "ctkCmdLineModuleReference.h" #include class ctkCmdLineModuleExplorerShowXmlAction : public QAction { Q_OBJECT public: ctkCmdLineModuleExplorerShowXmlAction(QObject* parent); void setModuleReference(const ctkCmdLineModuleReference& ref); protected: Q_SLOT virtual void run(); private: ctkCmdLineModuleReference ModuleRef; }; #endif // CTKCMDLINEMODULEEXPLORERSHOWXMLACTION_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerTabList.cpp000066400000000000000000000102511524622605700320050ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerTabList.h" #include #include #include #include #include #include #include #include #include Q_DECLARE_METATYPE(ctkCmdLineModuleFrontendFactory*) ctkCmdLineModuleExplorerTabList::ctkCmdLineModuleExplorerTabList(QTabWidget *tabWidget) : TabWidget(tabWidget) { Q_ASSERT(TabWidget != NULL); connect(TabWidget, SIGNAL(currentChanged(int)), SLOT(tabIndexChanged(int))); connect(TabWidget, SIGNAL(tabCloseRequested(int)), SLOT(tabCloseRequested(int))); } ctkCmdLineModuleExplorerTabList::~ctkCmdLineModuleExplorerTabList() { qDeleteAll(this->TabIndexToFrontend); } ctkCmdLineModuleFrontend* ctkCmdLineModuleExplorerTabList::activeTab() const { int index = this->TabWidget->currentIndex(); if (index < 0) return NULL; return this->TabIndexToFrontend[index]; } QList ctkCmdLineModuleExplorerTabList::tabs() const { return this->TabIndexToFrontend; } void ctkCmdLineModuleExplorerTabList::setActiveTab(ctkCmdLineModuleFrontend *frontend) { this->TabWidget->setCurrentIndex(this->TabIndexToFrontend.indexOf(frontend)); } void ctkCmdLineModuleExplorerTabList::addTab(ctkCmdLineModuleFrontend* moduleFrontend) { QWidget* widget = qobject_cast(moduleFrontend->guiHandle()); this->TabIndexToFrontend.push_back(moduleFrontend); int index = this->TabWidget->addTab(widget, moduleFrontend->moduleReference().description().title()); this->TabWidget->setCurrentIndex(index); } void ctkCmdLineModuleExplorerTabList::tabIndexChanged(int index) { if (index < 0) { emit tabActivated(NULL); return; } emit tabActivated(this->TabIndexToFrontend[index]); } void ctkCmdLineModuleExplorerTabList::tabCloseRequested(int index) { ctkCmdLineModuleFrontend* frontend = this->TabIndexToFrontend[index]; bool removeTab = false; if (frontend->isRunning()) { if (frontend->future().canCancel()) { QMessageBox::StandardButton button = QMessageBox::warning(QApplication::topLevelWidgets().front(), tr("Closing a running module"), //: %1 is the module name tr("The module '%1' is still running.\n" "Closing the tab will cancel the current computation.") .arg(frontend->moduleReference().description().title()), QMessageBox::Ok | QMessageBox::Cancel); if (button == QMessageBox::Ok) { frontend->future().cancel(); removeTab = true; } } else { QMessageBox::information(QApplication::topLevelWidgets().front(), tr("Closing not possible"), //: %1 is the module name tr("The module '%1' is still running " "and does not support being canceled.") .arg(frontend->moduleReference().description().title())); } } else { removeTab = true; } if (removeTab) { this->TabIndexToFrontend.removeAt(index); this->TabWidget->removeTab(index); emit this->tabClosed(frontend); delete frontend; } } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerTabList.h000066400000000000000000000035411524622605700314560ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERTABLIST_H #define CTKCMDLINEMODULEEXPLORERTABLIST_H class ctkCmdLineModuleFrontend; class ctkCmdLineModuleManager; #include #include class QTabWidget; class QModelIndex; /** * \class ctkCmdLineModuleExplorerTabList * \brief Example application tab list */ class ctkCmdLineModuleExplorerTabList : public QObject { Q_OBJECT public: ctkCmdLineModuleExplorerTabList(QTabWidget* tabWidget); ~ctkCmdLineModuleExplorerTabList(); ctkCmdLineModuleFrontend* activeTab() const; QList tabs() const; Q_SLOT void setActiveTab(ctkCmdLineModuleFrontend* frontend); Q_SLOT void addTab(ctkCmdLineModuleFrontend* frontend); Q_SIGNAL void tabActivated(ctkCmdLineModuleFrontend* module); Q_SIGNAL void tabClosed(ctkCmdLineModuleFrontend* module); private: Q_SLOT void tabIndexChanged(int index); Q_SLOT void tabCloseRequested(int index); private: QTabWidget* TabWidget; QList TabIndexToFrontend; }; #endif // CTKCMDLINEMODULEEXPLORERTABLIST_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerTreeWidget.cpp000066400000000000000000000230731524622605700325140ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerTreeWidget.h" #include "ctkCmdLineModuleExplorerShowXmlAction.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include QString ctkCmdLineModuleExplorerTreeWidget::CATEGORY_UNKNOWN = ctkCmdLineModuleExplorerTreeWidget::tr("Uncategorized"); class ctkCmdLineModuleTreeWidgetItem : public QStandardItem { public: ctkCmdLineModuleTreeWidgetItem(const ctkCmdLineModuleReference& moduleRef) : QStandardItem() , ModuleRef(moduleRef) { QString title; try { title = ModuleRef.description().title(); } catch (const ctkCmdLineModuleXmlException&) { title = ModuleRef.location().toString(); } this->setText(title + " [" + ModuleRef.backend()->name() + "]"); this->setData(QVariant::fromValue(ModuleRef)); QString toolTip = ModuleRef.location().toString(); if (!ModuleRef.xmlValidationErrorString().isEmpty()) { this->setIcon(QApplication::style()->standardIcon(QStyle::SP_MessageBoxWarning)); toolTip += QString("\n\n%1\n\n%2") .arg(ctkCmdLineModuleExplorerTreeWidget::tr("Warning:")) .arg(ModuleRef.xmlValidationErrorString()); } this->setToolTip(toolTip); } ctkCmdLineModuleReference moduleReference() const { return ModuleRef; } private: ctkCmdLineModuleReference ModuleRef; }; ctkCmdLineModuleExplorerTreeWidget::ctkCmdLineModuleExplorerTreeWidget(QWidget *parent) : QTreeView(parent) , DefaultFrontendFactory(NULL) { this->ContextMenu = new QMenu(this); this->ShowFrontendMenu = this->ContextMenu->addMenu(tr("Create Frontend")); this->ShowXmlAction = new ctkCmdLineModuleExplorerShowXmlAction(this); this->ContextMenu->addAction(ShowXmlAction); connect(this, SIGNAL(doubleClicked(QModelIndex)), SLOT(moduleDoubleClicked(QModelIndex))); TreeModel = new QStandardItemModel(this); FilterProxyModel = new ModuleSortFilterProxyModel(this); FilterProxyModel->setSourceModel(TreeModel); FilterProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); FilterProxyModel->setDynamicSortFilter(true); this->setModel(FilterProxyModel); } void ctkCmdLineModuleExplorerTreeWidget::setModuleFrontendFactories(const QList &frontendFactories, ctkCmdLineModuleFrontendFactory* defaultFactory) { this->FrontendFactories = frontendFactories; this->DefaultFrontendFactory = defaultFactory; this->ShowFrontendMenu->clear(); foreach(ctkCmdLineModuleFrontendFactory* factory, this->FrontendFactories) { QAction* action = this->ShowFrontendMenu->addAction(factory->name(), this, SLOT(frontendFactoryActionTriggered())); this->ActionsToFrontendFactoryMap[action] = factory; action->setToolTip(factory->description()); } } void ctkCmdLineModuleExplorerTreeWidget::addModuleItem(const ctkCmdLineModuleReference &moduleRef) { QString categories; try { categories = moduleRef.description().category(); } catch (const ctkCmdLineModuleXmlException&) { categories = CATEGORY_UNKNOWN; } if (categories.isEmpty()) { categories = CATEGORY_UNKNOWN; } QString currentCategories; QStandardItem* oldRootItem = NULL; #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QStringList categoryList = categories.split('.', Qt::SkipEmptyParts); #else QStringList categoryList = categories.split('.', QString::SkipEmptyParts); #endif foreach (const QString& category, categoryList) { currentCategories += (currentCategories.isEmpty() ? QString() : QString(".")) + category; QStandardItem* rootItem = TreeWidgetCategories[currentCategories]; if (rootItem == NULL) { rootItem = new QStandardItem(category); TreeWidgetCategories[currentCategories] = rootItem; if (oldRootItem != NULL) { oldRootItem->appendRow(rootItem); } else { TreeModel->appendRow(rootItem); } } oldRootItem = rootItem; } QStandardItem* moduleItem = new ctkCmdLineModuleTreeWidgetItem(moduleRef); TreeWidgetItems[moduleRef] = moduleItem; oldRootItem->appendRow(moduleItem); } void ctkCmdLineModuleExplorerTreeWidget::removeModuleItem(const ctkCmdLineModuleReference &moduleRef) { QStandardItem* treeWidgetItem = TreeWidgetItems.take(moduleRef); if (treeWidgetItem == NULL) return; QString categories; try { categories = moduleRef.description().category(); } catch (const ctkCmdLineModuleXmlException&) { categories = CATEGORY_UNKNOWN; } if (categories.isEmpty()) { categories = CATEGORY_UNKNOWN; } #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QStringList categoryList = categories.split('.', Qt::SkipEmptyParts); #else QStringList categoryList = categories.split('.', QString::SkipEmptyParts); #endif while (!categoryList.isEmpty()) { QStandardItem* rootItem = TreeWidgetCategories[categoryList.join(".")]; Q_ASSERT(rootItem); rootItem->removeRow(treeWidgetItem->row()); if (rootItem->rowCount() == 0) { treeWidgetItem = rootItem; TreeWidgetCategories.remove(categoryList.join(".")); categoryList.pop_back(); } else { break; } } if (categoryList.isEmpty()) { TreeModel->removeRow(treeWidgetItem->row()); } } void ctkCmdLineModuleExplorerTreeWidget::contextMenuEvent(QContextMenuEvent *event) { QModelIndex index = this->indexAt(this->viewport()->mapFromGlobal(event->globalPos())); if (index.isValid() && index.data(Qt::UserRole+1).isValid()) { this->ContextReference = index.data(Qt::UserRole+1).value(); this->ShowXmlAction->setModuleReference(this->ContextReference); this->ContextMenu->exec(event->globalPos()); event->accept(); } else { this->ContextReference = ctkCmdLineModuleReference(); event->ignore(); } } void ctkCmdLineModuleExplorerTreeWidget::moduleDoubleClicked(const QModelIndex &index) { if (this->DefaultFrontendFactory == NULL) return; QVariant data = index.data(Qt::UserRole+1); if (!data.isValid()) return; ctkCmdLineModuleReference moduleRef = data.value(); if (!moduleRef) return; this->createFrontend(moduleRef, this->DefaultFrontendFactory); } void ctkCmdLineModuleExplorerTreeWidget::frontendFactoryActionTriggered() { ctkCmdLineModuleFrontendFactory* frontendFactory = this->ActionsToFrontendFactoryMap[static_cast(this->sender())]; this->createFrontend(this->ContextReference, frontendFactory); } void ctkCmdLineModuleExplorerTreeWidget::setFilter(const QString &filter) { this->FilterProxyModel->setFilterWildcard(filter); } ctkCmdLineModuleFrontend* ctkCmdLineModuleExplorerTreeWidget::createFrontend(const ctkCmdLineModuleReference &moduleRef, ctkCmdLineModuleFrontendFactory* frontendFactory) { try { moduleRef.description(); ctkCmdLineModuleFrontend* moduleFrontend = frontendFactory->create(moduleRef); emit moduleFrontendCreated(moduleFrontend); return moduleFrontend; } catch (const ctkException& e) { //: %1 is the frontend factory name and %2 is the error description QMessageBox::information(this, tr("Frontend creation failed"), tr("Creating a %1 frontend failed:\n\n%2") .arg(frontendFactory->name()) .arg(e.what()) ); return NULL; } } bool ModuleSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const { QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent); QModelIndex childIndex = ctk::modelChildIndex(sourceModel(), index, 0, 0); if (childIndex.isValid()) { int i = 0; bool accept = false; while(childIndex.isValid()) { accept = this->filterAcceptsRow(childIndex.row(), index); if (accept) return true; childIndex = ctk::modelChildIndex(sourceModel(), index, ++i, 0); } return false; } return (sourceModel()->data(index).toString().contains(filterRegExp())); } bool ModuleSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const { QVariant l = (left.model() ? left.model()->data(left, this->sortRole()) : QVariant()); QVariant r = (right.model() ? right.model()->data(right, this->sortRole()) : QVariant()); return l.toString().compare(r.toString(), this->sortCaseSensitivity()) > 0; } ModuleSortFilterProxyModel::ModuleSortFilterProxyModel(QObject *parent) : QSortFilterProxyModel(parent) { } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerTreeWidget.h000066400000000000000000000061361524622605700321620ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCMDLINEMODULEEXPLORERTREEWIDGET_H #define CTKCMDLINEMODULEEXPLORERTREEWIDGET_H #include #include #include class ctkCmdLineModuleFrontend; struct ctkCmdLineModuleFrontendFactory; class ctkCmdLineModuleExplorerShowXmlAction; class QStandardItem; class QStandardItemModel; class ModuleSortFilterProxyModel : public QSortFilterProxyModel { Q_OBJECT public: ModuleSortFilterProxyModel(QObject *parent = 0); protected: bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; bool lessThan(const QModelIndex &left, const QModelIndex &right) const; }; /** * \class ctkCmdLineModuleExplorerTreeWidget * \brief Example application tree widget. */ class ctkCmdLineModuleExplorerTreeWidget : public QTreeView { Q_OBJECT public: explicit ctkCmdLineModuleExplorerTreeWidget(QWidget* parent = 0); void setModuleFrontendFactories(const QList& frontendFactories, ctkCmdLineModuleFrontendFactory *defaultFactory); Q_SLOT void addModuleItem(const ctkCmdLineModuleReference& moduleRef); Q_SLOT void removeModuleItem(const ctkCmdLineModuleReference& moduleRef); Q_SIGNAL void moduleFrontendCreated(ctkCmdLineModuleFrontend* moduleFrontend); Q_SLOT void setFilter(const QString& filter); protected: void contextMenuEvent(QContextMenuEvent* event); private: ctkCmdLineModuleFrontend* createFrontend(const ctkCmdLineModuleReference &moduleRef, ctkCmdLineModuleFrontendFactory* frontendFactory); Q_SLOT void moduleDoubleClicked(const QModelIndex& index); Q_SLOT void frontendFactoryActionTriggered(); static QString CATEGORY_UNKNOWN; QMenu* ContextMenu; QMenu* ShowFrontendMenu; ctkCmdLineModuleExplorerShowXmlAction* ShowXmlAction; ctkCmdLineModuleReference ContextReference; QList FrontendFactories; ctkCmdLineModuleFrontendFactory* DefaultFrontendFactory; QHash TreeWidgetCategories; QHash TreeWidgetItems; QHash ActionsToFrontendFactoryMap; QStandardItemModel* TreeModel; QSortFilterProxyModel* FilterProxyModel; }; #endif // CTKCMDLINEMODULEEXPLORERTREEWIDGET_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerUtils.cpp000066400000000000000000000025221524622605700315450ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkCmdLineModuleExplorerUtils.h" #include QPixmap ctkCmdLineModuleExplorerUtils::createIconOverlay(const QPixmap &base, const QPixmap &overlay) { QPixmap result(base.width(), base.height()); result.fill(Qt::transparent); QPainter painter(&result); painter.setCompositionMode(QPainter::CompositionMode_SourceOver); painter.drawPixmap(0, 0, base); painter.drawPixmap(base.width()/2, base.height()/2, overlay.scaled(base.width()/2, base.height()/2, Qt::KeepAspectRatio)); return result; } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCmdLineModuleExplorerUtils.h000066400000000000000000000021111524622605700312040ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKCOMMANDLINEMODULEEXPLORERUTILS_H #define CTKCOMMANDLINEMODULEEXPLORERUTILS_H #include struct ctkCmdLineModuleExplorerUtils { static QPixmap createIconOverlay(const QPixmap& base, const QPixmap& overlay); }; #endif // CTKCOMMANDLINEMODULEEXPLORERUTILS_H ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/ctkCommandLineModuleExplorerMain.cpp000066400000000000000000000144371524622605700322140ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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 #include #include #include #include #include #include #include #include // CTK includes #include #include #include "ctkCmdLineModuleExplorerMainWindow.h" int main(int argc, char** argv) { QApplication myApp(argc, argv); myApp.setOrganizationName("CommonTK"); myApp.setApplicationName("CommandLineModuleExplorer"); ctkCommandLineParser cmdLineParser; cmdLineParser.setArgumentPrefix("--", "-"); cmdLineParser.setStrictModeEnabled(true); cmdLineParser.addArgument("module", "", QVariant::String, "Path to a CLI module (executable), and show the generated GUI."); cmdLineParser.addArgument("gui", "", QVariant::String, "Path to a CLI XML file, and show the generated GUI."); cmdLineParser.addArgument("validate-module", "", QVariant::String, "Path to a CLI module (executable), and validate the XML."); cmdLineParser.addArgument("validate-xml", "", QVariant::String, "Path to a CLI XML file, and validate the XML."); cmdLineParser.addArgument("string", "", QVariant::String, "An XML string to validate. Be careful to quote correctly." ); cmdLineParser.addArgument("xml", "", QVariant::Bool, "Generate XML for this application"); cmdLineParser.addArgument("verbose", "v", QVariant::Bool, "Be verbose."); cmdLineParser.addArgument("help", "h", QVariant::Bool, "Print this help text."); bool parseOkay = false; QHash args = cmdLineParser.parseArguments(argc, argv, &parseOkay); QTextStream out(stdout, QIODevice::WriteOnly); if(!parseOkay) { out << "Error parsing command line arguments: " << cmdLineParser.errorString() << '\n'; return EXIT_FAILURE; } if (args.contains("help")) { out << "Usage:\n" << cmdLineParser.helpText(); out.flush(); return EXIT_SUCCESS; } if (args.contains("validate-module")) { if (args.contains("validate-xml")) { out << "Ignoring \"validate-xml\" option.\n\n"; } QString input = args["validate-module"].toString(); if (!QFile::exists(input)) { qCritical() << "Module does not exist:" << input; return EXIT_FAILURE; } QProcess process; process.setReadChannel(QProcess::StandardOutput); process.start(input, QStringList("--xml")); if (!process.waitForFinished() || process.exitStatus() == QProcess::CrashExit || process.error() != QProcess::UnknownError) { qWarning() << "The executable at" << input << "could not be started:" << process.errorString(); return EXIT_FAILURE; } process.waitForReadyRead(); QByteArray xml = process.readAllStandardOutput(); if (args.contains("verbose")) { qDebug() << xml; } // validate the outputted xml description QBuffer xmlInput(&xml); xmlInput.open(QIODevice::ReadOnly); ctkCmdLineModuleXmlValidator validator(&xmlInput); if (!validator.validateInput()) { qCritical() << validator.errorString(); return EXIT_FAILURE; } return EXIT_SUCCESS; } else if (args.contains("validate-xml")) { QFile input(args["validate-xml"].toString()); if (!input.exists()) { qCritical() << "XML description does not exist:" << input.fileName(); return EXIT_FAILURE; } input.open(QIODevice::ReadOnly); ctkCmdLineModuleXmlValidator validator(&input); if (!validator.validateInput()) { qCritical() << validator.errorString(); return EXIT_FAILURE; } return EXIT_SUCCESS; } else if (args.contains("string")) { QByteArray byteArray; byteArray.append(args["string"].toString().toUtf8()); QBuffer buffer(&byteArray); buffer.open(QIODevice::ReadOnly); ctkCmdLineModuleXmlValidator validator(&buffer); if (!validator.validateInput()) { qCritical() << validator.errorString(); return EXIT_FAILURE; } out << "Validated successfully"; return EXIT_SUCCESS; } else if (args.contains("xml")) { out << "\n"; out << "\n"; out << " Utilities\n"; out << " ctkCommandLineModuleExplorer\n"; out << " \n"; out << " 0.0.1\n"; out << " http://commontk.org\n"; out << " Apache 2\n"; out << " Various\n"; out << " \n"; out << " \n"; out << " \n"; out << " \n"; out << " \n"; out << " inputText\n"; out << " string\n"; out << " Input text containing an XML string.\n"; out << " \n"; out << " input\n"; out << " \n"; out << " \n"; out << "\n"; out.flush(); return EXIT_SUCCESS; } ctkCLModuleExplorerMainWindow mainWindow; if (args.contains("module")) { mainWindow.addModule(args["module"].toString()); } if (args.contains("gui")) { mainWindow.addModule(QString("xmlchecker://") + args["gui"].toString()); } mainWindow.show(); return myApp.exec(); } ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/resources/000077500000000000000000000000001524622605700251255ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/resources/clear.png000066400000000000000000000031711524622605700267230ustar00rootroot00000000000000‰PNG  IHDR szzô@IDATxÚ½–kTÔuÇŸ™¿0 #ÈÅB<$ë…ØÖL³b× MW2� h¹ÙÅ­´ÍCí…m›':'„!ôh *(®iææfáp™«0â#ÃufăFÀ¾û¬çÿÂãʾç|Μÿ‹ù=ßçû<ÿ Ý-å³$Sf¥yBo^ºpE™.-V.§+ågŒÛzäãGºô»ÑrrÔi¿°‘Öœåä;62{[U>v¯ ÅŽµÁ(ûp&~4£ŸM¼Fc¡¼téMó‘MPmŒ‡Óy»Þ‡©ìMðX[¶�tôHNèU«‡ ß~ðNñÂ7‚aÓí€ê­ð¾œtá¯c�%}¹ÚÇÕV™ �òI¨7¬Jƒ¦`”™BíØŒ!Cºyï»1®Îª/ Ýƒš†£áÀßÀÆn}ñ"%Òhëÿ³V¦ ÆŸÏýÅR¶ ê�äÐçÎÁ¡÷¢‡¶¿,9¬ß'Ëרåå$Ðh‰;} 7C¸Q­LFUö ߊŠma¨)ò‚U“<¨/õÒ~MQ4šÊ]!,/xɧïdÎCÐùâìÑ©ès|Â`Ç¢ Áw¼$WÞ$J£Ñ’nM©Ø.¹dØ'GOóZ õæ@“Ÿ†°srŽFDàm¢눂ÈÓªQÑFM±�'ê±®BÃáÅø×” |*Gû‚p¦¤àlB²¡�Sø3yZÕ%ô$/Úmmqä@þÓ“�å+à› 9lIIè[´êÄYx×GÀ¶yÒ!m±ôgM-$O˰—6ާ[AM“\ŽÊ¨(|4[ãý†­ÿ€ûZzZÖãôáh—®„Š-åäMžÔz¢Žr"g²}¤È �¢J¹îcp;7ÁÝ�Š~ûb\ïúMêùý¼7uÉÉSz�ház ¹6xÓ°j¥ÿðÀÅ ÷fÃݳ ƒ^Ì K1h{W-Óp¹å´Õ­¼­Û#´êŠ)Ò“&âNäP™£~1†.¿ÊE—`ðÂK¸Ö² ý¶%èkI‚³1mº‰°ÿ¼,ÝúR¿Ëº"Š'OI[L_ušRqË‘Ž!û|Ü´>ƒþÎp©~6ú¬³qùL,§cÑðƒ7ºÌ qÉúéð©ý¯×”ÐlÏ(¢-VÍ÷õŽt t$âZã1ЕŠîÚY¸jž»!öÚ´âqæ;�§Sqµ#�—3ÎÅæ3=ñ\X}öû)®ëô4ÄâZSœ 3Ñß>�Ç'Âyn&š~ E»Q�VÃ,.<ŽçÂißËOÉý|‡|­+ÿ_U%L¸q¥uºô!\05‘¸mû_Ç ñºŒ‰8{ÌV�uóQ÷ošªÑkß�Nó;ƒ†Rÿ+Z-£ûø ©-¡›ÝMkÑR‰‹õáh®àÎâp³ýiK½á0MCÃcÙ„mÆt�I�éPÌÇ¢à´0…З‚Ó|íþö`´êŸâhƒµÊ�Q ¥"˜ï†Ga;5¦ƒ28ÌÉ8UæË�Rt˜’`oXŠó•ó`,Å™£ ƒêBÊMH¸ó°’ÐoÔ¸ÿ|IÏÕ}rã‚e-wå�NC8êÊ}ÑmŠ@oÛ*îV�æÊÉl0†}Z4“áìʆÃòt%²�ãÛi')˜@f<ó«�x1ãår’kŠÉa3¯@Såü¢’áÜOñ0+ÃEËS°Õ§B·W ›9­ÆçQ{@ó÷S9òžOþN/Q4É„2AŒ?#£$0¾L£Øÿm0ŽpuŸ{ŸSà˜çn}Ð\†‹ç_ƹ“sØÔh¯]áÖ•xÝþ.ŸÔñ±ô8%0S™˜{Lø�½W âëK‘U»é<Çìî¬Ïâmÿ ìæ5à/$t7}À�/Òª„á£ùd|1…VÑcL3�‰gb`&1Áb #&àÃLç–µ†øU-qµ×f¢Q�«6Å}ê@è@u‘d`6Z¶€VÝéz¶X|&3�‰»k !Œ|äÄî3©`3­¬.$«z75ÙF%[ÖQ¦Ÿ×�B3D¦3`f¦Š�?È„ßS|ýJIoñO�¢‘PñÀÉâáÑLŒH4%ÆÉ„1™ 1M™xæ}Ið“‹+î!˜  û‰ 4 ’0RAD¼¹Ëÿbî#%¼IEND®B`‚ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/resources/ctkCmdLineModuleExplorer.qrc000066400000000000000000000002671524622605700325450ustar00rootroot00000000000000 run.png stop.png pause.png clear.png ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/resources/pause.png000066400000000000000000000015411524622605700267510ustar00rootroot00000000000000‰PNG  IHDR szzô(IDATxœå—=¯ÜD†ŸsæŒw/(URQGBTTtHÔ©R€øˆp»‹ Ë_H™‚žŽ!ZŠH)‰hP¸7ì§=ž¡ï®íõ®¯i3Òhdû™sÞóÎxg oz“þ�Ÿ~…ÈÕéB «Ç/¿ûük`óàáÓ/§ð@l?¶>¯N¯>ùôcÌŒ˜ ®¡ŽêD¨aµüøý³KàÉý¾X«ÙÕ£GøØð!"l6�g?üt <þVg ‚™ñâ×1AJ‰” Fˆ Þ¹{�ˆÜ-¼Á™ñüå’¤tè1Á»÷<ðϨ€„Ü,C(í”Uuþï_¾ý÷ÞûŸ\/B3?ÏÙµmu±çíç; ¢Ô5û䱉µ«j¢zÄÇVÒŸtùQ¨âprH”%í€ UB�:IÛZÊr¢GÃÉSê,Áž¯B"Ænœ¶m~T@®¨›|·¦» Í¦ä÷8\tø1¢Jº•ïÅÎIw¨²Þ&¶U¤®Ûis»s1y ”ªNÛwÉSJˆÐ[åfQ³XÕƒ êø?– ¬Ò!9¹¯·5e™x{º©²­NÆÇÓ(CÚ¯çzY®ë\ `ý%hø“ zü¨€]E!$®—�Ð nˆëòåÉøÇü˜åúuÍ«›a_Íqì@uÎ�óKpüD…Õ&  f=KUÎÔ3|_àñ$Å›´®%ïüfô^ŽÞ‚b?*Q̲zA´Õ¼×nESùQTö¯Ž:AUP§ˆ *PÚû!šÆßÊïç5Å9EMPUT…¢pÝ]=•u@„¢h‚™b^qæruN)f=&ò·p@ð&M0‡ù<:¯9àÜõöÀD~T‚÷‚sŠóŠ+¾p8SŠ™ëíê©ü-0Ô媜wø™ÃÏ óŽbvìÀ$~L€´wøÂ(æ¹·Ï÷©ü¸€�øð½;3wèó<&zMåÏ ¨ËÅãŸ_üv)ÚX'yUhî-þ Pq*\ìq{ ¸OþïO¯€¿ÈLä;ßC˜3†«Ü"°%j1‘>éÞØöÊ¥nìßk�dIEND®B`‚ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/resources/run.png000066400000000000000000000036321524622605700264430ustar00rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ GÀ4äIDATXõ—Yl\WÇçÎâx�Ç“8¶ã±O=8±iìÄ „†ª´J(¡EƒJyà�ª”ªbky(yâ!¡ŠEA*ª” ¡ÒBPTÒ¦±³8vLíIœÄÛ3^gõ,w;<Üqì¬M�4:££;÷ÿûþßw¾sÆÆÿà„-Ýõ¬nñL±ù™FÊR”ÕB1›­ùA Û’Õú|÷—Oðù§ÛHy¢œ;>IîH/sN|y€ÒèØÓÌší’µ[½4u¸Q|’ø¥Æ8ÃÈ' ðÈÞ0�µe¤3Ü5°þÑjZ}.•É 6<[ÉT¬ÙOÀÿ�©)ØuºfâkPX·£†úV/“‘4ÓÃEÚ¿æ£`+Þw},à¡É(Ï�÷þerõ�ïô ñGá¤�2öï:&¶~¹ ‹�PW€Ú°‡èùñSõ›]$Æ4ŠÑ{s@Übý‰WÞyöíšµ>þ|à¯zÏáéß«~¸ÿòSª@Á0tò¤Qm9Ìœ�¡£ó ¾7Ε¿åY»»œÄx€äi¨ì°æ{MA¨cOó7KE¨4u¸;Ÿ|ñÍWÏéÿüùpß¾ÿ)͉‡îA5Ьjwиq%U!ƒIf?0ð‡�d¯&ï¯B�ì wßP„rý£ÕΆVßc†K}îÍ÷'w~«íÜ‚ša.#27ÀœŒ±ªµœu]MTË™�H’½"©ÝiñJR¾ àßbÍwP*Bi×]B×LékPĺ5ÞúVïîèë>üÓ�¦+vÍ]À„Þ}ˆ[3$�8µ*hiá^ã`*’"Ñ ®:A~òfñÛtí wW5;)U¤DØ)æ¹)‹Âßb7C]�@mسwø�üÞ³¯iÃ[~Ë 0t˜O§HÚcÛª m â˜,$ó´|i¦;Ϩ¼ €§ÃÝþf'jQCšÓ”Há.©W(¦0dE³­Ÿ«­®jr}{äH~wÿ/ôHÝW¹*Mz ¥Ø6/¥7CÇg;)dUο£ýñz¦âiÌ„%d¿UqH ¦†H�R”Ö ¤”‹NµRfä¼X·»ÒhèªØ<²5y¼ÿ7ÑbÿV¿×u°l ÆÛ€usìàiâà $0t<мAg)€ÐÀ4-qÓ°`déWÒPP„�œšó…��ؤ‚¬~¬N<¹uý¶ËÛSýC¯�ùðØÅ}Ÿa$}ü[ú21r³ÜR»À@6S!«'Ï]dº0ŽªK+�F&¥MLR·«A;7~åÒÆ™=CïEò•DSw· �€F¨sO¸»¢ÁI± �©›t0_˜S牤Dª�Æ4˜`à D©•¤=&ƒmÕJhc°Ã0`ºóî…Qyl¹xoÊõÀ°£˜N²ZŠ«Ùÿ2“�a˜Ö#RZiZL�”Vz¿UL]d¥Ïmnn›óÌ‘¡—ÑãÚGoPjΊ´“)fžëc"7VÊ= º ¦¼žšEa³ôLAoy™ �£nåØÁÓSñáį%¼{g„UˆÓ¹ FâCÌ¥3ØÅ "0—Fl˜€Í¡ª0ʬK¹ztªxùÜÅ_¥Ï°Ÿ[ÜËØ!‘OP,:h%ÑŨ¯Eo‚T 6Á£Y>P¢'¦Ô‘S‘×gx˜¿ÝY°| RÁÔlhšvÍêE‹#×  Ôù‚x +EìÝ„8söìÁ™ÿÈ—€Q°¶_¢ç¦­(ÖÔUеRAš×{�¦#¥DÔj�Êb­múd‚ §.š:¡ý ¾ñu·¿s#Ò-€E4„€€; j�Ìô¦m§û{&N_$ËûþN”D/æÝ^H–L–Íš †å€,¨ˆÕþ*£ÆÑhKå9{j¸o¬g᜸)â{¿õY ,TÕ  ‚ÏåU6“�¶Áó#C—O¦BœÃ•�(É{½3€†.YáðÊ` NèQAäíèÕ+g/¹|"Þ‡!ÓGü†¾·ÄV¥Åè[ñ¹xáÒ‘DøåÛ)Ħç«�6=_…gÃÇ»–/)]MeC‡ë�Äxîdæ<û¾1Œ!%4¨òz¨.k$z\Ð÷�qFz“„:+éM’ÿèA”VžùC÷Î1òÙ‚Õí°¶¢fZ¾ù*\Š-Œ½_ ïïŒdiü´‡Ñ�,jäü1Y¿;€½!E± _kB¦aA`@.«_˜¢ªU²aG3þ€—©Kiæ5‚Û\„†>{?Nkµõñ*l�iÔ‚Ž©—ÌëwiZ0‰tžY=Nu»ƒõ[šq{œÌŽfHÆ ‚ÛÊÈj2y/|ý�mØ6dMÂr t32 ëБ%Óa‚Цç³Lfb<üd-�¡ ® …x$ɦ§êÉË ¹±åþ„ º|�—úIEND®B`‚ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/resources/stop.png000066400000000000000000000011021524622605700266120ustar00rootroot00000000000000‰PNG  IHDR szzôtEXtSoftwareAdobe ImageReadyqÉe<äIDATxÚäWKnÂ0|¦ uÝpSµËî8ê¦UW=,AbŨøH � ‰�DEI“دN ‰ý,ê�í|<ã™q3D„[– ܸd÷�GÆÞdõt%Ü÷Äg¯ÁöHøZ*¥ î¡eÁK±’ )°/¼Û5CRÞµ»|>Þ‚ð“x°“6c'Ïf£/á¥ÀBóAàË%ˆÕ ²ŽC#�lßç‹ðÉäÊ×ë`Íeà>—K§€ª�® ®tp§S?h˜0.WYàaüÔj ‚uk|–B~4<`ëë‹$¯‰zü»R�ßáP –$)È( l Ø�FdOMÕѰçs?¥çÈ|Ö*ðnº Ë, pô:£„�Ÿ‘tU&HË�˜Z@UC«€ X@±!µ"’TʬAãûqŸé6#Ø€‹ÛSŒ@Š4Û9‰€ * ‹{�BŸ@&£Ó‘I"!(?$…ÂE~L��fÞqé³\¾ÚÑìpTø÷§ã?¸sº˜’IEND®B`‚ctk-2026.09.02/Applications/ctkCommandLineModuleExplorer/target_libraries.cmake000066400000000000000000000006011524622605700274340ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKCommandLineModulesFrontendQtGui CTKCommandLineModulesFrontendQtWebKit CTKCommandLineModulesBackendXMLChecker CTKCommandLineModulesBackendLocalProcess CTKCommandLineModulesBackendFunctionPointer CTKWidgets ) ctk-2026.09.02/Applications/ctkDICOM/000077500000000000000000000000001524622605700166715ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOM/CMakeLists.txt000066400000000000000000000011671524622605700214360ustar00rootroot00000000000000project(ctkDICOM) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files set(KIT_SRCS ctkDICOMMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOM/Testing/000077500000000000000000000000001524622605700203065ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOM/Testing/CMakeLists.txt000066400000000000000000000000261524622605700230440ustar00rootroot00000000000000add_subdirectory(Cpp) ctk-2026.09.02/Applications/ctkDICOM/Testing/Cpp/000077500000000000000000000000001524622605700210305ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOM/Testing/Cpp/CMakeLists.txt000066400000000000000000000011231524622605700235650ustar00rootroot00000000000000set(KIT ${PROJECT_NAME}) create_test_sourcelist(Tests ${KIT}CppTests.cpp ctkDICOMTest1.cpp ) SET (TestsToRun ${Tests}) REMOVE (TestsToRun ${KIT}CppTests.cpp) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file '/target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries ${${KIT}_SOURCE_DIR}) ctk_add_executable_utf8(${KIT}CppTests ${Tests}) target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) # # Add Tests # SIMPLE_TEST(ctkDICOMTest1 $) ctk-2026.09.02/Applications/ctkDICOM/Testing/Cpp/ctkDICOMTest1.cpp000066400000000000000000000035541524622605700240210ustar00rootroot00000000000000/*========================================================================= 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 #include // STD includes #include #include int ctkDICOMTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); QString testName = arguments.takeFirst(); if (arguments.count() != 1) { std::cerr << "Usage: " << qPrintable(testName) << " " << std::endl; return EXIT_FAILURE; } QString command = arguments.at(0); std::cout << "Testing:\n" << qPrintable(command) << std::endl; QProcess process; process.start(command, /* arguments= */ QStringList()); bool res = process.waitForStarted(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " didn't start correctly" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } process.kill(); res = process.waitForFinished(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " failed to terminate" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } return res ? EXIT_SUCCESS : EXIT_FAILURE; } ctk-2026.09.02/Applications/ctkDICOM/ctkDICOMMain.cpp000066400000000000000000000044311524622605700215410ustar00rootroot00000000000000/*========================================================================= Library: CTK Copyright (c) Isomics 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 #include #include #include #include // CTK widget includes #include // ctkDICOMCore includes #include "ctkDICOMBrowser.h" #include "ctkDICOMDatabase.h" #include "ctkDICOMModel.h" // Logger #include "ctkLogger.h" // STD includes #include int main(int argc, char** argv) { QApplication app(argc, argv); app.setOrganizationName("commontk"); app.setOrganizationDomain("commontk.org"); app.setApplicationName("ctkDICOM"); // set up Qt resource files QResource::registerResource("./Resources/ctkDICOM.qrc"); QSettings settings; QString databaseDirectory; // set up the database if (argc > 1) { QString directory(argv[1]); settings.setValue("DatabaseDirectory", directory); settings.sync(); } if ( settings.value("DatabaseDirectory", "") == "" ) { databaseDirectory = QString("./ctkDICOM-Database"); std::cerr << "No DatabaseDirectory on command line or in settings. Using \"" << qPrintable(databaseDirectory) << "\".\n"; } else { databaseDirectory = settings.value("DatabaseDirectory", "").toString(); } QDir qdir(databaseDirectory); if ( !qdir.exists(databaseDirectory) ) { if ( !qdir.mkpath(databaseDirectory) ) { std::cerr << "Could not create database directory \"" << qPrintable(databaseDirectory) << "\".\n"; return EXIT_FAILURE; } } ctkDICOMAppWidget DICOMApp; DICOMApp.setDatabaseDirectory(databaseDirectory); DICOMApp.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkDICOM/target_libraries.cmake000066400000000000000000000002671524622605700232220ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMWidgets ) ctk-2026.09.02/Applications/ctkDICOM2/000077500000000000000000000000001524622605700167535ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOM2/CMakeLists.txt000066400000000000000000000011711524622605700215130ustar00rootroot00000000000000project(ctkDICOM2) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files set(KIT_SRCS ctkDICOM2Main.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOM2/Testing/000077500000000000000000000000001524622605700203705ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOM2/Testing/CMakeLists.txt000066400000000000000000000000261524622605700231260ustar00rootroot00000000000000add_subdirectory(Cpp) ctk-2026.09.02/Applications/ctkDICOM2/Testing/Cpp/000077500000000000000000000000001524622605700211125ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOM2/Testing/Cpp/CMakeLists.txt000066400000000000000000000011261524622605700236520ustar00rootroot00000000000000set(KIT ${PROJECT_NAME}) create_test_sourcelist(Tests ${KIT}CppTests.cpp ctkDICOM2Test1.cpp ) SET (TestsToRun ${Tests}) REMOVE (TestsToRun ${KIT}CppTests.cpp) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file '/target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries ${${KIT}_SOURCE_DIR}) ctk_add_executable_utf8(${KIT}CppTests ${Tests}) target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) # # Add Tests # SIMPLE_TEST(ctkDICOM2Test1 $) ctk-2026.09.02/Applications/ctkDICOM2/Testing/Cpp/ctkDICOM2Test1.cpp000066400000000000000000000035551524622605700241660ustar00rootroot00000000000000/*========================================================================= 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 #include // STD includes #include #include int ctkDICOM2Test1(int argc, char * argv []) { QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); QString testName = arguments.takeFirst(); if (arguments.count() != 1) { std::cerr << "Usage: " << qPrintable(testName) << " " << std::endl; return EXIT_FAILURE; } QString command = arguments.at(0); std::cout << "Testing:\n" << qPrintable(command) << std::endl; QProcess process; process.start(command, /* arguments= */ QStringList()); bool res = process.waitForStarted(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " didn't start correctly" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } process.kill(); res = process.waitForFinished(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " failed to terminate" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } return res ? EXIT_SUCCESS : EXIT_FAILURE; } ctk-2026.09.02/Applications/ctkDICOM2/ctkDICOM2Main.cpp000066400000000000000000000030611524622605700217030ustar00rootroot00000000000000/*========================================================================= Library: CTK Copyright (c) Isomics 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 #include #include #include #include // CTK widget includes #include // ctkDICOMCore includes #include "ctkDICOMDatabase.h" #include "ctkDICOMModel.h" // Logger #include "ctkLogger.h" // STD includes #include int main(int argc, char** argv) { QApplication app(argc, argv); app.setOrganizationName("commontk"); app.setOrganizationDomain("commontk.org"); app.setApplicationName("ctkDICOM"); // set up Qt resource files QResource::registerResource("./Resources/ctkDICOM.qrc"); ctkDICOMBrowser DICOMApp; DICOMApp.setDatabaseDirectorySettingsKey("DatabaseDirectory"); // set up the database if (argc > 1) { DICOMApp.setDatabaseDirectory(argv[1]); } DICOMApp.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkDICOM2/target_libraries.cmake000066400000000000000000000002671524622605700233040ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMWidgets ) ctk-2026.09.02/Applications/ctkDICOMDemoSCU/000077500000000000000000000000001524622605700200515ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMDemoSCU/CMakeLists.txt000066400000000000000000000012551524622605700226140ustar00rootroot00000000000000project(ctkDICOMDemoSCU) # # See CTK/CMake/ctkMacroBuildLib.cmake for details # # Source files set(KIT_SRCS ctkDICOMDemoSCUMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Plugins #add_subdirectory(Plugins) # Testing if(BUILD_TESTING) add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOMDemoSCU/Testing/000077500000000000000000000000001524622605700214665ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMDemoSCU/Testing/CMakeLists.txt000066400000000000000000000000261524622605700242240ustar00rootroot00000000000000add_subdirectory(Cpp) ctk-2026.09.02/Applications/ctkDICOMDemoSCU/Testing/Cpp/000077500000000000000000000000001524622605700222105ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMDemoSCU/Testing/Cpp/CMakeLists.txt000066400000000000000000000011501524622605700247450ustar00rootroot00000000000000set(KIT ${PROJECT_NAME}) create_test_sourcelist(Tests ${KIT}CppTests.cpp ctkDICOMDemoSCUTest1.cpp ) SET (TestsToRun ${Tests}) REMOVE (TestsToRun ${KIT}CppTests.cpp) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file '/target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries ${${KIT}_SOURCE_DIR}) ctk_add_executable_utf8(${KIT}CppTests ${Tests}) target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) # # Add Tests # SIMPLE_TEST(ctkDICOMDemoSCUTest1 $ ) ctk-2026.09.02/Applications/ctkDICOMDemoSCU/Testing/Cpp/ctkDICOMDemoSCUTest1.cpp000066400000000000000000000033751524622605700263620ustar00rootroot00000000000000/*========================================================================= 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 #include // STD includes #include #include int ctkDICOMDemoSCUTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); QString testName = arguments.takeFirst(); if (arguments.count() != 1) { std::cerr << "Usage: " << qPrintable(testName) << " " << std::endl; return EXIT_FAILURE; } QString command = arguments.at(0); QString peer("www.dicomserver.co.uk"); QString port("104"); QString aeTitle("MOVESCP"); QStringList parameters; parameters << peer << port << aeTitle; std::cout << "Testing:\n" << qPrintable(command) << " " << qPrintable(parameters.join(" ")) << std::endl; int res = QProcess::execute(command, parameters); if (res != EXIT_SUCCESS) { std::cerr << '\"' << qPrintable(command) << '\"' << " returned " << res << std::endl; return res; } return res; } ctk-2026.09.02/Applications/ctkDICOMDemoSCU/Testing/Cpp/target_libraries.cmake000066400000000000000000000004671524622605700265430ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries ) ## Query / Retrieve Testing if(CTK_APP_ctkDICOMQuery AND CTK_APP_ctkDICOMRetrieve) list(APPEND target_libraries CTKDICOMCore ) endif() ctk-2026.09.02/Applications/ctkDICOMDemoSCU/ctkDICOMDemoSCUMain.cpp000066400000000000000000000051441524622605700241030ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #include "dcmtk/config/osconfig.h" /* make sure OS specific configuration is included first */ #include "dcmtk/dcmnet/scu.h" // STD includes #include #include #include void print_usage() { std::cerr << "Usage: \n"; std::cerr << " ctkDICOMDemoSCU peer port [peerAETitle]\n"; std::cerr << " Issues ECHO request to the given host and given port.\n"; std::cerr << " Optional peerAETitle tells what application entity to address.\n"; return; } int main(int argc, char** argv) { // Check whether host and port are given if (argc < 3) { print_usage(); return 2; } OFString host(argv[1]); unsigned int port = atoi(argv[2]); OFString peerAET; if (argc > 3) { peerAET = argv[3]; } // Setup SCU DcmSCU scu; scu.setPeerHostName(host); scu.setPeerPort(port); OFString verificationSOP = UID_VerificationSOPClass; OFList ts; ts.push_back(UID_LittleEndianExplicitTransferSyntax); ts.push_back(UID_BigEndianExplicitTransferSyntax); ts.push_back(UID_LittleEndianImplicitTransferSyntax); scu.addPresentationContext(verificationSOP, ts); if (peerAET != "") { scu.setPeerAETitle(peerAET); } OFCondition result = scu.initNetwork(); if (result.bad()) { std::cerr << "Error setting up SCU: " << result.text() << "\n"; return 2; } // Negotiate association result = scu.negotiateAssociation(); if (result.bad()) { std::cerr << "Error negotiating association: " << result.text() << "\n"; return 2; } // Issue ECHO request and let scu find presentation context itself (0) result = scu.sendECHORequest(0); if (result.bad()) { std::cerr << "Error issuing ECHO request or received rejecting response: " << result.text() << "\n"; return 2; } std::cout << "Successfully sent DICOM Echo to host " << argv[1] << " on port " << argv[2] << "\n"; return 0; } ctk-2026.09.02/Applications/ctkDICOMDemoSCU/target_libraries.cmake000066400000000000000000000002641524622605700243770ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMCore ) ctk-2026.09.02/Applications/ctkDICOMHost/000077500000000000000000000000001524622605700175275ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMHost/CMakeLists.txt000066400000000000000000000013041524622605700222650ustar00rootroot00000000000000PROJECT(ctkDICOMHost) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files SET(KIT_SRCS ctkDICOMHostMain.cpp ctkDICOMHostMainLogic.cpp ) # UI files SET(KIT_UI_FORMS ctkDICOMHostMainWidget.ui ) # Resources SET(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing IF(BUILD_TESTING) ADD_SUBDIRECTORY(Testing) ENDIF(BUILD_TESTING) ctk-2026.09.02/Applications/ctkDICOMHost/Testing/000077500000000000000000000000001524622605700211445ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMHost/Testing/CMakeLists.txt000066400000000000000000000000261524622605700237020ustar00rootroot00000000000000ADD_SUBDIRECTORY(Cpp) ctk-2026.09.02/Applications/ctkDICOMHost/Testing/Cpp/000077500000000000000000000000001524622605700216665ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMHost/Testing/Cpp/CMakeLists.txt000066400000000000000000000011121524622605700244210ustar00rootroot00000000000000SET(KIT ${PROJECT_NAME}) CREATE_TEST_SOURCELIST(Tests ${KIT}CppTests.cpp ctkDICOMHostTest1.cpp ) SET (TestsToRun ${Tests}) REMOVE (TestsToRun ${KIT}CppTests.cpp) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctk_add_executable_utf8(${KIT}CppTests ${Tests}) TARGET_LINK_LIBRARIES(${KIT}CppTests ${KIT_target_libraries} ${QT_LIBRARIES}) # # Add Tests # SIMPLE_TEST( ctkDICOMHostTest1 $ ) ctk-2026.09.02/Applications/ctkDICOMHost/Testing/Cpp/ctkDICOMHostTest1.cpp000066400000000000000000000037331524622605700255140ustar00rootroot00000000000000/*========================================================================= 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 #include #include // STD includes #include #include //----------------------------------------------------------------------------- int ctkDICOMHostTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); QString testName = arguments.takeFirst(); if (arguments.count() != 1) { std::cerr << "Usage: " << qPrintable(testName) << " " << std::endl; return EXIT_FAILURE; } QString command = arguments.at(0); std::cout << "Testing:\n" << qPrintable(command) << std::endl; QProcess process; process.start(command, /* arguments= */ QStringList()); bool res = process.waitForStarted(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " didn't start correctly" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } process.kill(); res = process.waitForFinished(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " failed to terminate" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } return res ? EXIT_SUCCESS : EXIT_FAILURE; } ctk-2026.09.02/Applications/ctkDICOMHost/Testing/Cpp/target_libraries.cmake000066400000000000000000000004671524622605700262210ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # SET(target_libraries ) ## Query / Retrieve Testing if(CTK_APP_ctkDICOMQuery AND CTK_APP_ctkDICOMRetrieve) LIST(APPEND target_libraries CTKDICOMCore ) endif() ctk-2026.09.02/Applications/ctkDICOMHost/ctkDICOMHostMain.cpp000066400000000000000000000115531524622605700232400ustar00rootroot00000000000000/*========================================================================= Library: CTK Copyright (c) Isomics 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 #include #include #include #include #include #include // CTKPluginFramework includes #include #include #include #include #include // CTK widget includes #include #include // Host logic #include "ctkDICOMHostMainLogic.h" // ctkDICOMCore includes #include "ctkDICOMDatabase.h" #include "ctkDICOMModel.h" // STD includes #include // ui of this application #include "ui_ctkDICOMHostMainWidget.h" int main(int argc, char** argv) { QApplication app(argc, argv); app.setOrganizationName("commontk"); app.setOrganizationDomain("commontk.org"); app.setApplicationName("ctkDICOM"); // startup plugin framework and dah ctkPluginFrameworkFactory fwFactory; QSharedPointer framework = fwFactory.getFramework(); try { framework->init(); } catch (const ctkPluginException& exc) { qCritical() << "Failed to initialize the plug-in framework:" << exc; return EXIT_FAILURE; } #ifdef CMAKE_INTDIR QString pluginPath = CTK_PLUGIN_DIR CMAKE_INTDIR "/"; #else QString pluginPath = CTK_PLUGIN_DIR; #endif qApp->addLibraryPath(pluginPath); QStringList libFilter; libFilter << "*.dll" << "*.so" << "*.dylib"; QDirIterator dirIter(pluginPath, libFilter, QDir::Files); QStringList pluginsToInstall; pluginsToInstall << "org_commontk_dah_core." << "org_commontk_dah_host." << "org_commontk_dah_examplehost."; QList > installedPlugins; while(dirIter.hasNext()) { try { QString fileLocation = dirIter.next(); foreach(QString pluginToInstall, pluginsToInstall) { if (fileLocation.contains(pluginToInstall)) { QSharedPointer plugin = framework->getPluginContext()->installPlugin(QUrl::fromLocalFile(fileLocation)); installedPlugins << plugin; break; } } } catch (const ctkPluginException& e) { qCritical() << e.what(); } } framework->start(); foreach(QSharedPointer plugin, installedPlugins) { plugin->start(); } // end startup plugin framework and dah // set up Qt resource files QResource::registerResource("./Resources/ctkDICOM.qrc"); QSettings settings; QString databaseDirectory; // set up the database if (argc > 1) { QString directory(argv[1]); settings.setValue("DatabaseDirectory", directory); settings.sync(); } if ( settings.value("DatabaseDirectory", "") == "" ) { databaseDirectory = QString("./ctkDICOM-Database"); std::cerr << "No DatabaseDirectory on command line or in settings. Using \"" << qPrintable(databaseDirectory) << "\".\n"; } else { databaseDirectory = settings.value("DatabaseDirectory", "").toString(); } QDir qdir(databaseDirectory); if ( !qdir.exists(databaseDirectory) ) { if ( !qdir.mkpath(databaseDirectory) ) { std::cerr << "Could not create database directory \"" << qPrintable(databaseDirectory) << "\".\n"; return EXIT_FAILURE; } } QWidget *widget = new QWidget; Ui::ctkDICOMHostMainWidget ui; ui.setupUi(widget); widget->show(); ctkDICOMHostMainLogic *logic = new ctkDICOMHostMainLogic(ui.placeHolderForHostedApp, ui.placeHolderForDICOMAppWidget, ui.placeHolderForControls); logic->connect(ui.configureHostedApp,SIGNAL(clicked()), logic, SLOT(configureHostedApp())); logic->connect(ui.sendDataToHostedApp,SIGNAL(clicked()), logic, SLOT(sendDataToHostedApp())); logic->connect(logic, SIGNAL(TreeSelectionChanged(const QString &)), ui.selection, SLOT(setText(const QString &))); logic->connect(logic, SIGNAL(SelectionValid(bool)), ui.sendDataToHostedApp, SLOT(setEnabled(bool))); logic->connect(ui.cbShowControls, SIGNAL(toggled(bool)), ui.placeHolderForControls->children()[0], SLOT(setVisible(bool))); //ctkDICOMAppWidget DICOMApp(widget); ////DICOMApp.setDatabaseDirectory(databaseDirectory); ////DICOMApp.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkDICOMHost/ctkDICOMHostMainLogic.cpp000066400000000000000000000156541524622605700242240ustar00rootroot00000000000000// Qt includes #include #include #include #include #include #include // ctk includes #include "ctkDICOMHostMainLogic.h" #include "ctkHostedAppPlaceholderWidget.h" #include "ctkExampleHostControlWidget.h" #include "ctkExampleDicomHost.h" #include "ctkDICOMAppWidget.h" #include "ctkDICOMModel.h" #include "ctkDICOMDatabase.h" #include "ctkDicomAvailableDataHelper.h" ctkDICOMHostMainLogic::ctkDICOMHostMainLogic(ctkHostedAppPlaceholderWidget* placeHolder, ctkDICOMAppWidget* dicomAppWidget, QWidget* placeHolderForControls) : QObject(placeHolder), PlaceHolderForHostedApp(placeHolder), DicomAppWidget(dicomAppWidget), PlaceHolderForControls(placeHolderForControls), ValidSelection(false), SendData(false) { this->Host = new ctkExampleDicomHost(PlaceHolderForHostedApp); this->HostControls = new ctkExampleHostControlWidget(Host, PlaceHolderForControls); Data = new ctkDicomAppHosting::AvailableData; disconnect(this->Host,SIGNAL(startProgress()),this->Host,SLOT(onStartProgress())); connect(this->Host,SIGNAL(appReady()),this,SLOT(onAppReady()), Qt::QueuedConnection); connect(this->Host,SIGNAL(startProgress()),this,SLOT(publishSelectedData()), Qt::QueuedConnection); connect(this->PlaceHolderForHostedApp,SIGNAL(resized()),this,SLOT(placeHolderResized())); QTreeView * treeview = dicomAppWidget->findChild("TreeView"); QItemSelectionModel* selectionmodel = treeview->selectionModel(); connect(selectionmodel, SIGNAL(selectionChanged ( const QItemSelection &, const QItemSelection & )), this, SLOT(onTreeSelectionChanged(const QItemSelection &, const QItemSelection &))); connect(this->Host, SIGNAL(dataAvailable()), this, SLOT(onDataAvailable())); connect( qApp, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit()) ); } ctkDICOMHostMainLogic::~ctkDICOMHostMainLogic() { delete Data; } void ctkDICOMHostMainLogic::aboutToQuit() { this->Host->exitApplicationBlocking(); delete this->Host; this->Host = 0; } void ctkDICOMHostMainLogic::configureHostedApp() { //qDebug() << "load button clicked"; AppFileName = QFileDialog::getOpenFileName(PlaceHolderForHostedApp,tr("Choose hosted application"),QApplication::applicationDirPath()); HostControls->setAppFileName(AppFileName); emit SelectionValid(((this->Host) && (this->HostControls->validAppFileName()) && (ValidSelection))); } void ctkDICOMHostMainLogic::sendDataToHostedApp() { if ((this->Host) && (this->HostControls->validAppFileName()) && (ValidSelection)) { *Data = ctkDicomAppHosting::AvailableData(); // empty AvailableData structure (at least not with the same id...) foreach (const QString &str, SelectedFiles) { if (str.isEmpty()) continue; qDebug() << str; ctkDicomAvailableDataHelper::addToAvailableData(*Data, Host->objectLocatorCache(), str); } SendData = true; if(this->Host->getApplicationState() == ctkDicomAppHosting::EXIT) { this->HostControls->StartApplication(this->AppFileName); } if(this->Host->getApplicationState() == ctkDicomAppHosting::IDLE) { bool reply = this->Host->getDicomAppService()->setState(ctkDicomAppHosting::INPROGRESS); qDebug() << " setState(INPROGRESS) returned: " << reply; } if(this->Host->getApplicationState() == ctkDicomAppHosting::INPROGRESS) { publishSelectedData(); } } } void ctkDICOMHostMainLogic::onAppReady() { emit SelectionValid(ValidSelection); if(SendData) { bool reply = this->Host->getDicomAppService()->setState(ctkDicomAppHosting::INPROGRESS); qDebug() << " setState(INPROGRESS) returned: " << reply; QRect rect (this->PlaceHolderForHostedApp->getAbsolutePosition()); this->Host->getDicomAppService()->bringToFront(rect); } } void ctkDICOMHostMainLogic::onTreeSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected) { Q_UNUSED(deselected); ValidSelection=false; if(selected.indexes().count() > 0) { foreach (const QModelIndex &index, selected.indexes()) { ctkDICOMModel* model = const_cast(qobject_cast(index.model())); QModelIndex index0 = index.sibling(index.row(), 0); if(model && (model->data(index0,ctkDICOMModel::TypeRole) == static_cast(ctkDICOMModel::SeriesType))) { QString s = tr("Series selected: "); QString seriesUID = model->data(index0,ctkDICOMModel::UIDRole).toString(); s.append(seriesUID); SelectedFiles = DicomAppWidget->database()->filesForSeries(seriesUID); emit TreeSelectionChanged(s); ValidSelection=true; } } } if (ValidSelection==false) emit TreeSelectionChanged(tr("no series selected")); emit SelectionValid(((this->Host) && (this->HostControls->validAppFileName()) && (ValidSelection))); } //---------------------------------------------------------------------------- void ctkDICOMHostMainLogic::publishSelectedData() { if(SendData) { qDebug()<<"send dataDescriptors"; bool success = Host->publishData(*Data, true); if(!success) { qCritical() << "Failed to publish data"; } qDebug() << " notifyDataAvailable returned: " << success; SendData=false; QRect rect (this->PlaceHolderForHostedApp->getAbsolutePosition()); this->Host->getDicomAppService()->bringToFront(rect); } } //---------------------------------------------------------------------------- void ctkDICOMHostMainLogic::placeHolderResized() { ///the following does not work (yet) //if((this->Host) && (this->Host->getApplicationState() != ctkDicomAppHosting::EXIT)) //{ // QRect rect (this->PlaceHolderForHostedApp->getAbsolutePosition()); // this->Host->getDicomAppService()->bringToFront(rect); //} } //---------------------------------------------------------------------------- void ctkDICOMHostMainLogic::onDataAvailable() { const ctkDicomAppHosting::AvailableData& data = this->Host->getIncomingAvailableData(); QList uuidlist = ctkDicomAvailableDataHelper::getAllUuids(data); if(uuidlist.count()==0) return; QString transfersyntax("1.2.840.10008.1.2.1"); QList transfersyntaxlist; transfersyntaxlist.append(transfersyntax); QList locators; locators = this->Host->getOtherSideExchangeService()->getData(uuidlist, transfersyntaxlist, false); qDebug() << "got locators! " << QString().setNum(locators.count()); QString s; s=s+" loc.count:"+QString().setNum(locators.count()); if(locators.count()>0) { s=s+" URI: "+locators.begin()->URI +" locatorUUID: "+locators.begin()->locator+" sourceUUID: "+locators.begin()->source; qDebug() << "URI: " << locators.begin()->URI; QString filename = locators.begin()->URI; if(filename.startsWith("file:/",Qt::CaseInsensitive)) filename=filename.remove(0,8); qDebug()< #include #include "ctkDicomAppHostingTypes.h" class ctkHostedAppPlaceholderWidget; class ctkExampleDicomHost; class ctkExampleHostControlWidget; class ctkDICOMAppWidget; class QModelIndex; class QItemSelection; class ctkDICOMHostMainLogic : public QObject { Q_OBJECT public: ctkDICOMHostMainLogic(ctkHostedAppPlaceholderWidget*, ctkDICOMAppWidget*, QWidget* placeHolderForControls); virtual ~ctkDICOMHostMainLogic(); public slots: void configureHostedApp(); void sendDataToHostedApp(); protected slots: void onTreeSelectionChanged(const QItemSelection & selected, const QItemSelection & deselected); void publishSelectedData(); void onAppReady(); void placeHolderResized(); void onDataAvailable(); void aboutToQuit(); signals: void TreeSelectionChanged(const QString &); void SelectionValid(bool); protected: ctkExampleDicomHost* Host; ctkExampleHostControlWidget* HostControls; ctkHostedAppPlaceholderWidget* PlaceHolderForHostedApp; ctkDICOMAppWidget* DicomAppWidget; QWidget* PlaceHolderForControls; ctkDicomAppHosting::AvailableData* Data; QString AppFileName; bool ValidSelection; QStringList SelectedFiles; bool SendData; }; #endif ctk-2026.09.02/Applications/ctkDICOMHost/ctkDICOMHostMainWidget.ui000066400000000000000000000065331524622605700242410ustar00rootroot00000000000000 ctkDICOMHostMainWidget 0 0 887 359 DICOM Hosts 0 0 300 300 QFrame::StyledPanel QFrame::Raised QFrame::StyledPanel QFrame::Raised Show extended controls Qt::Vertical 20 299 Configure Hosted App false Send Data to Hosted App nothing selected ctkDICOMAppWidget QWidget
ctkDICOMAppWidget.h
1
ctkHostedAppPlaceholderWidget QFrame
ctkHostedAppPlaceholderWidget.h
1
ctk-2026.09.02/Applications/ctkDICOMHost/target_libraries.cmake000066400000000000000000000003261524622605700240540ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # SET(target_libraries org_commontk_dah_examplehost CTKDICOMWidgets ) ctk-2026.09.02/Applications/ctkDICOMIndexer/000077500000000000000000000000001524622605700202105ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMIndexer/CMakeLists.txt000066400000000000000000000012051524622605700227460ustar00rootroot00000000000000project(ctkDICOMIndexer) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files set(KIT_SRCS ctkDICOMIndexerMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOMIndexer/Testing/000077500000000000000000000000001524622605700216255ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMIndexer/Testing/CMakeLists.txt000066400000000000000000000000261524622605700243630ustar00rootroot00000000000000add_subdirectory(Cpp) ctk-2026.09.02/Applications/ctkDICOMIndexer/Testing/Cpp/000077500000000000000000000000001524622605700223475ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMIndexer/Testing/Cpp/CMakeLists.txt000066400000000000000000000011571524622605700251130ustar00rootroot00000000000000set(KIT ${PROJECT_NAME}) create_test_sourcelist(Tests ${KIT}CppTests.cpp ctkDICOMIndexerAppTest1.cpp ) SET (TestsToRun ${Tests}) REMOVE (TestsToRun ${KIT}CppTests.cpp) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file '/target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries ${${KIT}_SOURCE_DIR}) ctk_add_executable_utf8(${KIT}CppTests ${Tests}) target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) # # Add Tests # SIMPLE_TEST( ctkDICOMIndexerAppTest1 $ ) ctk-2026.09.02/Applications/ctkDICOMIndexer/Testing/Cpp/ctkDICOMIndexerAppTest1.cpp000066400000000000000000000044551524622605700273210ustar00rootroot00000000000000/*========================================================================= 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 #include // STD includes #include #include int ctkDICOMIndexerAppTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); QStringList arguments = app.arguments(); QString testName = arguments.takeFirst(); QString database("test.db"); if (arguments.count() != 1) { std::cerr << "Usage: " << qPrintable(testName) << " " << std::endl; return EXIT_FAILURE; } QString command = arguments.at(0); QStringList parameters; parameters << "--init" << database; std::cout << "Testing:\n" << qPrintable(command) << " " << qPrintable(parameters.join(" ")) << std::endl; int res = QProcess::execute(command, parameters); if (res != EXIT_SUCCESS) { std::cerr << '\"' << qPrintable(command + " " + parameters.join(" ")) << '\"' << " returned " << res << std::endl; return res; } parameters.clear(); parameters << "--add" << database << "."; res = QProcess::execute(command, parameters); if (res != EXIT_SUCCESS) { std::cerr << '\"' << qPrintable(command + " " + parameters.join(" ")) << '\"' << " returned " << res << std::endl; return res; } parameters.clear(); parameters << "--cleanup" << database; res = QProcess::execute(command, parameters); if (res != EXIT_SUCCESS) { std::cerr << '\"' << qPrintable(command + " " + parameters.join(" ")) << '\"' << " returned " << res << std::endl; return res; } return res; } ctk-2026.09.02/Applications/ctkDICOMIndexer/ctkDICOMIndexerMain.cpp000066400000000000000000000053431524622605700244020ustar00rootroot00000000000000/*========================================================================= 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 #include // CTK includes #include #include // STD includes #include #include #include void print_usage() { std::cerr << "Usage:\n"; std::cerr << " 1. ctkDICOMIndexer --add [destDir]\n"; std::cerr << " Adds (or refreshes) sourceDir to the index of the database.\n"; std::cerr << " Creates the database if it is not valid..\n"; std::cerr << " If destDir is provided, images are copied there after import.\n"; std::cerr << " 2. ctkDICOMIndexer --init [sqlScript]\n"; std::cerr << " Reinitialize the database. Uses default schema or the provided sqlScript file.\n"; std::cerr << " 3. ctkDICOMIndexer --cleanup \n"; std::cerr << " Remove non-existent files from the database.\n"; return; } /** * */ int main(int argc, char** argv) { if (argc < 3) { print_usage(); return EXIT_FAILURE; } QCoreApplication app(argc, argv); QTextStream out(stdout); ctkDICOMDatabase myCTK; ctkDICOMIndexer idx; idx.setDatabase(&myCTK); try { if (std::string("--add") == argv[1]) { { myCTK.openDatabase( argv[2] ); if (argc > 4) { idx.addDirectory(argv[3],argv[4]); } else { idx.addDirectory(argv[3]); } } } else if (std::string("--init") == argv[1]) { myCTK.openDatabase( argv[2] ); if (argc > 2) { myCTK.initializeDatabase(argv[2]); } else { myCTK.initializeDatabase(); } } else if (std::string("--cleanup") == argv[1]) { // TODO } else { print_usage(); return EXIT_FAILURE; } } catch (const std::exception& e) { Q_UNUSED(e); std::cerr << "Database error:" << qPrintable(myCTK.lastError()); myCTK.closeDatabase(); return EXIT_FAILURE; } return EXIT_SUCCESS; } ctk-2026.09.02/Applications/ctkDICOMIndexer/target_libraries.cmake000066400000000000000000000002641524622605700245360ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMCore ) ctk-2026.09.02/Applications/ctkDICOMObjectViewer/000077500000000000000000000000001524622605700212025ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMObjectViewer/CMakeLists.txt000066400000000000000000000012001524622605700237330ustar00rootroot00000000000000project(ctkDICOMObjectViewer) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkDICOMObjectViewerMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOMObjectViewer/ctkDICOMObjectViewerMain.cpp000066400000000000000000000031611524622605700263620ustar00rootroot00000000000000/*========================================================================== Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. ==========================================================================*/ // STD includes #include "iostream" // CTK Widgets #include "ctkDICOMItemView.h" // DCMTK includes #include // Qt includes #include #include #include int main(int argc, char** argv) { QApplication app(argc, argv); qApp->setOrganizationName("CTK"); qApp->setOrganizationDomain("commontk.org"); qApp->setApplicationName("ctkDICOMObjectViewer"); QString s; if( argc > 1 ) { s = argv[1]; } else { s = QFileDialog::getOpenFileName( 0, "Choose an image file", ".", "DCM (*)" ); if( s.size() == 0 ) { return EXIT_SUCCESS; } } DicomImage dcmImage( s.toStdString().c_str() ); ctkDICOMItemView imageView; imageView.addImage( dcmImage ); imageView.show(); imageView.raise(); return app.exec(); } ctk-2026.09.02/Applications/ctkDICOMObjectViewer/target_libraries.cmake000066400000000000000000000002671524622605700255330ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMWidgets ) ctk-2026.09.02/Applications/ctkDICOMQuery/000077500000000000000000000000001524622605700177175ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMQuery/CMakeLists.txt000066400000000000000000000012021524622605700224520ustar00rootroot00000000000000project(ctkDICOMQuery) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files set(KIT_SRCS ctkDICOMQueryMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) #add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOMQuery/ctkDICOMQueryMain.cpp000066400000000000000000000054071524622605700236210ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ /* Notes: * * This program is a test driver for the DcmScu class and puts the results * in an sqlite database. This command will query a public dicom server: * * ../CTK-build/bin/ctkDICOMQuery test.db FINDSCU MI2B2 mi2b2.slicer.org 11112 * or this one: * ../CTK-build/bin/ctkDICOMQuery test.db FINDSCU DICOMSERVER dicomserver.co.uk 104 * * you can get a similar * functionality with this command line: * * findscu --verbose -aec MI2B2 -P -k "0010,0010=F*" mi2b2.slicer.org 11112 patqry.dcm | grep Patients * */ // Qt includes #include #include // CTK includes #include #include #include "ctkLogger.h" // DCMTK includes #include "dcmtk/oflog/oflog.h" // STD includes #include #include #include void print_usage() { std::cerr << "Usage:\n"; std::cerr << " ctkDICOMQuery database callingAETitle calledAETitle host port\n"; return; } /** * */ int main(int argc, char** argv) { ctkLogger logger ( "org.commontk.core.Logger" ); if (argc < 5) { print_usage(); return EXIT_FAILURE; } QCoreApplication app(argc, argv); QTextStream out(stdout); ctkDICOMDatabase myCTK; logger.debug ( "Opening database " + QString ( argv[1] ) ); myCTK.openDatabase ( argv[1] ); logger.debug ( "Last error: " + myCTK.lastError() ); if ( myCTK.database().isOpen() ) { logger.debug ( "Database is open" ); } else { logger.debug ( "Database is not open" ); } ctkDICOMQuery query; query.setCallingAETitle ( QString ( argv[2] ) ); query.setCalledAETitle ( QString ( argv[3] ) ); query.setHost ( QString ( argv[4] ) ); int port; bool ok; port = QString ( argv[5] ).toInt ( &ok ); if ( !ok ) { std::cerr << "Could not convert " << argv[5] << " to an integer" << std::endl; print_usage(); return EXIT_FAILURE; } query.setPort ( port ); try { query.query ( myCTK ); } catch (const std::exception& e) { Q_UNUSED(e); return EXIT_FAILURE; } return EXIT_SUCCESS; } ctk-2026.09.02/Applications/ctkDICOMQuery/target_libraries.cmake000066400000000000000000000002641524622605700242450ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMCore ) ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/000077500000000000000000000000001524622605700214255ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/CMakeLists.txt000066400000000000000000000012221524622605700241620ustar00rootroot00000000000000project(ctkDICOMQueryRetrieve) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files set(KIT_SRCS ctkDICOMQueryRetrieveMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) #add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/Testing/000077500000000000000000000000001524622605700230425ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/Testing/CMakeLists.txt000066400000000000000000000000261524622605700256000ustar00rootroot00000000000000add_subdirectory(Cpp) ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/Testing/Cpp/000077500000000000000000000000001524622605700235645ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/Testing/Cpp/CMakeLists.txt000066400000000000000000000010131524622605700263170ustar00rootroot00000000000000set(KIT ${PROJECT_NAME}) create_test_sourcelist(Tests ${KIT}CppTests.cpp ) SET (TestsToRun ${Tests}) REMOVE (TestsToRun ${KIT}CppTests.cpp) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file '/target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries ${${KIT}_SOURCE_DIR}) ctk_add_executable_utf8(${KIT}CppTests ${Tests}) target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) # # Add Tests # ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/ctkDICOMQueryRetrieveMain.cpp000066400000000000000000000051011524622605700270240ustar00rootroot00000000000000/*========================================================================= Library: CTK Copyright (c) Isomics 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 #include #include #include // CTK Core #include #include #include // CTK widget includes #include // Logger #include "ctkLogger.h" #include "dcmtk/oflog/oflog.h" // STD includes #include int main(int argc, char** argv) { // Set the DCMTK log level to debug ctk::setDICOMLogLevel(ctkErrorLogLevel::Debug); QApplication app(argc, argv); app.setOrganizationName("commontk"); app.setOrganizationDomain("commontk.org"); app.setApplicationName("ctkDICOMQueryRetrieve"); QSettings settings; QString databaseDirectory; // set up the database if (argc > 1) { QString directory(argv[1]); settings.setValue("DatabaseDirectory", directory); settings.sync(); } if ( settings.value("DatabaseDirectory", "") == "" ) { databaseDirectory = QString("./ctkDICOM-Database"); std::cerr << "No DatabaseDirectory on command line or in settings. Using \"" << qPrintable(databaseDirectory) << "\".\n"; } else { databaseDirectory = settings.value("DatabaseDirectory", "").toString(); } QDir qdir(databaseDirectory); if ( !qdir.exists(databaseDirectory) ) { if ( !qdir.mkpath(databaseDirectory) ) { std::cerr << "Could not create database directory \"" << qPrintable(databaseDirectory) << "\".\n"; return EXIT_FAILURE; } } QString databaseFileName = databaseDirectory + QString("/ctkDICOM.sql"); QSharedPointer dicomDatabase = QSharedPointer (new ctkDICOMDatabase); dicomDatabase->openDatabase(databaseFileName); ctkDICOMQueryRetrieveWidget queryRetrieve; queryRetrieve.setRetrieveDatabase(dicomDatabase); queryRetrieve.show(); queryRetrieve.raise(); return app.exec(); } ctk-2026.09.02/Applications/ctkDICOMQueryRetrieve/target_libraries.cmake000066400000000000000000000002671524622605700257560ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMWidgets ) ctk-2026.09.02/Applications/ctkDICOMRetrieve/000077500000000000000000000000001524622605700203775ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMRetrieve/CMakeLists.txt000066400000000000000000000012101524622605700231310ustar00rootroot00000000000000project(ctkDICOMRetrieve) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files set(KIT_SRCS ctkDICOMRetrieveMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) #add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOMRetrieve/ctkDICOMRetrieveMain.cpp000066400000000000000000000061411524622605700247550ustar00rootroot00000000000000/*========================================================================= Library: CTK Copyright (c) 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 #include // CTK includes #include #include #include #include "ctkLogger.h" // DCMTK includes #include "dcmtk/oflog/oflog.h" // STD includes #include #include #include void print_usage() { std::cerr << "Usage:\n"; std::cerr << " ctkDICOMRetrieve StudyUID OutputDirectory callingAETitle calledAETitle host calledPort moveDestinationAETitle\n"; return; } /** * */ int main(int argc, char** argv) { ctkLogger logger ( "org.commontk.dicom.DICOMRetieveApp" ); // Set the DCMTK log level to debug ctk::setDICOMLogLevel(ctkErrorLogLevel::Debug); if (argc < 8) { print_usage(); return EXIT_FAILURE; } QCoreApplication app(argc, argv); QTextStream out(stdout); QString StudyUID ( argv[1] ); QDir OutputDirectory ( argv[2] ); QString CallingAETitle ( argv[3] ); bool ok; QString CalledAETitle ( argv[4] ); QString Host ( argv[5] ); int CalledPort = QString ( argv[6] ).toInt ( &ok ); if ( !ok ) { std::cerr << "Could not convert " << argv[6] << " to an integer for the calledPoint" << std::endl; print_usage(); return EXIT_FAILURE; } QString MoveDestinationAETitle ( argv[7] ); ctkDICOMRetrieve retrieve; retrieve.setCallingAETitle ( CallingAETitle ); retrieve.setCalledAETitle ( CalledAETitle ); retrieve.setPort ( CalledPort ); retrieve.setHost ( Host ); retrieve.setMoveDestinationAETitle ( MoveDestinationAETitle ); logger.info ( "StudyUID: " + StudyUID + "\n" + "OutputDirectory: " + OutputDirectory.absolutePath() + "\n" + "CallingAETitle: " + CallingAETitle + "\n" + "CalledAEtitle: " + CalledAETitle + "\n" + "Host: " + Host + "\n" + "CalledPort: " + QString::number ( CalledPort ) + "\n" ); QSharedPointer dicomDatabase = QSharedPointer (new ctkDICOMDatabase); dicomDatabase->openDatabase( OutputDirectory.absoluteFilePath(QString("ctkDICOM.sql")) ); retrieve.setDatabase( dicomDatabase ); logger.info ( "Starting to retrieve" ); try { retrieve.moveStudy ( StudyUID ); } catch (const std::exception& e) { Q_UNUSED(e); logger.error ( "Retrieve failed" ); return EXIT_FAILURE; } logger.info ( "Retrieve success" ); return EXIT_SUCCESS; } ctk-2026.09.02/Applications/ctkDICOMRetrieve/target_libraries.cmake000066400000000000000000000002641524622605700247250ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMCore ) ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/000077500000000000000000000000001524622605700214215ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/CMakeLists.txt000066400000000000000000000012211524622605700241550ustar00rootroot00000000000000project(ctkDICOMVisualBrowser) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # # Source files set(KIT_SRCS ctkDICOMVisualBrowserMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/Testing/000077500000000000000000000000001524622605700230365ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/Testing/CMakeLists.txt000066400000000000000000000000261524622605700255740ustar00rootroot00000000000000add_subdirectory(Cpp) ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/Testing/Cpp/000077500000000000000000000000001524622605700235605ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/Testing/Cpp/CMakeLists.txt000066400000000000000000000011721524622605700263210ustar00rootroot00000000000000set(KIT ${PROJECT_NAME}) create_test_sourcelist(Tests ${KIT}CppTests.cpp ctkDICOMVisualBrowserTest1.cpp ) SET (TestsToRun ${Tests}) REMOVE (TestsToRun ${KIT}CppTests.cpp) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file '/target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries ${${KIT}_SOURCE_DIR}) ctk_add_executable_utf8(${KIT}CppTests ${Tests}) target_link_libraries(${KIT}CppTests ${KIT_target_libraries}) # # Add Tests # SIMPLE_TEST(ctkDICOMVisualBrowserTest1 $) ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/Testing/Cpp/ctkDICOMVisualBrowserTest1.cpp000066400000000000000000000034161524622605700312760ustar00rootroot00000000000000/*========================================================================= 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 #include // STD includes #include #include int ctkDICOMVisualBrowserTest1(int argc, char * argv []) { QCoreApplication app(argc, argv); if (app.arguments().count() != 2) { std::cerr << "Line " << __LINE__ << " - Failed to run " << argv[0] << "\n" << "Usage:\n" << " " << argv[0] << " /path/to/ctkDICOM"; return EXIT_FAILURE; } QString command = app.arguments().at(1); QProcess process; process.start(command, /* arguments= */ QStringList()); bool res = process.waitForStarted(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " didn't start correctly" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } process.kill(); res = process.waitForFinished(); if (!res) { std::cerr << '\"' << qPrintable(command) << '\"' << " failed to terminate" << std::endl; return res ? EXIT_SUCCESS : EXIT_FAILURE; } return res ? EXIT_SUCCESS : EXIT_FAILURE; } ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/ctkDICOMVisualBrowserMain.cpp000066400000000000000000000071361524622605700270260ustar00rootroot00000000000000/*========================================================================= Library: CTK Copyright (c) Isomics 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 #include #include #include #include #include #include #include // CTK widget includes #include #include #include // STD includes #include int main(int argc, char** argv) { QApplication app(argc, argv); app.setOrganizationName("commontk"); app.setOrganizationDomain("commontk.org"); app.setApplicationName("ctkDICOM"); QSettings settings; QString databaseDirectory; // set up the database if (argc > 1) { QString directory(argv[1]); settings.setValue("DatabaseDirectory", directory); settings.sync(); } if (settings.value("DatabaseDirectory", "") == "") { databaseDirectory = QString("./ctkDICOM-Database"); std::cerr << "No DatabaseDirectory on command line or in settings. Using \"" << qPrintable(databaseDirectory) << "\".\n"; } else { databaseDirectory = settings.value("DatabaseDirectory", "").toString(); } QDir qdir(databaseDirectory); if (!qdir.exists(databaseDirectory)) { if (!qdir.mkpath(databaseDirectory)) { std::cerr << "Could not create database directory \"" << qPrintable(databaseDirectory) << "\".\n"; return EXIT_FAILURE; } } // set up Qt resource files QResource::registerResource("./Resources/ctkDICOM.qrc"); QWidget mainWidget; mainWidget.setObjectName(QString::fromUtf8("MainWidget")); mainWidget.setWindowTitle(QString::fromUtf8("DICOM Visual Browser")); mainWidget.resize(1600, 1200); QVBoxLayout mainLayout; mainLayout.setObjectName(QString::fromUtf8("mainLayout")); mainLayout.setContentsMargins(1, 1, 1, 1); QHBoxLayout topLayout; topLayout.setObjectName(QString::fromUtf8("topLayout")); topLayout.setContentsMargins(1, 1, 1, 1); QLabel databaseNameLabel; databaseNameLabel.setObjectName(QString::fromUtf8("DatabaseNameLabel")); databaseNameLabel.setMaximumSize(QSize(100, 30)); topLayout.addWidget(&databaseNameLabel); ctkDirectoryButton directoryButton; directoryButton.setObjectName(QString::fromUtf8("DirectoryButton")); directoryButton.setMinimumSize(QSize(200, 30)); directoryButton.setDirectory(databaseDirectory); topLayout.addWidget(&directoryButton); mainLayout.addLayout(&topLayout); ctkDICOMVisualBrowserWidget DICOMVisualBrowser; DICOMVisualBrowser.setObjectName(QString::fromUtf8("DICOMVisualBrowser")); DICOMVisualBrowser.setDatabaseDirectorySettingsKey("DatabaseDirectory"); DICOMVisualBrowser.setDatabaseDirectory(databaseDirectory); QObject::connect(&directoryButton, SIGNAL(directoryChanged(QString)), &DICOMVisualBrowser, SLOT(setDatabaseDirectory(QString))); mainLayout.addWidget(&DICOMVisualBrowser); mainWidget.setLayout(&mainLayout); mainWidget.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkDICOMVisualBrowser/target_libraries.cmake000066400000000000000000000002671524622605700257520ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKDICOMWidgets ) ctk-2026.09.02/Applications/ctkEventBusDemo/000077500000000000000000000000001524622605700203765ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkEventBusDemo/CMakeLists.txt000066400000000000000000000016171524622605700231430ustar00rootroot00000000000000project(ctkEventBusDemo) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkEventBusDemoMain.cpp ctkEventBusDemoMainWindow.cpp ctkEventBusDemoMainWindow.h ) # UI files set(KIT_UI_FORMS ctkEventBusDemoMainWindow.ui ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) # Fix this after having discussed include dependencies with Jc foreach(_dep ${${PROJECT_NAME}_DEPENDENCIES}) include_directories(${${_dep}_SOURCE_DIR} ${${_dep}_BINARY_DIR}) endforeach() ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkEventBusDemo/ctkEventBusDemoMain.cpp000066400000000000000000000062631524622605700247600ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) 2010 BioComputing Competence Centre - Super Computing Solutions 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 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. =============================================================================*/ #include #include #include #include #include #include #include "ctkEventAdminBus.h" #include #include #include #include #include #include #include "ctkEventBusDemoMainWindow.h" int main(int argv, char** argc) { QApplication app(argv, argc); qDebug() << "################################################################"; qApp->setOrganizationName("CTK"); qApp->setOrganizationDomain("commontk.org"); qApp->setApplicationName("ctkEventBusDemoApp"); qDebug() << "################################################################"; // setup the plugin framework ctkPluginFrameworkFactory fwFactory; QSharedPointer framework = fwFactory.getFramework(); try { framework->init(); } catch (const ctkPluginException& exc) { qCritical() << "Failed to initialize the plug-in framework:" << exc; exit(2); } #ifdef CMAKE_INTDIR QString pluginPath = CTK_PLUGIN_DIR CMAKE_INTDIR "/"; #else QString pluginPath = CTK_PLUGIN_DIR; #endif qApp->addLibraryPath(pluginPath); QStringList libFilter; libFilter << "*.dll" << "*.so" << "*.dylib"; QDirIterator dirIter(pluginPath, libFilter, QDir::Files); QStringList pluginsToInstall; pluginsToInstall << "org_commontk_eventbus"; qDebug() << pluginPath; QList > installedPlugins; while(dirIter.hasNext()) { try { QString fileLocation = dirIter.next(); foreach(QString pluginToInstall, pluginsToInstall) { if (fileLocation.contains(pluginToInstall)) { QSharedPointer plugin = framework->getPluginContext()->installPlugin(QUrl::fromLocalFile(fileLocation)); installedPlugins << plugin; break; } } } catch (const ctkPluginException& e) { qCritical() << e.what(); } } framework->start(); foreach(QSharedPointer plugin, installedPlugins) { plugin->start(ctkPlugin::START_TRANSIENT); } ctkServiceReference ebr = framework->getPluginContext()->getServiceReference("ctkEventAdminBus"); ctkEventAdminBus *eb = framework->getPluginContext()->getService(ebr); ctkEventBusDemoMainWindow win(eb); win.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkEventBusDemo/ctkEventBusDemoMainWindow.cpp000066400000000000000000000061421524622605700261440ustar00rootroot00000000000000#include "ctkEventBusDemoMainWindow.h" #include "ui_ctkEventBusDemoMainWindow.h" #include "ctkEventAdminBus.h" ctkEventBusDemoMainWindow::ctkEventBusDemoMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::ctkEventBusDemoMainWindow) { ui->setupUi(this); } ctkEventBusDemoMainWindow::ctkEventBusDemoMainWindow(ctkEventAdminBus *bus, QWidget *parent) : QMainWindow(parent), ui(new Ui::ctkEventBusDemoMainWindow), m_EventBus(bus) { ui->setupUi(this); connectEvents(); } ctkEventBusDemoMainWindow::~ctkEventBusDemoMainWindow() { delete handler; delete ui; } void ctkEventBusDemoMainWindow::connectEvents() { handler = new ctkEventDemo(); connect(ui->btnSend, SIGNAL(released()), this, SLOT(sendEvent())); connect(handler, SIGNAL(updateMessageSignal(QString)), this, SLOT(updateMessage(QString))); connect(ui->connectButton, SIGNAL(released()), this, SLOT(connectClient())); qDebug() << "connectEvents"; m_EventBus->publishSignal(handler, "receiveEventSignal(QVariantList)", "ctk/remote/eventBus/comunication/receive/xmlrpc"); ctkDictionary dic; dic.insert("event.topics","ctk/remote/eventBus/comunication/receive/xmlrpc"); m_EventBus->subscribeSlot(handler, "receiveEvent(QVariantList)", dic); } void ctkEventBusDemoMainWindow::sendEvent() { QString textToDisplay = tr("Me: "); textToDisplay.append(ui->txtParameter->property("plainText").toString()); ui->textBrowser->append(textToDisplay); // event bus starts here QVariantList localEventList; localEventList.append("ctk/remote/eventBus/comunication/receive/xmlrpc"); QVariantList dataList; dataList.append("myUser"); dataList.append(ui->txtParameter->property("plainText").toString()); ctkDictionary dic; dic.insert("localEvent",localEventList); dic.insert("localData",dataList); QString value = "ctk/remote/eventBus/comunication/send/xmlrpc"; ctkEvent event(value,dic); m_EventBus->sendEvent(event); } void ctkEventBusDemoMainWindow::changeEvent(QEvent *e) { QMainWindow::changeEvent(e); switch (e->type()) { case QEvent::LanguageChange: ui->retranslateUi(this); break; default: break; } } void ctkEventBusDemoMainWindow::updateMessage(QString message) { ui->textBrowser->append(message); } void ctkEventBusDemoMainWindow::connectClient() { bool result, resultClient, resultServer; resultClient = m_EventBus->createServer("XMLRPC", ui->portLineEdit->text().toInt()); m_EventBus->startListen(); resultServer = m_EventBus->createClient("XMLRPC", ui->hostLineEdit->text(), ui->portLineEdit->text().toInt()); result = resultClient && resultServer; if(result) { ui->hostLineEdit->setEnabled(false); ui->portLineEdit->setEnabled(false); ui->connectButton->setEnabled(false); ui->txtParameter->setEnabled(true); ui->btnSend->setEnabled(true); } } void ctkEventDemo::receiveEvent(QVariantList l) { QString value; value.append(l.at(0).toString()); value.append(": "); value.append(l.at(1).toString()); emit updateMessageSignal(value); } ctk-2026.09.02/Applications/ctkEventBusDemo/ctkEventBusDemoMainWindow.h000066400000000000000000000017231524622605700256110ustar00rootroot00000000000000#ifndef CTKEVENTBUSDEMOMAINWINDOW_H #define CTKEVENTBUSDEMOMAINWINDOW_H #include #include class ctkEventAdminBus; namespace Ui { class ctkEventBusDemoMainWindow; } class ctkEventDemo : public QObject { Q_OBJECT Q_SIGNALS: void receiveEventSignal(QVariantList l); void updateMessageSignal(QString message); public Q_SLOTS: void receiveEvent(QVariantList l); }; class ctkEventBusDemoMainWindow : public QMainWindow { Q_OBJECT public: ctkEventBusDemoMainWindow(QWidget *parent = 0); ctkEventBusDemoMainWindow(ctkEventAdminBus *bus, QWidget *parent = 0); ~ctkEventBusDemoMainWindow(); public Q_SLOTS: void sendEvent(); void updateMessage(QString message); void connectClient(); protected: void changeEvent(QEvent *e); void connectEvents(); private: Ui::ctkEventBusDemoMainWindow *ui; ctkEventAdminBus *m_EventBus; ctkEventDemo *handler; }; #endif // CTKEVENTBUSDEMOMAINWINDOW_H ctk-2026.09.02/Applications/ctkEventBusDemo/ctkEventBusDemoMainWindow.ui000066400000000000000000000076221524622605700260030ustar00rootroot00000000000000 ctkEventBusDemoMainWindow 0 0 395 352 0 0 392 223 16777215 16777215 EventBus Demo 20 0 361 311 127.0.0.1 8000 Connect Chat: Qt::ScrollBarAlwaysOff false 0 40 0 30 16777215 30 false Send 0 0 395 22 0 0 TopToolBarArea false 0 20 sendEvent() ctk-2026.09.02/Applications/ctkEventBusDemo/target_libraries.cmake000066400000000000000000000003171524622605700247230ustar00rootroot00000000000000# # See CMake/ctkMacroGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKPluginFramework org_commontk_eventbus ) ctk-2026.09.02/Applications/ctkExampleHost/000077500000000000000000000000001524622605700202675ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkExampleHost/CMakeLists.txt000066400000000000000000000014161524622605700230310ustar00rootroot00000000000000project(ctkExampleHost) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkExampleHostMain.cpp ctkHostAppExampleWidget.cpp ) # UI files set(KIT_UI_FORMS ctkExampleHostMainWindow.ui ctkHostAppExampleWidget.ui ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Widgets) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkExampleHost/ctkExampleHostMain.cpp000066400000000000000000000066321524622605700245420ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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 #include #include #include #include #include #include #include #include // CTKPluginFramework includes #include #include #include #include #include // CTK includes #include #include #include // STD includes #include int main(int argc, char** argv) { QApplication app(argc, argv); qApp->setOrganizationName("CTK"); qApp->setOrganizationDomain("commontk.org"); qApp->setApplicationName("ctkExampleHost"); ctkPluginFrameworkFactory fwFactory; QSharedPointer framework = fwFactory.getFramework(); try { framework->init(); } catch (const ctkPluginException& exc) { qCritical() << "Failed to initialize the plug-in framework:" << exc; return EXIT_FAILURE; } #ifdef CMAKE_INTDIR QString pluginPath = CTK_PLUGIN_DIR CMAKE_INTDIR "/"; #else QString pluginPath = CTK_PLUGIN_DIR; #endif qApp->addLibraryPath(pluginPath); QStringList libFilter; libFilter << "*.dll" << "*.so" << "*.dylib"; QDirIterator dirIter(pluginPath, libFilter, QDir::Files); QStringList pluginsToInstall; pluginsToInstall << "org_commontk_dah_core." << "org_commontk_dah_host." << "org_commontk_dah_examplehost."; QList > installedPlugins; while(dirIter.hasNext()) { try { QString fileLocation = dirIter.next(); foreach(QString pluginToInstall, pluginsToInstall) { if (fileLocation.contains(pluginToInstall)) { QSharedPointer plugin = framework->getPluginContext()->installPlugin(QUrl::fromLocalFile(fileLocation)); installedPlugins << plugin; break; } } } catch (const ctkPluginException& e) { qCritical() << e.what(); } } framework->start(); foreach(QSharedPointer plugin, installedPlugins) { plugin->start(); } QMainWindow mainWindow; Ui::MainWindow ui; ui.setupUi(&mainWindow); if ( argc > 1 ) { ui.controlWidget->setAppFileName(argv[1]); } // mainWindow.addDockWidget(static_cast(4),new ctkHostAppExampleWidget()); // QVBoxLayout* layout = new QVBoxLayout(&mainWindow); // ctkHostAppExampleWidget* placeholder = new ctkHostAppExampleWidget(&mainWindow); // layout->addWidget(placeholder); mainWindow.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkExampleHost/ctkExampleHostMainWindow.ui000066400000000000000000000026061524622605700255620ustar00rootroot00000000000000 MainWindow 0 0 800 600 DICOM Application Host 0 0 800 19 false CTK Example Hosting Application ctkHostAppExampleWidget QWidget
ctkHostAppExampleWidget.h
1
ctk-2026.09.02/Applications/ctkExampleHost/ctkHostAppExampleWidget.cpp000066400000000000000000000060411524622605700255340ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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 #include #include #include // CTK includes #include "ctkHostAppExampleWidget.h" #include "ui_ctkHostAppExampleWidget.h" #include "ctkExampleDicomHost.h" #include "ctkDicomAppService.h" #include #include //---------------------------------------------------------------------------- ctkHostAppExampleWidget::ctkHostAppExampleWidget(QWidget *parent) : QWidget(parent), ui(new Ui::ctkHostAppExampleWidget) { qDebug() << "setup ui"; ui->setupUi(this); ui->crashLabel->setVisible(false); this->Host = new ctkExampleDicomHost(ui->placeholderFrame); this->HostControls = new ctkExampleHostControlWidget(Host, ui->placeHolderForControls); this->HostControls->setObjectName(QString::fromUtf8("exampleHostControls")); ui->verticalLayout->addWidget(HostControls); connect(&this->Host->getAppProcess(),SIGNAL(error(QProcess::ProcessError)),SLOT(appProcessError(QProcess::ProcessError))); connect(ui->placeholderFrame,SIGNAL(resized()),SLOT(placeholderResized())); } //---------------------------------------------------------------------------- ctkHostAppExampleWidget::~ctkHostAppExampleWidget() { delete this->Host; this->Host = 0; delete this->ui; this->ui = 0; } //---------------------------------------------------------------------------- void ctkHostAppExampleWidget::loadButtonClicked() { qDebug() << "load button clicked"; this->setAppFileName(QFileDialog::getOpenFileName(this,tr("Choose hosted application"),QApplication::applicationDirPath())); } //---------------------------------------------------------------------------- void ctkHostAppExampleWidget::setAppFileName(QString name) { HostControls->setAppFileName(name); } //---------------------------------------------------------------------------- void ctkHostAppExampleWidget::placeholderResized() { qDebug() << "resized"; //ui->placeholderFrame->printPosition(); } //---------------------------------------------------------------------------- void ctkHostAppExampleWidget::appProcessError(QProcess::ProcessError error) { if (error == QProcess::Crashed) { qDebug() << "crash detected"; ui->crashLabel->setVisible(true); } } ctk-2026.09.02/Applications/ctkExampleHost/ctkHostAppExampleWidget.h000066400000000000000000000031001524622605700251720ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKHOSTAPPEXAMPLEWIDGET_H #define CTKHOSTAPPEXAMPLEWIDGET_H #include #include #include class ctkExampleDicomHost; class ctkExampleHostControlWidget; namespace Ui { class ctkHostAppExampleWidget; } class ctkHostAppExampleWidget : public QWidget { Q_OBJECT public: explicit ctkHostAppExampleWidget(QWidget *parent = 0); void setAppFileName(QString name); virtual ~ctkHostAppExampleWidget(); public Q_SLOTS: void loadButtonClicked(); void placeholderResized(); void appProcessError(QProcess::ProcessError error); protected: ctkExampleDicomHost* Host; ctkExampleHostControlWidget* HostControls; QString AppFileName; private: Ui::ctkHostAppExampleWidget *ui; }; #endif // CTKHOSTWIDGET_H ctk-2026.09.02/Applications/ctkExampleHost/ctkHostAppExampleWidget.ui000066400000000000000000000077651524622605700254050ustar00rootroot00000000000000 ctkHostAppExampleWidget 0 0 583 593 0 0 Load Qt::Horizontal 0 1 QFrame::StyledPanel QFrame::Raised Qt::Horizontal 40 20 0 0 crash.jpg false Qt::Horizontal 40 20 0 1 ctkHostedAppPlaceholderWidget QFrame
ctkHostedAppPlaceholderWidget.h
1
loadButton clicked() ctkHostAppExampleWidget loadButtonClicked() 65 32 87 25 startButtonClicked() stopButtonClicked() loadButtonClicked() runButtonClicked() suspendButtonClicked() cancelButtonClicked()
ctk-2026.09.02/Applications/ctkExampleHost/target_libraries.cmake000066400000000000000000000003231524622605700246110ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries org_commontk_dah_examplehost CTKDICOMCore ) ctk-2026.09.02/Applications/ctkExampleHostedApp/000077500000000000000000000000001524622605700212415ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkExampleHostedApp/CMakeLists.txt000066400000000000000000000012001524622605700237720ustar00rootroot00000000000000project(ctkExampleHostedApp) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkExampleHostedAppMain.cpp ) # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkExampleHostedApp/ctkExampleHostedAppMain.cpp000066400000000000000000000136211524622605700264620ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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 #include #include #include #include #include #include #include // CTK includes #include #include #include #include #include #include // For testing purposes use: // --hostURL http://localhost:8081/host --applicationURL http://localhost:8082/app dicomapp //---------------------------------------------------------------------------- void print_usage() { qCritical() << "Usage:"; qCritical() << " " << QFileInfo(qApp->arguments().at(0)).fileName() << " --hostURL url1 --applicationURL url2 "; } //---------------------------------------------------------------------------- int main(int argv, char** argc) { QApplication app(argv, argc); qApp->setOrganizationName("CTK"); qApp->setOrganizationDomain("commontk.org"); qApp->setApplicationName("ctkExampleHostedApp"); ctkCommandLineParser parser; parser.setArgumentPrefix("--", "-"); // Use Unix-style argument names // Add command line argument names parser.addArgument("hostURL", "", QVariant::String, "Hosting system URL"); parser.addArgument("applicationURL", "", QVariant::String, "Hosted Application URL"); parser.addArgument("plugin", "", QVariant::String, "Plugin implementing the DicomAppInterface", "org_commontk_dah_exampleapp"); parser.addArgument("help", "h", QVariant::Bool, "Show this help text"); bool ok = false; QHash parsedArgs = parser.parseArguments(QCoreApplication::arguments(), &ok); if (!ok) { QTextStream(stderr, QIODevice::WriteOnly) << "Error parsing arguments: " << parser.errorString() << "\n"; return EXIT_FAILURE; } // Show a help message if (parsedArgs.contains("help")) { print_usage(); QTextStream(stdout, QIODevice::WriteOnly) << parser.helpText(); return EXIT_SUCCESS; } if (parsedArgs.contains("hostURL") == false) { qCritical() << "Missing parameter hostURL."; print_usage(); QTextStream(stdout, QIODevice::WriteOnly) << parser.helpText(); return EXIT_FAILURE; } if (parsedArgs.contains("applicationURL") == false) { qCritical() << "Missing parameter hostURL."; print_usage(); QTextStream(stdout, QIODevice::WriteOnly) << parser.helpText(); return EXIT_FAILURE; } QString hostURL = parsedArgs.value("hostURL").toString(); QString appURL = parsedArgs.value("applicationURL").toString(); qDebug() << "appURL is: " << appURL << " . Extracted port is: " << QUrl(appURL).port(); // Get the name of the plugin with the business logic // (thus the actual logic of the hosted app) QString pluginName = parsedArgs.value("plugin").toString(); qCritical() << " Plugin name: " << pluginName; ctkProperties fwProps; // pass further parameters the plugins if(parser.unparsedArguments().count() > 0) { QString args = parser.unparsedArguments().join(" "); fwProps.insert("dah.args", parser.unparsedArguments().join(" ")); } // setup the plugin framework fwProps.insert("dah.hostURL", hostURL); fwProps.insert("dah.appURL", appURL); fwProps.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); ctkPluginFrameworkFactory fwFactory(fwProps); QSharedPointer framework = fwFactory.getFramework(); try { framework->init(); } catch (const ctkPluginException& exc) { qCritical() << "Failed to initialize the plug-in framework:" << exc; return EXIT_FAILURE; } #ifdef CMAKE_INTDIR QString pluginPath = CTK_PLUGIN_DIR CMAKE_INTDIR "/"; #else QString pluginPath = CTK_PLUGIN_DIR; #endif qApp->addLibraryPath(pluginPath); // try to find the plugin and install all plugins available in // pluginPath containing the string "org_commontk_dah" (but do not start them) QSharedPointer appPlugin; QStringList libFilter; libFilter << "*.dll" << "*.so" << "*.dylib"; QDirIterator dirIter(pluginPath, libFilter, QDir::Files); while(dirIter.hasNext()) { try { QString fileLocation = dirIter.next(); if (fileLocation.contains("org_commontk_dah")) { QSharedPointer plugin = framework->getPluginContext()->installPlugin(QUrl::fromLocalFile(fileLocation)); if (fileLocation.contains(pluginName)) { appPlugin = plugin; } //plugin->start(ctkPlugin::START_TRANSIENT); } } catch (const ctkPluginException& e) { qCritical() << e.what(); } } // if we did not find the business logic: abort if(!appPlugin) { qCritical() << "Could not find plugin."; qCritical() << " Plugin name: " << pluginName; qCritical() << " Plugin path: " << pluginPath; return EXIT_FAILURE; } // start the plugin framework framework->start(); // start the plugin with the business logic try { appPlugin->start(); } catch (const ctkPluginException& e) { qCritical() << e; } return app.exec(); } ctk-2026.09.02/Applications/ctkExampleHostedApp/target_libraries.cmake000066400000000000000000000003141524622605700255630ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKCore org_commontk_dah_hostedapp ) ctk-2026.09.02/Applications/ctkPluginBrowser/000077500000000000000000000000001524622605700206405ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkPluginBrowser/CMakeLists.txt000066400000000000000000000016071524622605700234040ustar00rootroot00000000000000project(ctkPluginBrowser) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkPluginBrowser.cpp ctkPluginBrowserEditors.cpp ctkPluginBrowserMain.cpp ctkPluginTableModel.cpp ctkPluginResourcesTreeModel.cpp ctkQtResourcesTreeModel.cpp ) # UI files set(KIT_UI_FORMS ctkPluginBrowserMainWindow.ui ) # Resources set(KIT_resources ctkPluginBrowserResources.qrc ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) list(APPEND KIT_target_libraries Qt${CTK_QT_VERSION}::Widgets) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginBrowser.cpp000066400000000000000000000234501524622605700246540ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkPluginBrowser.h" #include "ctkPluginTableModel.h" #include "ctkPluginResourcesTreeModel.h" #include "ctkQtResourcesTreeModel.h" #include "ctkServiceReference.h" #include "ctkServiceException.h" #include "ctkPluginConstants.h" #include #include #include #include #include #include #include #include #include #include #include #include #define SETTINGS_WND_GEOM "mainwindow.geom" #define SETTINGS_WND_STATE "mainwindow.state" ctkPluginBrowser::ctkPluginBrowser(ctkPluginFramework* framework) : framework(framework) { pluginEventTypeToString[ctkPluginEvent::INSTALLED] = tr("Installed"); pluginEventTypeToString[ctkPluginEvent::LAZY_ACTIVATION] = tr("Lazy Activation"); pluginEventTypeToString[ctkPluginEvent::RESOLVED] = tr("Resolved"); pluginEventTypeToString[ctkPluginEvent::STARTED] = tr("Started"); pluginEventTypeToString[ctkPluginEvent::STARTING] = tr("Starting"); pluginEventTypeToString[ctkPluginEvent::STOPPED] = tr("Stopped"); pluginEventTypeToString[ctkPluginEvent::STOPPING] = tr("Stopping"); pluginEventTypeToString[ctkPluginEvent::UNINSTALLED] = tr("Uninstalled"); pluginEventTypeToString[ctkPluginEvent::UNRESOLVED] = tr("Unresolved"); pluginEventTypeToString[ctkPluginEvent::UPDATED] = tr("Updated"); framework->getPluginContext()->connectFrameworkListener(this, SLOT(frameworkEvent(ctkPluginFrameworkEvent))); framework->getPluginContext()->connectPluginListener(this, SLOT(pluginEvent(ctkPluginEvent))); framework->getPluginContext()->connectServiceListener(this, "serviceEvent"); QStringList pluginDirs; #ifdef CMAKE_INTDIR pluginDirs << CTK_PLUGIN_DIR CMAKE_INTDIR "/"; #else pluginDirs << CTK_PLUGIN_DIR; #endif QStringListIterator dirIt(pluginDirs); while (dirIt.hasNext()) { QApplication::addLibraryPath(dirIt.next()); } QStringList libFilter; libFilter << "*.dll" << "*.so" << "*.dylib"; QDirIterator dirIter(pluginDirs.at(0), libFilter, QDir::Files); while(dirIter.hasNext()) { try { framework->getPluginContext()->installPlugin(QUrl::fromLocalFile(dirIter.next()).toString()); //plugin->start(ctkPlugin::START_ACTIVATION_POLICY); } catch (const ctkPluginException& e) { qCritical() << e.what(); } } framework->start(); ui.setupUi(this); tabifyDockWidget(ui.qtResourcesDockWidget, ui.pluginResourcesDockWidget); editors = new ctkPluginBrowserEditors(ui.centralwidget); QAbstractItemModel* pluginTableModel = new ctkPluginTableModel(framework->getPluginContext(), this); ui.pluginsTableView->setModel(pluginTableModel); QAbstractItemModel* qtresourcesTreeModel = new ctkQtResourcesTreeModel(this); ui.qtResourcesTreeView->setModel(qtresourcesTreeModel); connect(ui.pluginsTableView, SIGNAL(clicked(QModelIndex)), this, SLOT(pluginSelected(QModelIndex))); connect(ui.pluginsTableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(pluginDoubleClicked(QModelIndex))); connect(ui.pluginResourcesTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(dbResourceDoubleClicked(QModelIndex))); connect(ui.qtResourcesTreeView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(qtResourceDoubleClicked(QModelIndex))); startPluginNowAction = new QAction(QIcon(":/pluginbrowser/images/run-now.png"), tr("Start Plugin (ignore activation policy)"), this); startPluginAction = new QAction(QIcon(":/pluginbrowser/images/run.png"), tr("Start Plugin"), this); stopPluginAction = new QAction(QIcon(":/pluginbrowser/images/stop.png"), tr("Stop Plugin"), this); connect(startPluginNowAction, SIGNAL(triggered()), this, SLOT(startPluginNow())); connect(startPluginAction, SIGNAL(triggered()), this, SLOT(startPlugin())); connect(stopPluginAction, SIGNAL(triggered()), this, SLOT(stopPlugin())); startPluginNowAction->setEnabled(false); startPluginAction->setEnabled(false); stopPluginAction->setEnabled(false); ui.pluginToolBar->addAction(startPluginNowAction); ui.pluginToolBar->addAction(startPluginAction); ui.pluginToolBar->addAction(stopPluginAction); QSettings settings; if(settings.contains(SETTINGS_WND_GEOM)) { this->restoreGeometry(settings.value(SETTINGS_WND_GEOM).toByteArray()); } if (settings.contains(SETTINGS_WND_STATE)) { this->restoreState(settings.value(SETTINGS_WND_STATE).toByteArray()); } } void ctkPluginBrowser::pluginSelected(const QModelIndex &index) { QVariant v = index.data(Qt::UserRole); QSharedPointer plugin = framework->getPluginContext()->getPlugin(v.toLongLong()); if (!plugin) return; updatePluginToolbar(plugin); QAbstractItemModel* oldModel = ui.pluginResourcesTreeView->model(); ui.pluginResourcesTreeView->setModel(new ctkPluginResourcesTreeModel(plugin, this)); if (oldModel) oldModel->deleteLater();; } void ctkPluginBrowser::updatePluginToolbar(QSharedPointer plugin) { startPluginNowAction->setEnabled(false); startPluginAction->setEnabled(false); stopPluginAction->setEnabled(false); if (!plugin) return; const ctkPlugin::States startStates = ctkPlugin::INSTALLED | ctkPlugin::RESOLVED | ctkPlugin::STOPPING; const ctkPlugin::States stopStates = ctkPlugin::STARTING | ctkPlugin::ACTIVE; if (startStates.testFlag(plugin->getState())) { startPluginNowAction->setEnabled(true); startPluginAction->setEnabled(true); } if (stopStates.testFlag(plugin->getState())) { stopPluginAction->setEnabled(true); } } void ctkPluginBrowser::pluginDoubleClicked(const QModelIndex& index) { long pluginId = index.data(Qt::UserRole).toLongLong(); QSharedPointer plugin = framework->getPluginContext()->getPlugin(pluginId); QByteArray mfContent = plugin->getResource("/META-INF/MANIFEST.MF"); QString location = QString("/") + plugin->getSymbolicName() + "/META-INF/MANIFEST.MF"; editors->openEditor(location, mfContent, location + " [cached]"); QList serviceRefs = plugin->getPluginContext()->getServiceReferences(""); QListIterator it(serviceRefs); while (it.hasNext()) { ctkServiceReference ref(it.next()); qDebug() << "Service from" << ref.getPlugin()->getSymbolicName() << ":" << ref.getPropertyKeys(); qDebug() << "Object Classes:" << ref.getProperty(ctkPluginConstants::OBJECTCLASS).toStringList(); } } void ctkPluginBrowser::qtResourceDoubleClicked(const QModelIndex& index) { Q_UNUSED(index) } void ctkPluginBrowser::dbResourceDoubleClicked(const QModelIndex& index) { QString resPath = index.data(Qt::UserRole).toString(); if (resPath.isEmpty() || resPath.endsWith('/')) return; qDebug() << "Trying to open: " << resPath; QModelIndex pluginIndex = ui.pluginsTableView->selectionModel()->selectedIndexes().first(); long pluginId = pluginIndex.data(Qt::UserRole).toLongLong(); QSharedPointer plugin = framework->getPluginContext()->getPlugin(pluginId); QByteArray resContent = plugin->getResource(resPath); QString location = QString("/") + plugin->getSymbolicName() + resPath; editors->openEditor(location, resContent, location + " [cached]"); } void ctkPluginBrowser::frameworkEvent(const ctkPluginFrameworkEvent& event) { qDebug() << "FrameworkEvent: [" << event.getPlugin()->getSymbolicName() << "]" << event.getErrorString(); } void ctkPluginBrowser::pluginEvent(const ctkPluginEvent& event) { qDebug() << "PluginEvent: [" << event.getPlugin()->getSymbolicName() << "]" << pluginEventTypeToString[event.getType()]; QSharedPointer plugin = event.getPlugin(); QModelIndexList selection = ui.pluginsTableView->selectionModel()->selectedIndexes(); if (!selection.isEmpty() && selection.first().data(Qt::UserRole).toLongLong() == plugin->getPluginId()) { updatePluginToolbar(plugin); } } void ctkPluginBrowser::serviceEvent(const ctkServiceEvent &event) { qDebug() << "ServiceEvent: [" << event.getType() << "]" << event.getServiceReference().getUsingPlugins(); } void ctkPluginBrowser::startPlugin() { startPlugin(ctkPlugin::START_TRANSIENT | ctkPlugin::START_ACTIVATION_POLICY); } void ctkPluginBrowser::startPluginNow() { startPlugin(ctkPlugin::START_TRANSIENT); } void ctkPluginBrowser::startPlugin(ctkPlugin::StartOptions options) { QModelIndex selection = ui.pluginsTableView->selectionModel()->currentIndex(); QVariant v = selection.data(Qt::UserRole); QSharedPointer plugin = framework->getPluginContext()->getPlugin(v.toLongLong()); plugin->start(options); } void ctkPluginBrowser::stopPlugin() { QModelIndex selection = ui.pluginsTableView->selectionModel()->currentIndex(); QVariant v = selection.data(Qt::UserRole); QSharedPointer plugin = framework->getPluginContext()->getPlugin(v.toLongLong()); plugin->stop(); } void ctkPluginBrowser::closeEvent(QCloseEvent *closeEvent) { QSettings settings; settings.setValue(SETTINGS_WND_GEOM, this->saveGeometry()); settings.setValue(SETTINGS_WND_STATE, this->saveState()); QMainWindow::closeEvent(closeEvent); } ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginBrowser.h000066400000000000000000000042011524622605700243120ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKPLUGINBROWSER_H #define CTKPLUGINBROWSER_H #include #include #include "ctkPluginBrowserEditors.h" #include #include #include #include class ctkPluginFramework; class ctkPluginBrowser : public QMainWindow { Q_OBJECT public: ctkPluginBrowser(ctkPluginFramework* framework); private Q_SLOTS: void pluginSelected(const QModelIndex& index); void pluginDoubleClicked(const QModelIndex& index); void qtResourceDoubleClicked(const QModelIndex& index); void dbResourceDoubleClicked(const QModelIndex& index); void frameworkEvent(const ctkPluginFrameworkEvent& event); void pluginEvent(const ctkPluginEvent& event); void serviceEvent(const ctkServiceEvent& event); void startPlugin(); void startPluginNow(); void stopPlugin(); private: void closeEvent(QCloseEvent* closeEvent); void updatePluginToolbar(QSharedPointer plugin); void startPlugin(ctkPlugin::StartOptions options); QMap pluginEventTypeToString; ctkPluginFramework* framework; Ui::ctkPluginBrowserWindow ui; ctkPluginBrowserEditors* editors; QAction* startPluginNowAction; QAction* startPluginAction; QAction* stopPluginAction; }; #endif // CTKPLUGINBROWSER_H ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginBrowserEditors.cpp000066400000000000000000000036641524622605700262130ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkPluginBrowserEditors.h" #include #include ctkPluginBrowserEditors::ctkPluginBrowserEditors(QWidget* editorArea) : QObject(editorArea), tabWidget(editorArea) { editorArea->setLayout(new QVBoxLayout()); editorArea->layout()->addWidget(&tabWidget); tabWidget.setTabsClosable(true); connect(&tabWidget, SIGNAL(tabCloseRequested(int)), SLOT(tabCloseRequested(int))); } void ctkPluginBrowserEditors::openEditor(const QString &location, const QByteArray& content, const QString& title, const QString& tooltip) { Q_UNUSED(tooltip) if (editorLocations.contains(location)) { int index = editorLocations.indexOf(location); tabWidget.setCurrentIndex(index); } else { QTextEdit* textEdit = new QTextEdit(); textEdit->setReadOnly(true); textEdit->setPlainText(QString(content)); int index = tabWidget.addTab(textEdit, title); editorLocations.insert(index, location); tabWidget.setCurrentIndex(index); } } void ctkPluginBrowserEditors::tabCloseRequested(int index) { editorLocations.removeAt(index); tabWidget.removeTab(index); } ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginBrowserEditors.h000066400000000000000000000024741524622605700256560ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKPLUGINBROWSEREDITORS_H #define CTKPLUGINBROWSEREDITORS_H #include #include class ctkPluginBrowserEditors : public QObject { Q_OBJECT public: ctkPluginBrowserEditors(QWidget* editorArea); void openEditor(const QString& location, const QByteArray& content, const QString& title, const QString& tooltip = QString()); private: QStringList editorLocations; QTabWidget tabWidget; private Q_SLOTS: void tabCloseRequested(int index); }; #endif // CTKPLUGINBROWSEREDITORS_H ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginBrowserMain.cpp000066400000000000000000000030171524622605700254560ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include #include #include #include "ctkPluginBrowser.h" #include int main(int argv, char** argc) { QApplication app(argv, argc); app.setOrganizationName("commontk"); app.setOrganizationDomain("commontk.org"); app.setApplicationName("ctkPluginBrowser"); ctkPluginFrameworkFactory fwFactory; QSharedPointer framework = fwFactory.getFramework(); try { framework->init(); } catch (const ctkPluginException& exc) { qCritical() << "Failed to initialize the plug-in framework:" << exc; exit(1); } ctkPluginBrowser browser(framework.data()); browser.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginBrowserMainWindow.ui000066400000000000000000000241251524622605700265040ustar00rootroot00000000000000 ctkPluginBrowserWindow 0 0 800 600 Plugin Browser 0 0 0 0 0 0 0 800 22 File QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Plugins 1 0 0 0 0 0 false QAbstractItemView::SingleSelection QAbstractItemView::SelectRows false true true false true true false QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Qt Resources 1 0 0 0 0 0 true QDockWidget::DockWidgetFloatable|QDockWidget::DockWidgetMovable Plugin Resources 1 0 0 0 0 0 true Services 2 0 0 0 0 0 0 0 0 0 0 2 0 0 0 0 24 24 Link services :/pluginbrowser/images/linkicon.png:/pluginbrowser/images/linkicon.png true Qt::Horizontal 40 20 Qt::Vertical Events 8 0 0 0 0 0 toolBar TopToolBarArea false Exit QAction::QuitRole ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginBrowserResources.qrc000066400000000000000000000003401524622605700265430ustar00rootroot00000000000000 images/linkicon.png images/run.png images/stop.png images/run-now.png ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginResourcesTreeModel.cpp000066400000000000000000000143561524622605700270110ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkPluginResourcesTreeModel.h" #include class ctkPluginResourceTreeNode; class ctkPluginResourceTreeItem { public: ctkPluginResourceTreeItem(const QString& path, ctkPluginResourceTreeNode* parent = 0); virtual ~ctkPluginResourceTreeItem(); virtual ctkPluginResourceTreeItem* child(int row); virtual int childCount() const; int row(); QVariant data(int role) const; ctkPluginResourceTreeNode* parent() const; protected: const QString path; ctkPluginResourceTreeNode* parentNode; }; class ctkPluginResourceTreeNode : public ctkPluginResourceTreeItem { public: ctkPluginResourceTreeNode(QSharedPointer plugin, const QString& path, ctkPluginResourceTreeNode* parent = 0); ~ctkPluginResourceTreeNode(); ctkPluginResourceTreeItem* child(int row); int childCount() const; int indexOf(ctkPluginResourceTreeItem* child) const; private: QSharedPointer plugin; QList children; }; ctkPluginResourceTreeItem::ctkPluginResourceTreeItem(const QString& path, ctkPluginResourceTreeNode* parent) : path(path), parentNode(parent) { } ctkPluginResourceTreeItem::~ctkPluginResourceTreeItem() { } ctkPluginResourceTreeItem* ctkPluginResourceTreeItem::child(int row) { Q_UNUSED(row) return 0; } int ctkPluginResourceTreeItem::childCount() const { return 0; } int ctkPluginResourceTreeItem::row() { if (parentNode) { return parentNode->indexOf(this); } return 0; } QVariant ctkPluginResourceTreeItem::data(int role) const { if (role == Qt::DisplayRole) { QString p = path; if (p.endsWith('/')) p = p.left(p.size()-1); int i = p.lastIndexOf('/'); return p.mid(i+1); } else if (role == Qt::UserRole) { if (this->parent()) { return this->parent()->data(role).toString() + path; } else { return path; } } return QVariant(); } ctkPluginResourceTreeNode* ctkPluginResourceTreeItem::parent() const { return parentNode; } ctkPluginResourceTreeNode::ctkPluginResourceTreeNode(QSharedPointer plugin, const QString& path, ctkPluginResourceTreeNode* parent) : ctkPluginResourceTreeItem(path, parent), plugin(plugin) { QStringList pathEntries = plugin->getResourceList(path); QStringListIterator it(pathEntries); while (it.hasNext()) { const QString& entry = it.next(); if (entry.endsWith('/')) { children.push_back(new ctkPluginResourceTreeNode(plugin, entry, this)); } else { children.push_back(new ctkPluginResourceTreeItem(entry, this)); } } } ctkPluginResourceTreeNode::~ctkPluginResourceTreeNode() { qDeleteAll(children); } ctkPluginResourceTreeItem* ctkPluginResourceTreeNode::child(int row) { return children.value(row); } int ctkPluginResourceTreeNode::childCount() const { return children.size(); } int ctkPluginResourceTreeNode::indexOf(ctkPluginResourceTreeItem* child) const { return children.indexOf(child); } ctkPluginResourcesTreeModel::ctkPluginResourcesTreeModel(QSharedPointer plugin, QObject* parent) : QAbstractItemModel(parent), plugin(plugin) { rootItem = new ctkPluginResourceTreeNode(plugin, "/"); } ctkPluginResourcesTreeModel::~ctkPluginResourcesTreeModel() { delete rootItem; } QVariant ctkPluginResourcesTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if ((role == Qt::DisplayRole) | (role == Qt::UserRole)) { ctkPluginResourceTreeItem* item = static_cast(index.internalPointer()); return item->data(role); } return QVariant(); } Qt::ItemFlags ctkPluginResourcesTreeModel::flags(const QModelIndex &index) const { if (!index.isValid()) { return Qt::ItemFlags(); } return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QVariant ctkPluginResourcesTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { Q_UNUSED(section) Q_UNUSED(orientation) Q_UNUSED(role) return QVariant(); } QModelIndex ctkPluginResourcesTreeModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); ctkPluginResourceTreeItem* parentItem; if (!parent.isValid()) parentItem = rootItem; else parentItem = static_cast(parent.internalPointer()); ctkPluginResourceTreeItem* childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } QModelIndex ctkPluginResourcesTreeModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); ctkPluginResourceTreeItem* childItem = static_cast(index.internalPointer()); ctkPluginResourceTreeItem* parentItem = childItem->parent(); if (parentItem == rootItem) return QModelIndex(); return createIndex(parentItem->row(), 0, parentItem); } int ctkPluginResourcesTreeModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) return 0; ctkPluginResourceTreeItem* parentItem; if (!parent.isValid()) { parentItem = rootItem; } else { parentItem = static_cast(parent.internalPointer()); } return parentItem->childCount(); } int ctkPluginResourcesTreeModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) return 1; } ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginResourcesTreeModel.h000066400000000000000000000035371524622605700264550ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKPLUGINRESOURCESTREEMODEL_H #define CTKPLUGINRESOURCESTREEMODEL_H #include #include #include class ctkPlugin; class ctkPluginResourceTreeItem; class ctkPluginResourcesTreeModel : public QAbstractItemModel { public: ctkPluginResourcesTreeModel(QSharedPointer plugin, QObject* parent = 0); ~ctkPluginResourcesTreeModel(); QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; private: QSharedPointer plugin; ctkPluginResourceTreeItem* rootItem; }; #endif // CTKPLUGINRESOURCESTREEMODEL_H ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginTableModel.cpp000066400000000000000000000065741524622605700252510ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkPluginTableModel.h" #include #include ctkPluginTableModel::ctkPluginTableModel(ctkPluginContext* pc, QObject* parent) : QAbstractTableModel(parent) { plugins = pc->getPlugins(); pc->connectPluginListener(this, SLOT(pluginChanged(ctkPluginEvent))); } QVariant ctkPluginTableModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) return QVariant(); QSharedPointer plugin = plugins.at(index.row()); if (role == Qt::DisplayRole) { int col = index.column(); if (col == 0) { return QVariant(plugin->getSymbolicName()); } else if (col == 1) { return QVariant(plugin->getVersion().toString()); } else if (col == 2) { return QVariant(getStringForState(plugin->getState())); } } else if (role == Qt::UserRole) { return QVariant::fromValue(plugin->getPluginId()); } return QVariant(); } QVariant ctkPluginTableModel::headerData(int section, Qt::Orientation orientation, int role) const { if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { if (section == 0) { return QVariant(/*no tr*/"Plugin"); } else if (section == 1) { return QVariant(/*no tr*/"Version"); } else if (section == 2) { return QVariant(/*no tr*/"State"); } } return QVariant(); } int ctkPluginTableModel::columnCount(const QModelIndex& parent) const { Q_UNUSED(parent) return 3; } int ctkPluginTableModel::rowCount(const QModelIndex& parent) const { Q_UNUSED(parent) return plugins.size(); } QString ctkPluginTableModel::getStringForState(const ctkPlugin::State state) const { static const QString uninstalled = tr("UNINSTALLED"); static const QString installed = tr("INSTALLED"); static const QString resolved = tr("RESOLVED"); static const QString starting = tr("STARTING"); static const QString stopping = tr("STOPPING"); static const QString active = tr("ACTIVE"); switch(state) { case ctkPlugin::UNINSTALLED: return uninstalled; case ctkPlugin::INSTALLED: return installed; case ctkPlugin::RESOLVED: return resolved; case ctkPlugin::STARTING: return starting; case ctkPlugin::STOPPING: return stopping; case ctkPlugin::ACTIVE: return active; default: return tr("unknown"); } } void ctkPluginTableModel::pluginChanged(const ctkPluginEvent& event) { QModelIndex topLeftIndex = createIndex(plugins.indexOf(event.getPlugin()), 0); QModelIndex bottomRightIndex = createIndex(topLeftIndex.row(), columnCount()-1); emit dataChanged(topLeftIndex, bottomRightIndex); } ctk-2026.09.02/Applications/ctkPluginBrowser/ctkPluginTableModel.h000066400000000000000000000032351524622605700247050ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKPLUGINTABLEMODEL_H #define CTKPLUGINTABLEMODEL_H #include #include #include #include class ctkPluginContext; class ctkPluginTableModel : public QAbstractTableModel { Q_OBJECT public: ctkPluginTableModel(ctkPluginContext* pc, QObject* parent = 0); QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; int columnCount(const QModelIndex& parent = QModelIndex()) const; int rowCount(const QModelIndex& parent = QModelIndex()) const; protected Q_SLOTS: void pluginChanged(const ctkPluginEvent& event); private: QString getStringForState(const ctkPlugin::State state) const; QList > plugins; }; #endif // CTKPLUGINTABLEMODEL_H ctk-2026.09.02/Applications/ctkPluginBrowser/ctkQtResourcesTreeModel.cpp000066400000000000000000000131501524622605700261260ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkQtResourcesTreeModel.h" class ctkQtResourceTreeNode; class ctkQtResourceTreeItem { public: ctkQtResourceTreeItem(const QFileInfo& fileInfo, ctkQtResourceTreeNode* parent = 0); virtual ~ctkQtResourceTreeItem(); virtual ctkQtResourceTreeItem* child(int row); virtual int childCount() const; int row(); QVariant data(int role) const; ctkQtResourceTreeNode* parent() const; protected: QFileInfo entry; ctkQtResourceTreeNode* parentNode; }; class ctkQtResourceTreeNode : public ctkQtResourceTreeItem { public: ctkQtResourceTreeNode(const QFileInfo& dirInfo, ctkQtResourceTreeNode* parent = 0); ~ctkQtResourceTreeNode(); ctkQtResourceTreeItem* child(int row); int childCount() const; int indexOf(ctkQtResourceTreeItem* child) const; private: QList children; }; ctkQtResourceTreeItem::ctkQtResourceTreeItem(const QFileInfo& fileInfo, ctkQtResourceTreeNode* parent) : entry(fileInfo), parentNode(parent) { } ctkQtResourceTreeItem::~ctkQtResourceTreeItem() { } ctkQtResourceTreeItem* ctkQtResourceTreeItem::child(int row) { Q_UNUSED(row) return 0; } int ctkQtResourceTreeItem::childCount() const { return 0; } int ctkQtResourceTreeItem::row() { if (parentNode) { return parentNode->indexOf(this); } return 0; } QVariant ctkQtResourceTreeItem::data(int role) const { if (role == Qt::DisplayRole) { if (entry.isFile()) return entry.fileName(); QString lastDir = entry.absoluteFilePath(); int i = lastDir.lastIndexOf('/'); if (i == lastDir.size()-1) return lastDir; return lastDir.mid(i+1); } return QVariant(); } ctkQtResourceTreeNode* ctkQtResourceTreeItem::parent() const { return parentNode; } ctkQtResourceTreeNode::ctkQtResourceTreeNode(const QFileInfo& dirInfo, ctkQtResourceTreeNode* parent) : ctkQtResourceTreeItem(dirInfo, parent) { QFileInfoList infoList = QDir(dirInfo.absoluteFilePath()).entryInfoList(); QListIterator it(infoList); while (it.hasNext()) { const QFileInfo& info = it.next(); if (info.isFile()) { children.push_back(new ctkQtResourceTreeItem(info, this)); } else { children.push_back(new ctkQtResourceTreeNode(info, this)); } } } ctkQtResourceTreeNode::~ctkQtResourceTreeNode() { qDeleteAll(children); } ctkQtResourceTreeItem* ctkQtResourceTreeNode::child(int row) { return children.value(row); } int ctkQtResourceTreeNode::childCount() const { return children.size(); } int ctkQtResourceTreeNode::indexOf(ctkQtResourceTreeItem* child) const { return children.indexOf(child); } ctkQtResourcesTreeModel::ctkQtResourcesTreeModel(QObject* parent) : QAbstractItemModel(parent) { rootItem = new ctkQtResourceTreeNode(QFileInfo(":/")); } ctkQtResourcesTreeModel::~ctkQtResourcesTreeModel() { delete rootItem; } QVariant ctkQtResourcesTreeModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); if (role == Qt::DisplayRole) { ctkQtResourceTreeItem* item = static_cast(index.internalPointer()); return item->data(role); } return QVariant(); } Qt::ItemFlags ctkQtResourcesTreeModel::flags(const QModelIndex &index) const { if (!index.isValid()) return Qt::ItemFlags(); return Qt::ItemIsEnabled | Qt::ItemIsSelectable; } QVariant ctkQtResourcesTreeModel::headerData(int section, Qt::Orientation orientation, int role) const { Q_UNUSED(section) Q_UNUSED(orientation) Q_UNUSED(role) return QVariant(); } QModelIndex ctkQtResourcesTreeModel::index(int row, int column, const QModelIndex &parent) const { if (!hasIndex(row, column, parent)) return QModelIndex(); if (!parent.isValid()) return createIndex(row, column, rootItem); ctkQtResourceTreeItem* parentItem = static_cast(parent.internalPointer()); ctkQtResourceTreeItem* childItem = parentItem->child(row); if (childItem) return createIndex(row, column, childItem); else return QModelIndex(); } QModelIndex ctkQtResourcesTreeModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); ctkQtResourceTreeItem* childItem = static_cast(index.internalPointer()); ctkQtResourceTreeItem* parentItem = childItem->parent(); if (parentItem) return createIndex(parentItem->row(), 0, parentItem); return QModelIndex(); } int ctkQtResourcesTreeModel::rowCount(const QModelIndex &parent) const { if (parent.column() > 0) return 0; if (!parent.isValid()) { return 1; } else { ctkQtResourceTreeItem* parentItem = static_cast(parent.internalPointer()); return parentItem->childCount(); } } int ctkQtResourcesTreeModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent) return 1; } ctk-2026.09.02/Applications/ctkPluginBrowser/ctkQtResourcesTreeModel.h000066400000000000000000000033151524622605700255750ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKQTRESOURCESTREEMODEL_H #define CTKQTRESOURCESTREEMODEL_H #include #include class ctkQtResourceTreeItem; class ctkQtResourcesTreeModel : public QAbstractItemModel { Q_OBJECT public: ctkQtResourcesTreeModel(QObject* parent = 0); ~ctkQtResourcesTreeModel(); QVariant data(const QModelIndex &index, int role) const; Qt::ItemFlags flags(const QModelIndex &index) const; QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const; QModelIndex parent(const QModelIndex &index) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex &parent = QModelIndex()) const; private: ctkQtResourceTreeItem* rootItem; }; #endif // CTKQTRESOURCESTREEMODEL_H ctk-2026.09.02/Applications/ctkPluginBrowser/images/000077500000000000000000000000001524622605700221055ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkPluginBrowser/images/linkicon.png000066400000000000000000000011201524622605700244130ustar00rootroot00000000000000‰PNG  IHDRóÿasBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ÍIDAT8�­“?hZQÆ¿û¢¼H¤:‡ Á�Nm–¶ÙHˆ¸'ÇÖR.c‡`éR:t±BÉ”½ É (O“ÐÁH**â^ðO…÷ìµÜ¾çÃw:Té‹XZ°¾åœûý8œs.#"ÌÒLîÿpLÉÍX˜È™øß7ƒÁ[“`‡ÃI’ŠÞ¸ºF "*•Ê«jµú!�†ܳËï÷ï(Šò²¬c"’Æ"úàév»åF£±b/Žä©×ë·‚Áàf¿ßÏÑÉ“€•^¯wFD·mÆu!Ä‘®ëE]×?qÎ/MÓüfÆg˲Έh�ˆ<ã-|/—Ëžx (ʪªªos¹Ü—X,ö2‘H¼©Õjµf³Y”eùi(z×étŽ;˜óù|ÛÙlv�sþ‘s^7 £+„(! ªªžçóùƒL&½¿�LJÓßÜüÖ’Éän»ÝV¬�à²Ï&�N?✳i§ìt:ïkš¶ïv»³NˆkGašË­Vë¹Ëå:œ `Œy#‘ÈF*•ºëõzï0Æælkgš¦ý(•J…p8üz*`Y°@ž(€¯šDdýð¯1ógú ™T5ÕêIEND®B`‚ctk-2026.09.02/Applications/ctkPluginBrowser/images/run-now.png000066400000000000000000000030471524622605700242240ustar00rootroot00000000000000‰PNG  IHDR szzôsRGB®ÎébKGDÿÿÿ ½§“ pHYs  šœtIMEÚ P:=/§IDATXÃí•Ëkœ×Æç›ùFÖÌH3£ÑÝ�,ÙS9qê´–»1n)4PZ ÙD´Ý MY„Bi›]Wí¢›�¿ à@!PZh‰C°‚°lÉr$ilÝ#�.Í]3ßí¼]Œ¤HuG¸Ð�8‹ïüÏsÞóx¦gú?Ë@˜ÞsÃǾè8ëÈÜ)Ìy€æo£¬Ì×àÿýð÷ÿxSÞŸù¹\üu»Hñ>8Ê ðµ¾·Ž^Ž¿Ôdô†�ˆ¼³™Ûv½,“@â Üyê.§†ãÇ(–J„:‘ç¾ßèˆüÀ Ú?[_¨Õ.ü8uá±Ïµ¿ÜSßÚ-{Íp÷æ‚jhÃ<ÀåäéþçBGÍ_VÜbwõ7j«”40ôZj¸¹'€Us@Ê'&[µMu¯p›taJªE´hÐxà�çÂV±@ÞŸ!ñ|Ým=d>ñÈ­VU0�ÚáFÞŸ‘ÄóíFÿ‹‰A3®¥CÕPeI>> šâÚBÅ)©ÙÂ-æ wUÉ*£4JvŒYDƒcA¦°…zù¹Y›|©ˆѨ®¤©¤_ò×ÊöÅõµâ¨w ñS²JÌf'YÝ^Ft}_ ¸ºn R7ùr¯fCSc€c-=°æêGcX͉$P®³Ë$ïA–BÆÇWn®¯Íæþ,pµÀ„�íUæÖfÈKøÕ>©×¾û½»¼�P>ú[Rƒ,þk�œyŸèwÀ €ã�ÏØãÆâ?×­ù[÷þXçPŸ�z?äª9,«†rÁÙ1Õì! €í€éƒîh’`®•åÏÖØ¬¥i> Ñ0b;(ÓS�%uãVÜXY·ç®§?È�ó°µÿÖ(Pb Žã€¬Xvp5(º# šj­d>Éq7?NèˆÄ×CyÎW™«95>1qeóš¼ ,í^¿ÜØ—?¤z£>P® ®S7ß=1€ã""¨Îx'1«›�Ñ÷Ö?§aÀ#òMÄqÁ²P]ñ./juù6FsL_Ÿþp}Äù-0»ÿÄûÍ4 uýJ¹{ 8(ñP\ušI6o¹µ2…Ñ뺄8ªfCkx�ûn~~gluÄz‡2ŸĆ0r7Ð�{ öˆÇ¯Þ€ÔlTG¬Åë4“¾âL•ééyxa›ÆKŽˆ@eû Ÿ¸>;¹IîH/sN|y€ÒèØÓÌší’µ[½4u¸Q|’ø¥Æ8ÃÈ' ðÈÞ0�µe¤3Ü5°þÑjZ}.•É 6<[ÉT¬ÙOÀÿ�©)ØuºfâkPX·£†úV/“‘4ÓÃEÚ¿æ£`+Þw},à¡É(Ï�÷þerõ�ïô ñGá¤�2öï:&¶~¹ ‹�PW€Ú°‡èùñSõ›]$Æ4ŠÑ{s@Übý‰WÞyöíšµ>þ|à¯zÏáéß«~¸ÿòSª@Á0tò¤Qm9Ìœ�¡£ó ¾7Ε¿åY»»œÄx€äi¨ì°æ{MA¨cOó7KE¨4u¸;Ÿ|ñÍWÏéÿüùpß¾ÿ)͉‡îA5Ьjwиq%U!ƒIf?0ð‡�d¯&ï¯B�ì wßP„rý£ÕΆVßc†K}îÍ÷'w~«íÜ‚ša.#27ÀœŒ±ªµœu]MTË™�H’½"©ÝiñJR¾ àßbÍwP*Bi×]B×LékPĺ5ÞúVïîèë>üÓ�¦+vÍ]À„Þ}ˆ[3$�8µ*hiá^ã`*’"Ñ ®:A~òfñÛtí wW5;)U¤DØ)æ¹)‹Âßb7C]�@mسwø�üÞ³¯iÃ[~Ë 0t˜O§HÚcÛª m â˜,$ó´|i¦;Ϩ¼ €§ÃÝþf'jQCšÓ”Há.©W(¦0dE³­Ÿ«­®jr}{äH~wÿ/ôHÝW¹*Mz ¥Ø6/¥7CÇg;)dUο£ýñz¦âiÌ„%d¿UqH ¦†H�R”Ö ¤”‹NµRfä¼X·»ÒhèªØ<²5y¼ÿ7ÑbÿV¿×u°l ÆÛ€usìàiâà $0t<мAg)€ÐÀ4-qÓ°`déWÒPP„�œšó…��ؤ‚¬~¬N<¹uý¶ËÛSýC¯�ùðØÅ}Ÿa$}ü[ú21r³ÜR»À@6S!«'Ï]dº0ŽªK+�F&¥MLR·«A;7~åÒÆ™=CïEò•DSw· �€F¨sO¸»¢ÁI± �©›t0_˜S牤Dª�Æ4˜`à D©•¤=&ƒmÕJhc°Ã0`ºóî…Qyl¹xoÊõÀ°£˜N²ZŠ«Ùÿ2“�a˜Ö#RZiZL�”Vz¿UL]d¥Ïmnn›óÌ‘¡—ÑãÚGoPjΊ´“)fžëc"7VÊ= º ¦¼žšEa³ôLAoy™ �£nåØÁÓSñáį%¼{g„UˆÓ¹ FâCÌ¥3ØÅ "0—Fl˜€Í¡ª0ʬK¹ztªxùÜÅ_¥Ï°Ÿ[ÜËØ!‘OP,:h%ÑŨ¯Eo‚T 6Á£Y>P¢'¦Ô‘S‘×gx˜¿ÝY°| RÁÔlhšvÍêE‹#×  Ôù‚x +EìÝ„8söìÁ™ÿÈ—€Q°¶_¢ç¦­(ÖÔUеRAš×{�¦#¥DÔj�Êb­múd‚ §.š:¡ý ¾ñu·¿s#Ò-€E4„€€; j�Ìô¦m§û{&N_$ËûþN”D/æÝ^H–L–Íš †å€,¨ˆÕþ*£ÆÑhKå9{j¸o¬g᜸)â{¿õY ,TÕ  ‚ÏåU6“�¶Áó#C—O¦BœÃ•�(É{½3€†.YáðÊ` NèQAäíèÕ+g/¹|"Þ‡!ÓGü†¾·ÄV¥Åè[ñ¹xáÒ‘DøåÛ)Ħç«�6=_…gÃÇ»–/)]MeC‡ë�Äxîdæ<û¾1Œ!%4¨òz¨.k$z\Ð÷�qFz“„:+éM’ÿèA”VžùC÷Î1òÙ‚Õí°¶¢fZ¾ù*\Š-Œ½_ ïïŒdiü´‡Ñ�,jäü1Y¿;€½!E± _kB¦aA`@.«_˜¢ªU²aG3þ€—©Kiæ5‚Û\„†>{?Nkµõñ*l�iÔ‚Ž©—ÌëwiZ0‰tžY=Nu»ƒõ[šq{œÌŽfHÆ ‚ÛÊÈj2y/|ý�mØ6dMÂr t32 ëБ%Óa‚Цç³Lfb<üd-�¡ ® …x$ɦ§êÉË ¹±åþ„ º|�—úIEND®B`‚ctk-2026.09.02/Applications/ctkPluginBrowser/images/stop.png000066400000000000000000000011021524622605700235720ustar00rootroot00000000000000‰PNG  IHDR szzôtEXtSoftwareAdobe ImageReadyqÉe<äIDATxÚäWKnÂ0|¦ uÝpSµËî8ê¦UW=,AbŨøH � ‰�DEI“دN ‰ý,ê�í|<ã™q3D„[– ܸd÷�GÆÞdõt%Ü÷Äg¯ÁöHøZ*¥ î¡eÁK±’ )°/¼Û5CRÞµ»|>Þ‚ð“x°“6c'Ïf£/á¥ÀBóAàË%ˆÕ ²ŽC#�lßç‹ðÉäÊ×ë`Íeà>—K§€ª�® ®tp§S?h˜0.WYàaüÔj ‚uk|–B~4<`ëë‹$¯‰zü»R�ßáP –$)È( l Ø�FdOMÕѰçs?¥çÈ|Ö*ðnº Ë, pô:£„�Ÿ‘tU&HË�˜Z@UC«€ X@±!µ"’TʬAãûqŸé6#Ø€‹ÛSŒ@Š4Û9‰€ * ‹{�BŸ@&£Ó‘I"!(?$…ÂE~L��fÞqé³\¾ÚÑìpTø÷§ã?¸sº˜’IEND®B`‚ctk-2026.09.02/Applications/ctkPluginBrowser/target_libraries.cmake000066400000000000000000000002721524622605700251650ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKPluginFramework ) ctk-2026.09.02/Applications/ctkPluginGenerator/000077500000000000000000000000001524622605700211435ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkPluginGenerator/CMakeLists.txt000066400000000000000000000014331524622605700237040ustar00rootroot00000000000000project(ctkPluginGenerator) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkPluginGenerator.cpp ctkPluginGeneratorMain.cpp ctkPluginGeneratorOptionsDialog.cpp ) # UI files set(KIT_UI_FORMS ctkPluginGeneratorMainWindow.ui ctkPluginGeneratorOptionsDialog.ui ) # Resources set(KIT_resources ctkPluginGenerator.qrc ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkPluginGenerator/DefaultLicense.txt000066400000000000000000000013421524622605700245730ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) %1 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 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. =============================================================================*/ ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGenerator.cpp000066400000000000000000000226731524622605700254700ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkPluginGenerator_p.h" #include "ui_ctkPluginGeneratorMainWindow.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include class ctkTemporaryDir { public: static QString create(const QString& path = QString()) { QString tmpPath = path; if (tmpPath.isEmpty()) { tmpPath = "ctkplugingenerator"; } tmpPath += "." + QTime::currentTime().toString("hhmmsszzz"); QDir tmp = QDir::temp(); if (!tmp.mkdir(tmpPath)) { QString msg = QString("Creating temporary directory ") + tmpPath + " in " + QDir::temp().canonicalPath() + " failed."; throw std::runtime_error(msg.toStdString()); } tmp.cd(tmpPath); return tmp.canonicalPath(); } }; ctkPluginGenerator::ctkPluginGenerator(ctkPluginFramework* framework, QWidget *parent) : QMainWindow(parent), framework(framework), ui(new Ui::ctkPluginGeneratorMainWindow), mode(EDIT), previewModel(0) { ui->setupUi(this); previewModel = new QFileSystemModel(this); ui->previewTreeView->setModel(previewModel); ui->previewTreeView->hideColumn(1); ui->previewTreeView->hideColumn(2); ui->previewTreeView->hideColumn(3); this->setStatusBar(0); connect(ui->actionOptions, SIGNAL(triggered(bool)), this, SLOT(menuOptionsTriggered())); connect(ui->generateButton, SIGNAL(clicked()), this, SLOT(generateClicked())); connect(ui->previewButton, SIGNAL(clicked()), this, SLOT(previewClicked())); connect(ui->cancelButton, SIGNAL(clicked()), qApp, SLOT(quit())); connect(ui->uiExtensionList, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(extensionItemClicked(QListWidgetItem*))); connect(ui->previewTreeView->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)), this, SLOT(previewIndexChanged(QModelIndex))); QList serviceRefs = framework->getPluginContext()-> getServiceReferences("ctkPluginGeneratorAbstractUiExtension"); QListIterator it(serviceRefs); while (it.hasNext()) { ctkServiceReference serviceRef = it.next(); ctkPluginGeneratorAbstractUiExtension* extension = qobject_cast(framework->getPluginContext()->getService(serviceRef)); qDebug() << "Service reference found"; if (extension) { qDebug() << "inserted"; int ranking = serviceRef.getProperty(ctkPluginConstants::SERVICE_RANKING).toInt(); if (ranking > 0) { uiExtensionMap.insert(ranking, extension); } else { uiExtensionMap.insert(-1, extension); } } } int id = 0; foreach (ctkPluginGeneratorAbstractUiExtension* extension, uiExtensionMap) { idToExtensionMap.insert(id, extension); ui->extensionStack->addWidget(extension->getWidget()); connect(extension, SIGNAL(errorMessageChanged(QString)), this, SLOT(errorMessageChanged(QString))); extension->validate(); (new QListWidgetItem(extension->getTitle(), ui->uiExtensionList))->setData(Qt::UserRole, id); ++id; } ui->uiExtensionList->setCurrentRow(0); extensionClicked(idToExtensionMap[0]); } ctkPluginGenerator::~ctkPluginGenerator() { delete ui; if (!previewDir.isEmpty()) { ctk::removeDirRecursively(previewDir); } } void ctkPluginGenerator::menuOptionsTriggered() { ctkPluginGeneratorOptionsDialog optionsDialog; int result = optionsDialog.exec(); if (result == QDialog::Accepted && mode == PREVIEW) { QString selPath; QString oldPreviewDir = previewDir; if (!ui->previewTreeView->selectionModel()->selection().isEmpty()) { QModelIndex index = ui->previewTreeView->selectionModel()->selectedIndexes().front(); selPath = previewModel->data(index, QFileSystemModel::FilePathRole).toString(); } if (createPreview()) { ui->modeStack->setCurrentWidget(ui->previewPage); ui->previewButton->setText(tr("<< Back")); ui->previewTreeView->expandAll(); if (!selPath.isEmpty()) { selPath.replace(oldPreviewDir, previewDir); QModelIndex index = previewModel->index(selPath); ui->previewTreeView->selectionModel()->select(index, QItemSelectionModel::ClearAndSelect); previewIndexChanged(index); } } } } void ctkPluginGenerator::previewClicked() { if (mode == EDIT) { if (createPreview()) { ui->modeStack->setCurrentWidget(ui->previewPage); ui->previewButton->setText(tr("<< Back")); ui->previewTreeView->expandAll(); if (!ui->previewTreeView->selectionModel()->selection().isEmpty()) { previewIndexChanged(ui->previewTreeView->selectionModel()->selectedIndexes().front()); } mode = PREVIEW; } } else { ui->modeStack->setCurrentWidget(ui->editPage); ui->previewButton->setText(tr("Preview >>")); mode = EDIT; ctk::removeDirRecursively(previewDir); previewDir.clear(); } } void ctkPluginGenerator::generateClicked() { try { createPlugin(ui->outputDirButton->directory()); QMessageBox msgBox; msgBox.setText(tr("Successfully create plugin")); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Information); msgBox.exec(); } catch (const std::runtime_error& error) { QMessageBox msgBox; msgBox.setText(tr("Creating the plugin failed.")); msgBox.setInformativeText(QString::fromLatin1(error.what())); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Critical); msgBox.exec(); } } QString ctkPluginGenerator::createPlugin(const QString& path) { ctkServiceReference codeModelRef = framework->getPluginContext()-> getServiceReference("ctkPluginGeneratorCodeModel"); ctkPluginGeneratorCodeModel* codeModel = qobject_cast(framework->getPluginContext()->getService(codeModelRef)); codeModel->reset(); // set global code model info from QSettings object QSettings settings; codeModel->setLicense(settings.value(ctkPluginGeneratorConstants::PLUGIN_LICENSE_MARKER).toString()); foreach(ctkPluginGeneratorAbstractUiExtension* extension, idToExtensionMap) { extension->updateCodeModel(); } QString pluginDir = path + "/" + codeModel->getSymbolicName(true); if (!QDir(path).mkdir(codeModel->getSymbolicName(true))) { QString msg(tr("Creating directory \"%1\" failed.").arg(pluginDir)); throw std::runtime_error(msg.toStdString()); } codeModel->create(pluginDir); return pluginDir; } void ctkPluginGenerator::previewIndexChanged(const QModelIndex& index) { QString filePath = previewModel->data(index, QFileSystemModel::FilePathRole).toString(); ui->previewTextLabel->setText(QDir(QString(filePath).replace(previewDir, ui->outputDirButton->directory())).absolutePath()); QFile file(filePath); file.open(QFile::ReadOnly); QTextStream textStream(&file); ui->previewTextEdit->setText(textStream.readAll()); } bool ctkPluginGenerator::createPreview() { try { previewDir = ctkTemporaryDir::create(); QString tmpPluginDir = createPlugin(previewDir); previewModel->setRootPath(tmpPluginDir); ui->previewTreeView->setRootIndex(previewModel->index(previewDir)); } catch (const std::runtime_error& error) { QMessageBox msgBox; msgBox.setText(tr("Creating the preview failed.")); msgBox.setInformativeText(QString::fromLatin1(error.what())); msgBox.setStandardButtons(QMessageBox::Ok); msgBox.setIcon(QMessageBox::Critical); msgBox.exec(); return false; } return true; } void ctkPluginGenerator::extensionItemClicked(QListWidgetItem* item) { ctkPluginGeneratorAbstractUiExtension* extension = idToExtensionMap[item->data(Qt::UserRole).toInt()]; extensionClicked(extension); } void ctkPluginGenerator::extensionClicked(ctkPluginGeneratorAbstractUiExtension* extension) { ui->extensionStack->setCurrentWidget(extension->getWidget()); ui->extensionMsgLabel->setText(extension->getTitle()); this->errorMessageChanged(extension->getErrorMessage()); } void ctkPluginGenerator::errorMessageChanged(const QString& errMsg) { ui->extensionErrMsgLabel->setText(errMsg); bool enableButtons = false; if (errMsg.isEmpty()) { enableButtons = true; } ui->previewButton->setEnabled(enableButtons); ui->generateButton->setEnabled(enableButtons); } ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGenerator.qrc000066400000000000000000000002061524622605700254570ustar00rootroot00000000000000 DefaultLicense.txt ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGeneratorMain.cpp000066400000000000000000000062411524622605700262660ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include #include #include #include #include #include #include "ctkPluginGenerator_p.h" #include #include #include #include #include int main(int argv, char** argc) { QApplication app(argv, argc); qApp->setOrganizationName("CTK"); qApp->setOrganizationDomain("commontk.org"); qApp->setApplicationName("ctkPluginGenerator"); // init global template defaults QSettings settings; if (!settings.contains(ctkPluginGeneratorConstants::PLUGIN_LICENSE_MARKER)) { QFile license(":/generatordefaults/license.txt"); license.open(QIODevice::ReadOnly); QString licenseText = license.readAll(); bool ok; QString organization = QInputDialog::getText(0, ctkPluginGenerator::tr("CTK Plugin Generator"), ctkPluginGenerator::tr("Enter the name of your organization:"), QLineEdit::Normal, ctkPluginGenerator::tr(""), &ok); if (!ok) { exit(0); } organization.replace("\\n", "\n"); settings.setValue(ctkPluginGeneratorConstants::PLUGIN_LICENSE_MARKER, licenseText.arg(organization)); } ctkPluginFrameworkFactory fwFactory; QSharedPointer framework = fwFactory.getFramework(); try { framework->init(); } catch (const ctkPluginException& exc) { qCritical() << "Failed to initialize the plug-in framework:" << exc; exit(1); } #ifdef CMAKE_INTDIR QString pluginPath = CTK_PLUGIN_DIR CMAKE_INTDIR "/"; #else QString pluginPath = CTK_PLUGIN_DIR; #endif qApp->addLibraryPath(pluginPath); QStringList libFilter; libFilter << "*.dll" << "*.so" << "*.dylib"; QDirIterator dirIter(pluginPath, libFilter, QDir::Files); while(dirIter.hasNext()) { try { QString fileLocation = dirIter.next(); if (fileLocation.contains("org_commontk_plugingenerator")) { QSharedPointer plugin = framework->getPluginContext()->installPlugin(QUrl::fromLocalFile(fileLocation)); plugin->start(ctkPlugin::START_TRANSIENT); } } catch (const ctkPluginException& e) { qCritical() << e.what(); } } framework->start(); ctkPluginGenerator generator(framework.data()); generator.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGeneratorMainWindow.ui000066400000000000000000000437621524622605700273220ustar00rootroot00000000000000 ctkPluginGeneratorMainWindow 0 0 800 600 CTK Plugin Generator true 0 1 0 0 0 0 0 Qt::Horizontal 0 0 0 0 0 40 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> <tr> <td style="border: none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Plugin</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Generator</span></p></td></tr></table></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 200 0 1 0 6 0 0 0 0 0 0 0 0 0 20 75 true TextLabel 0 20 255 0 0 255 0 0 150 147 140 TextLabel 1 0 Qt::LeftToRight 0 0 0 0 Qt::Horizontal 0 0 0 0 0 40 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> <html><head><meta name="qrichtext" content="1" /><style type="text/css"> p, li { white-space: pre-wrap; } </style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;"> <table border="0" style="-qt-table-type: root; margin-top:4px; margin-bottom:4px; margin-left:4px; margin-right:4px;"> <tr> <td style="border: none;"> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Plugin </span><span style=" font-size:12pt; font-weight:600;">Generator</span></p> <p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:12pt; font-weight:600;">Preview</span></p></td></tr></table></body></html> Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop 0 0 0 0 0 40 Qt::AlignBottom|Qt::AlignLeading|Qt::AlignLeft true true 0 0 0 0 0 0 Output directory 1 0 Choose output directory ctkDirectoryButton::HideNameFilterDetails Qt::Horizontal Qt::Vertical 20 4 0 0 0 0 Preview >> Qt::Horizontal 40 20 Generate Exit 0 0 800 22 File Exit Ctrl+Q Options... ctkDirectoryButton QWidget
ctkDirectoryButton.h
1 directoryChanged(QString)
actionExit triggered() cancelButton click() -1 -1 748 555
ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGeneratorOptionsDialog.cpp000066400000000000000000000031201524622605700301460ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkPluginGeneratorOptionsDialog_p.h" #include "ui_ctkPluginGeneratorOptionsDialog.h" #include #include ctkPluginGeneratorOptionsDialog::ctkPluginGeneratorOptionsDialog(QWidget *parent) : QDialog(parent), ui(new Ui::ctkPluginGeneratorOptionsDialog) { ui->setupUi(this); QSettings settings; ui->licenseEdit->setPlainText(settings.value( ctkPluginGeneratorConstants::PLUGIN_LICENSE_MARKER).toString()); } ctkPluginGeneratorOptionsDialog::~ctkPluginGeneratorOptionsDialog() { delete ui; } void ctkPluginGeneratorOptionsDialog::accept() { QSettings settings; settings.setValue(ctkPluginGeneratorConstants::PLUGIN_LICENSE_MARKER, ui->licenseEdit->toPlainText()); QDialog::accept(); } ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGeneratorOptionsDialog.ui000066400000000000000000000033151524622605700300070ustar00rootroot00000000000000 ctkPluginGeneratorOptionsDialog 0 0 400 300 Options License template Qt::Horizontal QDialogButtonBox::Cancel|QDialogButtonBox::Ok buttonBox accepted() ctkPluginGeneratorOptionsDialog accept() 248 254 157 274 buttonBox rejected() ctkPluginGeneratorOptionsDialog reject() 316 260 286 274 ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGeneratorOptionsDialog_p.h000066400000000000000000000024161524622605700301410ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKPLUGINGENERATOROPTIONSDIALOG_H #define CTKPLUGINGENERATOROPTIONSDIALOG_H #include namespace Ui { class ctkPluginGeneratorOptionsDialog; } class ctkPluginGeneratorOptionsDialog : public QDialog { Q_OBJECT public: explicit ctkPluginGeneratorOptionsDialog(QWidget *parent = 0); ~ctkPluginGeneratorOptionsDialog(); void accept(); private: Ui::ctkPluginGeneratorOptionsDialog *ui; }; #endif // CTKPLUGINGENERATOROPTIONSDIALOG_H ctk-2026.09.02/Applications/ctkPluginGenerator/ctkPluginGenerator_p.h000066400000000000000000000041631524622605700254460ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKPLUGINGENERATOR_H #define CTKPLUGINGENERATOR_H #include #include #include class ctkPluginFramework; class QListWidgetItem; class QFileSystemModel; #include namespace Ui { class ctkPluginGeneratorMainWindow; } class ctkPluginGenerator : public QMainWindow { Q_OBJECT public: explicit ctkPluginGenerator(ctkPluginFramework* framework, QWidget *parent = 0); ~ctkPluginGenerator(); protected Q_SLOTS: void previewClicked(); void generateClicked(); void previewIndexChanged(const QModelIndex& index); void extensionItemClicked(QListWidgetItem* item); void errorMessageChanged(const QString& errMsg); void menuOptionsTriggered(); private: void extensionClicked(ctkPluginGeneratorAbstractUiExtension* extension); QString createPlugin(const QString& path); bool createPreview(); enum GeneratorMode { EDIT, PREVIEW }; ctkPluginFramework *const framework; Ui::ctkPluginGeneratorMainWindow *ui; GeneratorMode mode; QFileSystemModel* previewModel; QString previewDir; QMultiMap uiExtensionMap; QHash idToExtensionMap; }; #endif // CTKPLUGINGENERATOR_H ctk-2026.09.02/Applications/ctkPluginGenerator/target_libraries.cmake000066400000000000000000000003341524622605700254670ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKPluginFramework org_commontk_plugingenerator_ui ) ctk-2026.09.02/Applications/ctkQtTesting/000077500000000000000000000000001524622605700177605ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkQtTesting/CMakeLists.txt000066400000000000000000000013041524622605700225160ustar00rootroot00000000000000project(ctkQtTesting) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkQtTestingMain.cpp ctkQtTestingMainWindow.cpp ctkQtTestingMainWindow.h ) # UI files set(KIT_UI_FORMS ctkQtTestingMainWindow.ui ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) # Testing if(BUILD_TESTING) # add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkQtTesting/Test.xml000066400000000000000000001146051524622605700214300ustar00rootroot00000000000000 ctk-2026.09.02/Applications/ctkQtTesting/ctkQtTestingMain.cpp000066400000000000000000000023011524622605700237110ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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 #include // CTK includes #include int main(int argv, char** argc) { QApplication app(argv, argc); // qApp->setOrganizationName("CTK"); // qApp->setOrganizationDomain("commontk.org"); // qApp->setApplicationName("ctkQtTesting"); ctkQtTestingMainWindow mainWindow; mainWindow.show(); return app.exec(); } ctk-2026.09.02/Applications/ctkQtTesting/ctkQtTestingMainWindow.cpp000066400000000000000000000067131524622605700251140ustar00rootroot00000000000000// QT includes #include #include #include #include #include #include #include // QtTesting includes #include "pqTestUtility.h" #include "pqEventObserver.h" #include "pqEventSource.h" // VTK includes #include #include #include #include #include #include #include #include #include #include #include #include #include // CTK includes #include "ctkQtTestingMainWindow.h" #include "ctkXMLEventObserver.h" #include "ctkXMLEventSource.h" //----------------------------------------------------------------------------- ctkQtTestingMainWindow::ctkQtTestingMainWindow() { this->Ui.setupUi(this); QObject::connect(Ui.RecordButton, SIGNAL(toggled(bool)), this, SLOT(record(bool))); QObject::connect(Ui.PlayBackButton, SIGNAL(clicked()), this, SLOT(play())); this->TestUtility = new ctkQtTestingUtility(this); this->TestUtility->addEventObserver("xml", new ctkXMLEventObserver(this->TestUtility)); this->TestUtility->addEventSource("xml", new ctkXMLEventSource(this->TestUtility)); Ui.renderView->setBackgroundColor(QColor(Qt::gray)); Ui.renderView->setBackgroundColor2(QColor(Qt::darkBlue)); Ui.renderView->setGradientBackground(true); Ui.renderView->setCornerAnnotationText("ctk Qt test"); // Create a cube. vtkSmartPointer cubeSource = vtkSmartPointer::New(); // Create a mapper and actor. vtkSmartPointer mapper = vtkSmartPointer::New(); mapper->SetInputConnection(cubeSource->GetOutputPort()); vtkSmartPointer actor = vtkSmartPointer::New(); actor->SetMapper(mapper); // Add the actors to the scene Ui.renderView->renderer()->AddActor(actor); // vtkSmartPointer boxWidget = // vtkSmartPointer::New(); // boxWidget->SetInteractor(Ui.renderView->interactor()); // boxWidget->SetPlaceFactor(1.0); // boxWidget->PlaceWidget(); // boxWidget->On(); Ui.renderView->resetCamera(); } //----------------------------------------------------------------------------- ctkQtTestingMainWindow::~ctkQtTestingMainWindow() { if(TestUtility) { delete this->TestUtility; } } //----------------------------------------------------------------------------- void ctkQtTestingMainWindow::record(bool start) { if (start) { QString filename = QFileDialog::getSaveFileName (this, "Test File Name", QString(), "XML Files (*.xml)"); if (!filename.isEmpty()) { qDebug() << "Start recording"; QFileInfo fileInfo(filename); if (fileInfo.suffix() != "xml") { filename += ".xml"; } this->TestUtility->recordTests(filename); } } else { qDebug() << "Stop recording"; this->TestUtility->stopRecords(1); } } //----------------------------------------------------------------------------- void ctkQtTestingMainWindow::play() { qDebug() << "Start Playback"; QString filename = QFileDialog::getOpenFileName (this, "Test File Name", QString(), "XML Files (*.xml)"); if (!filename.isEmpty()) { this->TestUtility->playTests(filename); } qDebug() << "End Playback"; } ctk-2026.09.02/Applications/ctkQtTesting/ctkQtTestingMainWindow.h000066400000000000000000000010321524622605700245460ustar00rootroot00000000000000#ifndef CTKQTTESTINGMAINWINDOW_H #define CTKQTTESTINGMAINWINDOW_H #include #include #include "ui_ctkQtTestingMainWindow.h" //class pqTestUtility; class ctkQtTestingMainWindow : public QMainWindow { Q_OBJECT public: ctkQtTestingMainWindow(); ~ctkQtTestingMainWindow(); protected slots: void record(bool start); void play(); private: Q_DISABLE_COPY(ctkQtTestingMainWindow) // pqTestUtility *TestUtility; ctkQtTestingUtility *TestUtility; Ui::ctkQtTestingMainWindow Ui; }; #endif ctk-2026.09.02/Applications/ctkQtTesting/ctkQtTestingMainWindow.ui000066400000000000000000000107201524622605700247400ustar00rootroot00000000000000 ctkQtTestingMainWindow 0 0 794 595 Qt Testing true 51 51 51 51 51 51 false true 0 Qt::Horizontal Qt::Horizontal Qt::Vertical 20 40 Record true PlayBack 0 0 794 23 ctkVTKRenderView QWidget
ctkVTKRenderView.h
ctkAxesWidget QWidget
ctkAxesWidget.h
ctkFontButton QPushButton
ctkFontButton.h
ctkRangeSlider QSlider
ctkRangeSlider.h
ctkRangeWidget QWidget
ctkRangeWidget.h
ctkSearchBox QLineEdit
ctkSearchBox.h
ctkSliderWidget QWidget
ctkSliderWidget.h
ctk-2026.09.02/Applications/ctkQtTesting/target_libraries.cmake000066400000000000000000000002641524622605700243060ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKQtTesting ) ctk-2026.09.02/Applications/ctkSimplePythonShell/000077500000000000000000000000001524622605700214615ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkSimplePythonShell/CMakeLists.txt000066400000000000000000000056321524622605700242270ustar00rootroot00000000000000project(ctkSimplePythonShell) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ${CMAKE_CURRENT_BINARY_DIR}/ctkSimplePythonManager.cpp ctkSimplePythonManager.h ctkSimplePythonQtDecorators.h ctkSimplePythonShellMain.cpp ctkTestWrappedQProperty.h ctkTestWrappedQInvokable.h ctkTestWrappedSlot.h ) if(CTK_LIB_Scripting/Python/Core AND CTK_LIB_Scripting/Python/Core_PYTHONQT_USE_VTK) list(APPEND KIT_SRCS ctkTestWrappedQListOfVTKObject.h ctkTestWrappedVTKObserver.h ctkTestWrappedVTKQInvokable.h ctkTestWrappedVTKSlot.h ) endif() # UI files set(KIT_UI_FORMS ) # Resources set(KIT_resources ) set(VTK_LIBRARIES ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) # Configure file will be configured using CTK_WRAP_PYTHONQT_LIGHT and # CTK_BUILD_SHARED_LIBS variables configure_file( ctkSimplePythonShellConfigure.h.in ${CMAKE_CURRENT_BINARY_DIR}/ctkSimplePythonShellConfigure.h ) # The following block generate the code required to initialize the wrapper # when CTK is statically built. if(NOT CTK_BUILD_SHARED_LIBS AND CTK_WRAP_PYTHONQT_LIGHT) # Update list of target libraries with the list of available PythonQt libraries # and set variables holding list of pythonqt initialization method set(CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION) set(CTK_PYTHONQT_INITIALIZATION_METHOD_CALL) # To avoid the complex process of resolving the dependencies associated with each # external project required by each decorator. For now, let's just include the decorator # associated with CTKCore and CTKWidgets. set(MY_CTK_WRAPPED_LIBRARIES_PYTHONQT) if(CTK_LIB_Core) list(APPEND MY_CTK_WRAPPED_LIBRARIES_PYTHONQT CTKCore) endif() if(CTK_LIB_Widgets) list(APPEND MY_CTK_WRAPPED_LIBRARIES_PYTHONQT CTKWidgets) endif() if(CTK_LIB_DICOM/Core) list(APPEND MY_CTK_WRAPPED_LIBRARIES_PYTHONQT CTKDICOMCore) endif() if(CTK_LIB_DICOM/Widgets) list(APPEND MY_CTK_WRAPPED_LIBRARIES_PYTHONQT CTKDICOMWidgets) endif() foreach(lib_name ${MY_CTK_WRAPPED_LIBRARIES_PYTHONQT}) list(APPEND KIT_target_libraries ${lib_name}PythonQt) set(CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION "${CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION} extern \"C\"{ void init${lib_name}PythonQt(); }") set(CTK_PYTHONQT_INITIALIZATION_METHOD_CALL "${CTK_PYTHONQT_INITIALIZATION_METHOD_CALL} init${lib_name}PythonQt();") endforeach() endif() configure_file( ctkSimplePythonManager.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/ctkSimplePythonManager.cpp ) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) add_subdirectory(Python) # Testing if(BUILD_TESTING) add_subdirectory(Testing) endif() ctk-2026.09.02/Applications/ctkSimplePythonShell/Python/000077500000000000000000000000001524622605700227425ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkSimplePythonShell/Python/CMakeLists.txt000066400000000000000000000004561524622605700255070ustar00rootroot00000000000000 set(KIT_PYTHON_SCRIPTS ctkSimplePythonShell ) set(KIT_PYTHON_RESOURCES ) ctkMacroCompilePythonScript( TARGET_NAME ${PROJECT_NAME} SCRIPTS "${KIT_PYTHON_SCRIPTS}" RESOURCES "${KIT_PYTHON_RESOURCES}" DESTINATION_DIR ${CTK_BINARY_DIR}/bin/Python INSTALL_DIR ${CTK_INSTALL_BIN_DIR} ) ctk-2026.09.02/Applications/ctkSimplePythonShell/Python/ctkSimplePythonShell.py000066400000000000000000000001641524622605700274420ustar00rootroot00000000000000import qt, ctk def app(): return _ctkSimplePythonShellInstance def quit(): exit() def exit(): app().quit() ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/000077500000000000000000000000001524622605700230765ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/CMakeLists.txt000066400000000000000000000000311524622605700256300ustar00rootroot00000000000000add_subdirectory(Python) ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/000077500000000000000000000000001524622605700243575ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/CMakeLists.txt000066400000000000000000000022071524622605700271200ustar00rootroot00000000000000 set(KIT_TESTS ${CPP_TEST_PATH}/ctkSimplePythonShell) set(SCRIPTS wrappedQInvokableTest.py wrappedQPropertyTest.py wrappedSlotTest.py ) # Since QTimer is part of QtCore and is used in both 'ctkWidgetsTest.py' and 'derivedQWidgetTest.py', # these two tests should be included only if CTK_LIB_Scripting/Python/Core_PYTHONQT_WRAP_QTCORE is ON if(CTK_LIB_Widgets AND CTK_LIB_Scripting/Python/Core_PYTHONQT_WRAP_QTCORE) list(APPEND SCRIPTS ctkWidgetsTest.py) endif() if(CTK_LIB_Scripting/Python/Core_PYTHONQT_WRAP_QTCORE AND CTK_LIB_Scripting/Python/Core_PYTHONQT_WRAP_QTGUI) list(APPEND SCRIPTS derivedQWidgetTest.py) endif() if(CTK_LIB_Scripting/Python/Core_PYTHONQT_USE_VTK) list(APPEND SCRIPTS vtkPythonSmoke.py wrappedVTKObserverTest.py wrappedVTKQInvokableTest.py wrappedVTKSlotTest.py ) endif() foreach(script ${SCRIPTS}) get_filename_component(scriptname ${script} NAME_WE) add_test( NAME ctkSimplePythonShell_${scriptname} COMMAND $ ${CMAKE_CURRENT_SOURCE_DIR}/${script} ) set_property(TEST ctkSimplePythonShell_${scriptname} PROPERTY LABELS ${KIT}) endforeach() ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/ctkWidgetsTest.py000066400000000000000000000012221524622605700276760ustar00rootroot00000000000000from __future__ import print_function from ctk import * from qt import QTimer # Test display of a CTK widget w = ctkMatrixWidget() w.show() # Test command execution using Python manager pythonManager = _ctkPythonManagerInstance pythonManager.executeString("variableInPythonConsole=523") try: print("variableInPythonConsole was successfully set to {0}".format(variableInPythonConsole)) except: print("PythonManager.executeString failed") qt.QApplication.exit(1) if not _ctkPythonConsoleInstance.isInteractive: #QTimer().singleShot(0, app(), SLOT('quit()')) t = QTimer() t.setInterval(250) t.connect('timeout()', app(), 'quit()') t.start() ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/derivedQWidgetTest.py000066400000000000000000000020341524622605700304770ustar00rootroot00000000000000from __future__ import division from qt import * class ExampleWidget(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.setGeometry(300, 300, 250, 150) self.setWindowTitle('Example Widget') layout = QHBoxLayout(self) checkbox = QCheckBox('Shell Visibility', self) layout.addWidget(checkbox); checkbox.setChecked(True) checkbox.connect('toggled(bool)', _ctkPythonConsoleInstance, 'setVisible(bool)') self.button = QPushButton('Quit', self) layout.addWidget(self.button); QObject.connect(self.button, SIGNAL('clicked()'), app(), SLOT('quit()')) self.center() def center(self): screen = QDesktopWidget().screenGeometry() size = self.geometry self.move(int((screen.width() - size.width())/2), int((screen.height() - size.height())/2)) w = ExampleWidget() w.show() if not _ctkPythonConsoleInstance.isInteractive: #QTimer().singleShot(250, app(), SLOT('quit()')) t = QTimer() t.setInterval(250) t.connect('timeout()', app(), 'quit()') t.start() ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/vtkPythonSmoke.py000066400000000000000000000015771524622605700277500ustar00rootroot00000000000000from __future__ import print_function # # Copied from VTK/Common/Testing/Python/PythonSmoke.py # import qt try: import vtk except: print("Cannot import vtk") qt.QApplication.exit(1) try: print(dir(vtk)) except: print("Cannot print dir(vtk)") qt.QApplication.exit(1) try: try: try: o = vtk.vtkLineWidget() print("Using Hybrid") except: o = vtk.vtkActor() print("Using Rendering") except: o = vtk.vtkObject() print("Using Common") except: print("Cannot create vtkObject") qt.QApplication.exit(1) try: print(o) print("Reference count: %d" % o.GetReferenceCount()) print("Class name: %s" % o.GetClassName()) except: print("Cannot print object") qt.QApplication.exit(1) try: b = vtk.vtkObject() d = b.SafeDownCast(o) print((b, d)) except: print("Cannot downcast") qt.QApplication.exit(1) qt.QApplication.exit(0) ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/wrappedQInvokableTest.py000066400000000000000000000003521524622605700312070ustar00rootroot00000000000000import qt if (_testWrappedQInvokableInstance.value() != 0): qt.QApplication.exit(1) _testWrappedQInvokableInstance.setValue(74) if (_testWrappedQInvokableInstance.value() != 74): qt.QApplication.exit(1) qt.QApplication.exit(0) ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/wrappedQPropertyTest.py000066400000000000000000000003421524622605700311200ustar00rootroot00000000000000 import qt if (_testWrappedQPropertyInstance.value != 0): qt.QApplication.exit(1) _testWrappedQPropertyInstance.value = 74 if (_testWrappedQPropertyInstance.value != 74): qt.QApplication.exit(1) qt.QApplication.exit(0) ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/wrappedSlotTest.py000066400000000000000000000003301524622605700300710ustar00rootroot00000000000000import qt if (_testWrappedSlotInstance.value() != 0): qt.QApplication.exit(1) _testWrappedSlotInstance.setValue(74) if (_testWrappedSlotInstance.value() != 74): qt.QApplication.exit(1) qt.QApplication.exit(0) ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/wrappedVTKObserverTest.py000066400000000000000000000007621524622605700313350ustar00rootroot00000000000000from __future__ import print_function import qt # Importing vtk initializes vtkPythonMap owned by vtkPythonUtil and prevent # call to vtkPythonUtil::GetObjectFromPointer() from segfaulting. # PythonQt internally uses vtkPythonUtil to properly wrap/unwrap VTK objects from vtk import * t = _testWrappedVTKObserverInstance.getTable() def onTableModified(caller, event): print("Table modified !") t.AddObserver(vtkCommand.ModifiedEvent, onTableModified) t.Modified() qt.QApplication.exit(0) ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/wrappedVTKQInvokableTest.py000066400000000000000000000010231524622605700315700ustar00rootroot00000000000000from __future__ import print_function import qt # Importing vtk initializes vtkPythonMap owned by vtkPythonUtil and prevent # call to vtkPythonUtil::GetObjectFromPointer() from segfaulting. # PythonQt internally uses vtkPythonUtil to properly wrap/unwrap VTK objects from vtk import * t = _testWrappedVTKQInvokableInstance.getTable() print(t.GetClassName()) t2 = vtkTable() _testWrappedVTKQInvokableInstance.setTable(t2) if _testWrappedVTKQInvokableInstance.getTable() != t2: qt.QApplication.exit(1) qt.QApplication.exit(0) ctk-2026.09.02/Applications/ctkSimplePythonShell/Testing/Python/wrappedVTKSlotTest.py000066400000000000000000000010011524622605700304520ustar00rootroot00000000000000from __future__ import print_function import qt # Importing vtk initializes vtkPythonMap owned by vtkPythonUtil and prevent # call to vtkPythonUtil::GetObjectFromPointer() from segfaulting. # PythonQt internally uses vtkPythonUtil to properly wrap/unwrap VTK objects from vtk import * t = _testWrappedVTKSlotInstance.getTable() print(t.GetClassName()) t2 = vtkTable() _testWrappedVTKSlotInstance.setTable(t2) if _testWrappedVTKSlotInstance.getTable() != t2: qt.QApplication.exit(1) qt.QApplication.exit(0) ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkSimplePythonManager.cpp.in000066400000000000000000000066271524622605700272350ustar00rootroot00000000000000 // QT includes #include #include #include // PythonQT includes #include // CTK includes #include "ctkSimplePythonManager.h" #include "ctkSimplePythonQtDecorators.h" #include "ctkSimplePythonShellConfigure.h" // For CTK_WRAP_PYTHONQT_LIGHT, CTK_WRAP_PYTHONQT_USE_VTK and CTK_BUILD_SHARED_LIBS #ifdef CTK_WRAP_PYTHONQT_USE_VTK # include "ctkVTKPythonQtWrapperFactory.h" #endif #if defined(CTK_WRAP_PYTHONQT_LIGHT) # ifndef CTK_BUILD_SHARED_LIBS // PythonQt wrapper initialization methods @CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION@ # endif #endif #ifdef CTK_WRAP_PYTHONQT_USE_VTK # if defined(CMAKE_INTDIR) # define VTK_PYTHON_LIBRARY_DIR VTK_PYTHON_LIBRARY_DIR_BUILD "/" CMAKE_INTDIR # else # define VTK_PYTHON_LIBRARY_DIR VTK_PYTHON_LIBRARY_DIR_BUILD # endif #endif //----------------------------------------------------------------------------- ctkSimplePythonManager::ctkSimplePythonManager(QObject* _parent) : Superclass(_parent) { } //----------------------------------------------------------------------------- ctkSimplePythonManager::~ctkSimplePythonManager() { } //----------------------------------------------------------------------------- QStringList ctkSimplePythonManager::pythonPaths() { QStringList paths; paths << Superclass::pythonPaths(); QString self_dir = QFileInfo(qApp->applicationFilePath()).absolutePath(); QString ctk_python_dir = self_dir; #if defined(CMAKE_INTDIR) ctk_python_dir.append("/.."); #endif ctk_python_dir.append("/Python"); paths << QFileInfo(ctk_python_dir).absoluteFilePath(); #ifdef CTK_BUILD_SHARED_LIBS // Path containing python module paths << self_dir; #endif #ifdef CTK_WRAP_PYTHONQT_USE_VTK // Try to put the VTK python module location in sys.path. QString vtk_package_dir = "@VTK_DIR@/Wrapping/Python"; bool found_vtk = false; QFileInfo fi(vtk_package_dir); vtk_package_dir = fi.absoluteFilePath(); if (fi.isDir()) { // This executable is running from the build tree. Prepend the // library directory and package directory to the search path. paths << vtk_package_dir; paths << VTK_PYTHON_LIBRARY_DIR; found_vtk = true; } Q_ASSERT(found_vtk); if (!found_vtk) { // TODO Handle case when the application is started from an installed tree } #endif return paths; } //----------------------------------------------------------------------------- void ctkSimplePythonManager::preInitialization() { Superclass::preInitialization(); #if defined(CTK_WRAP_PYTHONQT_LIGHT) # ifndef CTK_BUILD_SHARED_LIBS // Initialize wrappers @CTK_PYTHONQT_INITIALIZATION_METHOD_CALL@ # endif #endif #ifdef CTK_WRAP_PYTHONQT_USE_VTK this->addWrapperFactory(new ctkVTKPythonQtWrapperFactory); #endif // Register decorators this->registerPythonQtDecorator(new ctkSimplePythonQtDecorators(this)); // Add object to python interpreter context this->addObjectToPythonMain("_ctkSimplePythonShellInstance", qApp); } //----------------------------------------------------------------------------- void ctkSimplePythonManager::executeInitializationScripts() { QString self_dir = QFileInfo(qApp->applicationFilePath()).absolutePath(); QString initFile = self_dir; #if defined(CMAKE_INTDIR) initFile.append("/.."); #endif initFile.append("/Python/ctkSimplePythonShell.py"); Q_ASSERT(QFile::exists(initFile)); // Evaluate application script this->executeFile(initFile); } ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkSimplePythonManager.h000066400000000000000000000023461524622605700262670ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkSimplePythonManager_h #define __ctkSimplePythonManager_h // CTK includes # include class PythonQtObjectPtr; class ctkSimplePythonManager : public ctkAbstractPythonManager { Q_OBJECT public: typedef ctkAbstractPythonManager Superclass; ctkSimplePythonManager(QObject* parent=0); ~ctkSimplePythonManager(); protected: virtual QStringList pythonPaths(); virtual void preInitialization(); virtual void executeInitializationScripts(); }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkSimplePythonQtDecorators.h000066400000000000000000000024611524622605700273250ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkSimplePythonQtDecorators_h #define __ctkSimplePythonQtDecorators_h // PythonQt includes #include // CTK includes #include // NOTE: // // For decorators it is assumed that the methods will never be called // with the self argument as NULL. The self argument is the first argument // for non-static methods. // class ctkSimplePythonQtDecorators : public QObject { Q_OBJECT public: ctkSimplePythonQtDecorators(ctkAbstractPythonManager* pythonManager) { Q_UNUSED(pythonManager); } public Q_SLOTS: }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkSimplePythonShellConfigure.h.in000066400000000000000000000006571524622605700302360ustar00rootroot00000000000000#ifndef __ctkSimplePythonShellConfigure_h #define __ctkSimplePythonShellConfigure_h /// /// Here is where system computed values get stored /// #cmakedefine CTK_BUILD_SHARED_LIBS #cmakedefine CTK_WRAP_PYTHONQT_LIGHT //#define CTK_PYTHON_LIBRARY_DIR_BUILD "@LIBRARY_OUTPUT_DIRECTORY@" #cmakedefine CTK_WRAP_PYTHONQT_USE_VTK #ifdef CTK_WRAP_PYTHONQT_USE_VTK # define VTK_PYTHON_LIBRARY_DIR_BUILD "@VTK_DIR@/bin" #endif #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkSimplePythonShellMain.cpp000066400000000000000000000144361524622605700271270ustar00rootroot00000000000000/*========================================================================= 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 #include #include #include #include #include // CTK includes #include #include #include #include "ctkSimplePythonManager.h" #include "ctkTestWrappedQProperty.h" #include "ctkTestWrappedQInvokable.h" #include "ctkTestWrappedSlot.h" #include "ctkSimplePythonShellConfigure.h" // For CTK_WRAP_PYTHONQT_USE_VTK #ifdef CTK_WRAP_PYTHONQT_USE_VTK # include "ctkTestWrappedQListOfVTKObject.h" # include "ctkTestWrappedVTKObserver.h" # include "ctkTestWrappedVTKQInvokable.h" # include "ctkTestWrappedVTKSlot.h" # include #endif namespace { //----------------------------------------------------------------------------- void executeScripts(void * data) { ctkSimplePythonManager * pythonManager = reinterpret_cast(data); QStringList scripts = pythonManager->property("scripts").toStringList(); foreach(const QString& script, scripts) { pythonManager->executeFile(script); if (pythonManager->pythonErrorOccured()) { QApplication::exit(EXIT_FAILURE); } } } //----------------------------------------------------------------------------- void onCursorPositionChanged(void *data) { ctkPythonConsole* pythonConsole = reinterpret_cast(data); QMainWindow* mainWindow = qobject_cast( pythonConsole->parentWidget()); QLabel * label = mainWindow->statusBar()->findChild(); label->setText(QString("Position %1, Column %2, Line %3") .arg(pythonConsole->cursorPosition()) .arg(pythonConsole->cursorColumn()) .arg(pythonConsole->cursorLine())); } } // end of anonymous namespace //----------------------------------------------------------------------------- int main(int argc, char** argv) { #ifdef CTK_WRAP_PYTHONQT_USE_VTK vtkDebugLeaks::SetExitError(true); ctkTestWrappedVTKObserver testWrappedVTKObserver; #endif int exitCode = EXIT_FAILURE; { QApplication app(argc, argv); ctkCommandLineParser parser; // Use Unix-style argument names parser.setArgumentPrefix("--", "-"); // Add command line argument names parser.addArgument("help", "h", QVariant::Bool, "Print usage information and exit."); parser.addArgument("interactive", "I", QVariant::Bool, "Enable interactive mode"); // Parse the command line arguments bool ok = false; QHash parsedArgs = parser.parseArguments(QCoreApplication::arguments(), &ok); if (!ok) { QTextStream(stderr, QIODevice::WriteOnly) << "Error parsing arguments: " << parser.errorString() << "\n"; return EXIT_FAILURE; } // Show a help message if (parsedArgs.contains("help") || parsedArgs.contains("h")) { QTextStream(stdout, QIODevice::WriteOnly) << "ctkSimplePythonShell\n" << "Usage\n\n" << " ctkSimplePythonShell [options] [ ...]\n\n" << "Options\n" << parser.helpText(); return EXIT_SUCCESS; } ctkSimplePythonManager pythonManager; ctkPythonConsole console; console.initialize(&pythonManager); QMainWindow * mainWindow = new QMainWindow(); mainWindow->setCentralWidget(&console); mainWindow->resize(600, 280); mainWindow->show(); QLabel cursorPositionLabel; mainWindow->statusBar()->addWidget(&cursorPositionLabel); ctkCallback cursorPositionChangedCallback; cursorPositionChangedCallback.setCallbackData(&console); cursorPositionChangedCallback.setCallback(onCursorPositionChanged); QObject::connect(&console, SIGNAL(cursorPositionChanged()), &cursorPositionChangedCallback, SLOT(invoke())); console.setProperty("isInteractive", parsedArgs.contains("interactive")); QStringList list; list << "qt.QPushButton"; console.completer()->setAutocompletePreferenceList(list); pythonManager.addObjectToPythonMain("_ctkPythonConsoleInstance", &console); pythonManager.addObjectToPythonMain("_ctkPythonManagerInstance", &pythonManager); ctkTestWrappedQProperty testWrappedQProperty; pythonManager.addObjectToPythonMain("_testWrappedQPropertyInstance", &testWrappedQProperty); ctkTestWrappedQInvokable testWrappedQInvokable; pythonManager.addObjectToPythonMain("_testWrappedQInvokableInstance", &testWrappedQInvokable); ctkTestWrappedSlot testWrappedSlot; pythonManager.addObjectToPythonMain("_testWrappedSlotInstance", &testWrappedSlot); #ifdef CTK_WRAP_PYTHONQT_USE_VTK pythonManager.addObjectToPythonMain("_testWrappedVTKObserverInstance", &testWrappedVTKObserver); ctkTestWrappedVTKQInvokable testWrappedVTKQInvokable; pythonManager.addObjectToPythonMain("_testWrappedVTKQInvokableInstance", &testWrappedVTKQInvokable); ctkTestWrappedVTKSlot testWrappedVTKSlot; pythonManager.addObjectToPythonMain("_testWrappedVTKSlotInstance", &testWrappedVTKSlot); // ctkTestWrappedQListOfVTKObject testWrappedQListOfVTKObject; // pythonManager.addObjectToPythonMain("_testWrappedQListOfVTKObjectInstance", &testWrappedQListOfVTKObject); #endif ctkCallback callback; callback.setCallbackData(&pythonManager); pythonManager.setProperty("scripts", parser.unparsedArguments()); callback.setCallback(executeScripts); QTimer::singleShot(0, &callback, SLOT(invoke())); exitCode = app.exec(); } #ifdef CTK_WRAP_PYTHONQT_USE_VTK testWrappedVTKObserver.getTable()->Modified(); #endif return exitCode; } ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkTestWrappedQInvokable.h000066400000000000000000000023401524622605700265510ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkTestWrappedQInvokable_h #define __ctkTestWrappedQInvokable_h // Qt includes #include class ctkTestWrappedQInvokable : public QObject { Q_OBJECT public: ctkTestWrappedQInvokable(QObject * newParent = 0) : QObject(newParent) { this->Value = 0; } /// Example of method wrapped using Q_INVOKABLE Q_INVOKABLE int value() const { return this->Value; } Q_INVOKABLE void setValue(int newValue){ this->Value = newValue; } private: int Value; }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkTestWrappedQListOfVTKObject.h000066400000000000000000000023751524622605700275630ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkTestWrappedQListOfVTKObject_h #define __ctkTestWrappedQListOfVTKObject_h // Qt includes #include #include // VTK includes #include class ctkTestWrappedQListOfVTKObject : public QObject { Q_OBJECT public: ctkTestWrappedQListOfVTKObject(QObject * newParent = 0) : QObject(newParent) { } /// Example of slot accepting a VTK object as parameter Q_INVOKABLE int numberOfElementInList(const QList& listOfTable) { return listOfTable.count(); } }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkTestWrappedQProperty.h000066400000000000000000000025261524622605700264710ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkTestWrappedQProperty_h #define __ctkTestWrappedQProperty_h // Qt includes #include class ctkTestWrappedQProperty : public QObject { Q_OBJECT Q_PROPERTY(int value READ value WRITE setValue); public: ctkTestWrappedQProperty(QObject * newParent = 0) : QObject(newParent) { this->Value = 0; } /// Example of property declared using Q_PROPERTY /// Using Q_PROPERTY is enough to expose them, it's not required to declare them as slot int value() const { return this->Value; } void setValue(int newValue){ this->Value = newValue; } private: int Value; }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkTestWrappedSlot.h000066400000000000000000000022201524622605700254340ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkTestWrappedSlot_h #define __ctkTestWrappedSlot_h // Qt includes #include class ctkTestWrappedSlot : public QObject { Q_OBJECT public: ctkTestWrappedSlot(QObject * newParent = 0) : QObject(newParent) { this->Value = 0; } public Q_SLOTS: int value() const { return this->Value; } void setValue(int newValue){ this->Value = newValue; } private: int Value; }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkTestWrappedVTKObserver.h000066400000000000000000000025241524622605700266760ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkTestWrappedVTKObserver_h #define __ctkTestWrappedVTKObserver_h // Qt includes #include // VTK includes #include #include class ctkTestWrappedVTKObserver : public QObject { Q_OBJECT public: ctkTestWrappedVTKObserver(QObject * newParent = 0) : QObject(newParent) { this->MyTable = vtkSmartPointer::New(); } virtual ~ctkTestWrappedVTKObserver() { } public Q_SLOTS: /// Example of slot returning a VTK object vtkTable* getTable() const { return this->MyTable; } private: vtkSmartPointer MyTable; }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkTestWrappedVTKQInvokable.h000066400000000000000000000032671524622605700271470ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkTestWrappedVTKQInvokable_h #define __ctkTestWrappedVTKQInvokable_h // Qt includes #include // VTK includes #include #include class ctkTestWrappedVTKQInvokable : public QObject { Q_OBJECT public: ctkTestWrappedVTKQInvokable(QObject * newParent = 0) : QObject(newParent) { this->MyTable = vtkSmartPointer::New(); } virtual ~ctkTestWrappedVTKQInvokable() { } /// Example of 'invokable' returning a VTK object /// Declaring a method as invokable allows to add it to the MetaObject system /// \note When a method returns a value, we tend to use Q_INVOKABLE /// instead of declaring a slot. Q_INVOKABLE vtkTable * getTable() const { return this->MyTable; } /// Example of 'invokable' accepting a VTK object as parameter Q_INVOKABLE void setTable(vtkTable * newTable) { this->MyTable = newTable; } private: vtkSmartPointer MyTable; }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/ctkTestWrappedVTKSlot.h000066400000000000000000000027061524622605700260320ustar00rootroot00000000000000/*========================================================================= 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. =========================================================================*/ #ifndef __ctkTestWrappedVTKSlot_h #define __ctkTestWrappedVTKSlot_h // Qt includes #include // VTK includes #include #include class ctkTestWrappedVTKSlot : public QObject { Q_OBJECT public: ctkTestWrappedVTKSlot(QObject * newParent = 0) : QObject(newParent) { this->MyTable = vtkSmartPointer::New(); } virtual ~ctkTestWrappedVTKSlot() { } public Q_SLOTS: /// Example of slot returning a VTK object vtkTable* getTable() const { return this->MyTable; } /// Example of slot accepting a VTK object as parameter void setTable(vtkTable * newTable) { this->MyTable = newTable; } private: vtkSmartPointer MyTable; }; #endif ctk-2026.09.02/Applications/ctkSimplePythonShell/target_libraries.cmake000066400000000000000000000003011524622605700257770ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKScriptingPythonWidgets ) ctk-2026.09.02/Applications/ctkXnatTreeBrowser/000077500000000000000000000000001524622605700211345ustar00rootroot00000000000000ctk-2026.09.02/Applications/ctkXnatTreeBrowser/CMakeLists.txt000066400000000000000000000012661524622605700237010ustar00rootroot00000000000000project(ctkXnatTreeBrowser) # # See CTK/CMake/ctkMacroBuildApp.cmake for details # set(KIT_SRCS ctkXnatTreeBrowserMain.cpp ctkXnatTreeBrowserMainWindow.cpp ) # UI files set(KIT_UI_FORMS ctkXnatTreeBrowserMainWindow.ui ) # Resources set(KIT_resources ) # Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake # The following macro will read the target libraries from the file 'target_libraries.cmake' ctkFunctionGetTargetLibraries(KIT_target_libraries) ctkMacroBuildApp( NAME ${PROJECT_NAME} SRCS ${KIT_SRCS} UI_FORMS ${KIT_UI_FORMS} TARGET_LIBRARIES ${KIT_target_libraries} RESOURCES ${KIT_resources} ) target_link_libraries(${PROJECT_NAME} ${QT_LIBRARIES}) ctk-2026.09.02/Applications/ctkXnatTreeBrowser/ctkXnatTreeBrowserMain.cpp000066400000000000000000000021741524622605700262510ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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 #include "ctkXnatTreeBrowserMainWindow.h" int main(int argc, char** argv) { QApplication myApp(argc, argv); myApp.setOrganizationName("CommonTK"); myApp.setApplicationName("XnatTreeBrowser"); ctkXnatTreeBrowserMainWindow mainWindow; mainWindow.show(); return myApp.exec(); } ctk-2026.09.02/Applications/ctkXnatTreeBrowser/ctkXnatTreeBrowserMainWindow.cpp000066400000000000000000000164301524622605700274410ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #include "ctkXnatTreeBrowserMainWindow.h" #include "ui_ctkXnatTreeBrowserMainWindow.h" #include "ctkXnatAssessor.h" #include "ctkXnatAssessorFolder.h" #include "ctkXnatDataModel.h" #include "ctkXnatException.h" #include "ctkXnatExperiment.h" #include "ctkXnatFile.h" #include "ctkXnatLoginDialog.h" #include "ctkXnatProject.h" #include "ctkXnatReconstruction.h" #include "ctkXnatReconstructionFolder.h" #include "ctkXnatResource.h" #include "ctkXnatResourceFolder.h" #include "ctkXnatScan.h" #include "ctkXnatScanFolder.h" #include "ctkXnatSession.h" #include "ctkXnatSubject.h" #include "ctkXnatTreeModel.h" #include #include #include #include #include #include ctkXnatTreeBrowserMainWindow::ctkXnatTreeBrowserMainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::ctkXnatTreeBrowserMainWindow), m_Session(0), m_TreeModel(new ctkXnatTreeModel()) { ui->setupUi(this); ui->treeView->setModel(m_TreeModel); ui->downloadLabel->hide(); ui->treeView->setHeaderHidden(true); this->connect(ui->loginButton, SIGNAL(clicked()), SLOT(loginButtonPushed())); this->connect(ui->treeView, SIGNAL(clicked(const QModelIndex&)), SLOT(itemSelected(const QModelIndex&))); this->connect(ui->downloadButton, SIGNAL(clicked()), SLOT(downloadButtonClicked())); this->connect(ui->addResourceButton, SIGNAL(clicked()), SLOT(addResourceClicked())); this->connect(ui->uploadFileButton, SIGNAL(clicked()), SLOT(uploadFileClicked())); } ctkXnatTreeBrowserMainWindow::~ctkXnatTreeBrowserMainWindow() { if (m_Session) { delete m_Session; } delete ui; delete m_TreeModel; } void ctkXnatTreeBrowserMainWindow::loginButtonPushed() { if (m_Session) { ctkXnatDataModel* dataModel = m_Session->dataModel(); m_TreeModel->removeDataModel(dataModel); ui->treeView->reset(); delete m_Session; m_Session = 0; ui->loginButton->setText(tr("Login")); ui->loginLabel->setText(tr("Disconnected")); ui->downloadLabel->hide(); } else { ctkXnatLoginDialog loginDialog; if (loginDialog.exec() == QDialog::Accepted) { m_Session = loginDialog.session(); if (m_Session) { ui->loginButton->setText(tr("Logout")); ui->loginLabel->setText(tr("Connected: %1").arg(m_Session->url().toString())); this->connect(m_Session, SIGNAL(timedOut()), this, SLOT(sessionTimedOutMsg())); this->connect(m_Session, SIGNAL(aboutToTimeOut()), this, SLOT(sessionAboutToTimeOutMsg())); ctkXnatDataModel* dataModel = m_Session->dataModel(); m_TreeModel->addDataModel(dataModel); ui->treeView->reset(); ui->downloadLabel->show(); } } } } void ctkXnatTreeBrowserMainWindow::itemSelected(const QModelIndex &index) { ctkXnatObject* xnatObject = m_TreeModel->xnatObject(index); bool downloadable = false; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; downloadable |= dynamic_cast(xnatObject)!=NULL; ui->downloadButton->setEnabled(downloadable); ui->downloadLabel->setVisible(!downloadable); bool canHaveResource = false; canHaveResource |= dynamic_cast(xnatObject) != NULL; canHaveResource |= dynamic_cast(xnatObject) != NULL; canHaveResource |= dynamic_cast(xnatObject) != NULL; ui->addResourceButton->setEnabled(canHaveResource); bool uploadFilePossible = false; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; ui->uploadFileButton->setEnabled(uploadFilePossible); } void ctkXnatTreeBrowserMainWindow::downloadButtonClicked() { const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); QVariant variant = m_TreeModel->data(index, Qt::DisplayRole); QString fileName = variant.value(); if ( fileName.length() != 0 ) { m_TreeModel->downloadFile(index, fileName); } } void ctkXnatTreeBrowserMainWindow::addResourceClicked() { const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); ctkXnatObject* parentObject = m_TreeModel->xnatObject(index); parentObject->addResourceFolder("data"); m_TreeModel->refresh(index); } void ctkXnatTreeBrowserMainWindow::uploadFileClicked() { QString filename = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::homePath()); const QModelIndex index = ui->treeView->selectionModel()->currentIndex(); ctkXnatResource* resource = dynamic_cast(m_TreeModel->xnatObject(index)); if (resource) { ctkXnatFile* file = new ctkXnatFile(); file->setLocalFilePath(filename); QFileInfo fileInfo (filename); file->setName(fileInfo.fileName()); resource->add(file); try { file->save(); } catch (ctkXnatException &e) { QMessageBox msgbox; msgbox.setText(e.what()); msgbox.setIcon(QMessageBox::Critical); msgbox.exec(); } m_TreeModel->addChildNode(index, file); } } void ctkXnatTreeBrowserMainWindow::sessionTimedOutMsg() { ctkXnatDataModel* dataModel = m_Session->dataModel(); m_TreeModel->removeDataModel(dataModel); ui->treeView->reset(); delete m_Session; m_Session = 0; ui->loginButton->setText(tr("Login")); ui->loginLabel->setText(tr("Disconnected")); ui->downloadLabel->hide(); QMessageBox::warning(this, tr("Session Timeout"), tr("The session timed out.")); } void ctkXnatTreeBrowserMainWindow::sessionAboutToTimeOutMsg() { QMessageBox msgBox; msgBox.setIcon(QMessageBox::Warning); msgBox.setWindowTitle(tr("Session Timeout Soon")); msgBox.setText(tr("The session will time out in 1 minute.\nDo you want to renew the session?")); msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); msgBox.show(); QTimer* timer = new QTimer(this); timer->start(60000); this->connect(timer, SIGNAL(timeout()), &msgBox, SLOT(reject())); if (msgBox.exec() == QMessageBox::Yes) { m_Session->renew(); } timer->stop(); } ctk-2026.09.02/Applications/ctkXnatTreeBrowser/ctkXnatTreeBrowserMainWindow.h000066400000000000000000000030561524622605700271060ustar00rootroot00000000000000/*============================================================================= Library: CTK Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics 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 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. =============================================================================*/ #ifndef CTKXNATTREEBROWSERMAINWINDOW_H #define CTKXNATTREEBROWSERMAINWINDOW_H #include class QModelIndex; class ctkXnatSession; class ctkXnatTreeModel; namespace Ui { class ctkXnatTreeBrowserMainWindow; } class ctkXnatTreeBrowserMainWindow : public QMainWindow { Q_OBJECT public: explicit ctkXnatTreeBrowserMainWindow(QWidget *parent = 0); ~ctkXnatTreeBrowserMainWindow(); private Q_SLOTS: void loginButtonPushed(); void itemSelected(const QModelIndex&); void downloadButtonClicked(); void addResourceClicked(); void uploadFileClicked(); void sessionTimedOutMsg(); void sessionAboutToTimeOutMsg(); private: Ui::ctkXnatTreeBrowserMainWindow* ui; ctkXnatSession* m_Session; ctkXnatTreeModel* m_TreeModel; }; #endif ctk-2026.09.02/Applications/ctkXnatTreeBrowser/ctkXnatTreeBrowserMainWindow.ui000066400000000000000000000065331524622605700272770ustar00rootroot00000000000000 ctkXnatTreeBrowserMainWindow 0 0 553 325 MainWindow Login false Creates a new resource folder Add Resource false Upload File false Download 0 0 Not connected Details Select a xnat file, resource, scan, or scan folder to download... 0 0 553 22 &File &Quit ctk-2026.09.02/Applications/ctkXnatTreeBrowser/target_libraries.cmake000066400000000000000000000002661524622605700254640ustar00rootroot00000000000000# # See CMake/ctkFunctionGetTargetLibraries.cmake # # This file should list the libraries required to build the current CTK application. # set(target_libraries CTKXNATWidgets ) ctk-2026.09.02/CMake/000077500000000000000000000000001524622605700136665ustar00rootroot00000000000000ctk-2026.09.02/CMake/CTKConfig.cmake.in000066400000000000000000000122241524622605700170450ustar00rootroot00000000000000 # # CTKConfig.cmake - CTK CMake configuration file for external projects. # # This file is configured by CTK and used by the UseCTK.cmake module # to load CTK's settings for an external project. if(CMAKE_VERSION VERSION_LESS 3.0.0) message(FATAL_ERROR "CTK requires at least CMake version 3.0.0") endif() @PACKAGE_INIT@ # Help finding external projects which might have been # installed with CTK in the same install location list(APPEND CMAKE_PREFIX_PATH ${PACKAGE_PREFIX_DIR}) # CMake extension module directory set_and_check(CTK_CMAKE_DIR "@PACKAGE_CTK_CMAKE_DIR_CONFIG@") set_and_check(CTK_CMAKE_UTILITIES_DIR "@PACKAGE_CTK_CMAKE_UTILITIES_DIR_CONFIG@") # The location of the UseCTK.cmake file. set_and_check(CTK_USE_FILE "@PACKAGE_CTK_CONFIG_DIR_CONFIG@/UseCTK.cmake") # Include CTK Plugin specific variables set_and_check(CTK_PLUGIN_USE_FILE "@PACKAGE_CTK_CONFIG_DIR_CONFIG@/CTKPluginUseFile.cmake") set_and_check(CTK_TARGETS "@PACKAGE_CTK_CONFIG_DIR_CONFIG@/CTKExports.cmake") # Directory containing the ctkConfig.h file set_and_check(CTK_CONFIG_H_INCLUDE_DIR "@PACKAGE_CTK_CONFIG_H_INCLUDE_DIR_CONFIG@") # Set the header template which defines custom export/import macros # for shared libraries set_and_check(CTK_EXPORT_HEADER_TEMPLATE "@PACKAGE_CTK_EXPORT_HEADER_TEMPLATE_DIR_CONFIG@/ctkExport.h.in") # Set CTK library directory set_and_check(CTK_LIBRARY_DIR "@PACKAGE_CTK_LIBRARY_DIR_CONFIG@") set(CTK_LIBRARY_DIRS ${CTK_LIBRARY_DIR}) # CTK specific variables set(CTK_CMAKE_DEBUG_POSTFIX "@CMAKE_DEBUG_POSTFIX@") set(CTK_COMPILE_PYTHON_SCRIPT_SKIP_SCRIPT_COPY "@CTK_COMPILE_PYTHON_SCRIPT_SKIP_SCRIPT_COPY@") # Import CTK targets if(NOT TARGET CTKCore) include(${CTK_TARGETS}) endif() @CTK_CONFIG_CODE@ # Include CTK macros include("${CTK_CMAKE_DIR}/ctkFunctionGetGccVersion.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionCheckCompilerFlags.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGetCompilerVisibilityFlags.cmake") include("${CTK_CMAKE_DIR}/ctkMacroParseArguments.cmake") include("${CTK_CMAKE_DIR}/ctkMacroSetPaths.cmake") include("${CTK_CMAKE_DIR}/ctkMacroListFilter.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionExtractOptimizedLibrary.cmake") include("${CTK_CMAKE_DIR}/ctkMacroBuildLibWrapper.cmake") include("${CTK_CMAKE_DIR}/ctkMacroBuildPlugin.cmake") include("${CTK_CMAKE_DIR}/ctkMacroBuildQtPlugin.cmake") include("${CTK_CMAKE_DIR}/ctkMacroTargetLibraries.cmake") # Import multiple macros include("${CTK_CMAKE_DIR}/ctkFunctionExtractOptionNameAndValue.cmake") include("${CTK_CMAKE_DIR}/ctkMacroValidateBuildOptions.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGenerateDGraphInput.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGetIncludeDirs.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGetLibraryDirs.cmake") include("${CTK_CMAKE_DIR}/ctkMacroGenerateMocs.cmake") # PluginFramework include("${CTK_CMAKE_DIR}/ctkFunctionGeneratePluginManifest.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGeneratePluginUseFile.cmake") include("${CTK_CMAKE_DIR}/ctkMacroGeneratePluginResourceFile.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionExtractPluginTargets.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGetAllPluginTargets.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGetTargetDependencies.cmake") include("${CTK_CMAKE_DIR}/ctkFunctionGetPluginDependencies.cmake") include("${CTK_CMAKE_DIR}/ctkMacroSetupPlugins.cmake") include(CMakeFindDependencyMacro) # List all libraries SET(CTK_LIBRARIES @CTK_LIBRARIES@) # List all CTK libraries wrapped with PythonQt SET(CTK_WRAPPED_LIBRARIES_PYTHONQT @CTK_WRAPPED_LIBRARIES_PYTHONQT@) # Include CTK Plugin specific variables include(${CTK_PLUGIN_USE_FILE}) # Qt configuration set(CTK_QT_VERSION "@CTK_QT_VERSION@") set(CTK_QT_COMPONENTS @CTK_QT_COMPONENTS@) # Update CMake module path so that calling "find_package(DCMTK)" works as expected # after calling "find_package(CTK)" # Ideally projects like DCMTK or PythonQt should provide both "Config" and "Use" files. set(CMAKE_MODULE_PATH ${CTK_CMAKE_UTILITIES_DIR} ${CMAKE_MODULE_PATH} ) # Relative install paths set(CTK_INSTALL_BIN_DIR "@CTK_INSTALL_BIN_DIR@") set(CTK_INSTALL_INCLUDE_DIR "@CTK_INSTALL_INCLUDE_DIR@") set(CTK_INSTALL_LIB_DIR "@CTK_INSTALL_LIB_DIR@") set(CTK_INSTALL_PLUGIN_INCLUDE_DIR "@CTK_INSTALL_PLUGIN_INCLUDE_DIR@") set(CTK_INSTALL_PLUGIN_DIR "@CTK_INSTALL_PLUGIN_DIR@") set(CTK_INSTALL_QTPLUGIN_DIR "@CTK_INSTALL_QTPLUGIN_DIR@") # A CTK install tree always provides one build configuration. A CTK # build tree may provide either one or multiple build configurations # depending on the CMake generator used. Since CTK can be used either # from a build tree or an install tree it is useful for outside # projects to know the configurations available. If this # CTKConfig.cmake is in a CTK install tree CTK_CONFIGURATION_TYPES # will be empty and CTK_BUILD_TYPE will be set to the value of # CMAKE_BUILD_TYPE used to build CTK. If CTKConfig.cmake is in a CTK # build tree then CTK_CONFIGURATION_TYPES and CTK_BUILD_TYPE will have # values matching CMAKE_CONFIGURATION_TYPES and CMAKE_BUILD_TYPE for # that build tree (only one will ever be set). SET(CTK_CONFIGURATION_TYPES @CTK_CONFIGURATION_TYPES_CONFIG@) SET(CTK_BUILD_TYPE @CTK_BUILD_TYPE_CONFIG@) # CTK external projects variables @CTK_SUPERBUILD_EP_VARS_CONFIG@ ctk-2026.09.02/CMake/CTKPluginUseFile.cmake.in000066400000000000000000000006471524622605700203610ustar00rootroot00000000000000# List all plugins set(@_ctk_plugin_libraries_variable@ @_ctk_plugin_libraries@) if(NOT @_ctk_plugin_libraries_variable@_set) set_property(GLOBAL APPEND PROPERTY CTK_PLUGIN_LIBRARIES_VARS @_ctk_plugin_libraries_variable@) set(@_ctk_plugin_libraries_variable@_set 1) endif() # Plugin specific include directories @CTK_PLUGIN_INCLUDE_DIRS_CONFIG@ # Plugin specific library directories @CTK_PLUGIN_LIBRARY_DIRS_CONFIG@ ctk-2026.09.02/CMake/CTKValgrind.supp000066400000000000000000000010751524622605700167120ustar00rootroot00000000000000{ fsetpos when used in ctkFDHandler Memcheck:Param lseek(offset) obj:/lib/x86_64-linux-gnu/libc-2.21.so fun:_IO_file_seekoff@@GLIBC_2.2.5 fun:fsetpos@@GLIBC_2.2.5 fun:_ZN12ctkFDHandler10setEnabledEb fun:_ZN27ctkErrorLogFDMessageHandler18setEnabledInternalEb fun:_ZN33ctkErrorLogAbstractMessageHandler10setEnabledEb fun:_ZN23ctkErrorLogModelPrivateD1Ev fun:_ZN16ctkErrorLogModelD1Ev fun:_ZN16ctkErrorLogModelD0Ev fun:_ZN25qSlicerApplicationPrivateD1Ev fun:_ZN25qSlicerApplicationPrivateD0Ev fun:_ZN22qSlicerCoreApplicationD1Ev } ctk-2026.09.02/CMake/CTestCustom.cmake.in000066400000000000000000000046411524622605700175170ustar00rootroot00000000000000SET(CTEST_CUSTOM_COVERAGE_EXCLUDE ${CTEST_CUSTOM_COVERAGE_EXCLUDE} # Exclude try_compile sources from coverage results: "/CMakeFiles/CMakeTmp/" # Exclude files generated by the moc pre-compiler ".*/moc_.*" # Exclude files generated by the uic pre-compiler ".*/ui_.*" # Exclude files from the Testing directories ".*/Testing/.*" ".*/CMakeExternals/.*" "./ctkPixmapIconEngine.*" "./ctkIconEngine.*" ) # The following tests should not be run under valgrind SET(CTEST_CUSTOM_MEMCHECK_IGNORE ) SET(CTEST_CUSTOM_ERROR_MATCH ${CTEST_CUSTOM_ERROR_MATCH} "CMake Error[ :]" ) SET(CTEST_CUSTOM_WARNING_MATCH ${CTEST_CUSTOM_WARNING_MATCH} "CMake Warning[ :]" ) SET(CTEST_CUSTOM_WARNING_EXCEPTION ${CTEST_CUSTOM_WARNING_EXCEPTION} # kwstyle suppressions "[Kk][Ww][Ss]tyle.*kws.*cxx" "[Kk][Ww][Ss]tyle.*kws.*h" "[Kk][Ww][Ss]tyle.*metaCommand.*cxx" # Log4Qt suppressions "[Ll]og4[Qq]t.*src.*log4qt" "logobjectptr.*obj : warning" # vtk suppressions "vtkfreetype" "Utilities.vtktiff" "VTK.*IO.vtkMySQLQuery.cxx" "VTK.*Utilities.vtkexodus2" "VTK.*Utilities.vtklibproj" "VTK.*Utilities.vtksqlite" "VTK.*Utilities.vtkmetaio" "VTK.*warn_unused_result" "VTK.*Filtering.*cxx" "VTK.*IO.*cxx" "VTK.*Infovis.*cxx" # qt suppressions from vtk... # Some VTK dashboards include building bits of Qt which produce lots of # the following warnings when built with the MS compilers. Qt guys should # fix their code. Until they do, keep the Qt chatter off the VTK dashboard # results: "include.[Qq]t([Cc]ore|[Gg]ui).*warning C4127: conditional expression is constant" "[Qq]t.*h.*warning.*declaration of .* shadows a member of .this" "[Qq]t.*h.*warning.*(copy constructor|assignment operator) could not be generated" # Suppress warning caused when QT 'foreach' loops are combined ".*warning: declaration of '_container_' shadows a previous local" # PythonQt suppressions "PythonQt.*src.*PythonQt.*(cpp|h)" "include.PythonQt.PythonQt.*h" # Suppressing warnings about duplicate libraries in Darwin # At some point this may be addressed by CMake feature request: # http://public.kitware.com/Bug/view.php?id=10179 "ld: warning: duplicate dylib.*" # Visual studio spurious warnings... "The following environment variables were not found" # External projects not using $(MAKE) properly "warning: jobserver unavailable: using -j1. Add `+' to parent make rule." ) ctk-2026.09.02/CMake/LastConfigureStep/000077500000000000000000000000001524622605700172675ustar00rootroot00000000000000ctk-2026.09.02/CMake/LastConfigureStep/CMakeLists.txt000066400000000000000000000067651524622605700220450ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### ########################################################################### # # Program: Visualization Toolkit # Module: Utilities/LastConfigureStep/CMakeLists.txt # # Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen # # All rights reserved. # See Copyright.txt or http://www.kitware.com/Copyright.htm for details. # # This software is distributed WITHOUT ANY WARRANTY; without even # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the above copyright notice for more information. # ########################################################################### # The commands in this directory are intended to be executed at # the end of the whole configuration process, as a "last step". # This directory is typically the last SUBDIRS in the main CMakeLists.txt. # It enable the above commands to use variables that might have been configured # in previous SUBDIRS. This is especially important when it comes to # the CONFIGURE_FILE command, since in IMMEDIATE mode that command will # use the current values of CMake variables instead of waiting until the # end of CMakeLists processing, i.e. instead of waiting until some variables # are configured in SUBDIRS. set(ctk_target_dependencies) # Loop over the list of CTK* targets and retrieve the associated dependencies foreach(ctk_target ${CTEST_PROJECT_SUBPROJECTS}) list(APPEND ctk_target_dependencies ${${ctk_target}_LIB_DEPENDS}) endforeach() set(CTK_EXTERNAL_LIBRARIES) # Loop over dependencies and append to CTK_EXTERNAL_LIBRARIES # target dependency which are neither CTK or static library set(link_type) foreach(ctk_target_dependency ${ctk_target_dependencies}) string(REGEX MATCH "^(general|optimized|debug)$" is_link_type ${ctk_target_dependency}) if(is_link_type) set(link_type ${ctk_target_dependency}) else() # Sanity checks - link_type shouldn't be empty if(link_type STREQUAL "") message(SEND_ERROR "link_type shouldn't be empty") endif() # Make sure ctk_target_dependency is not a CTK library string(REGEX MATCH "(^(c|C)(t|T)(k|K)[a-zA-Z0-9]+$)" is_ctk_library ${ctk_target_dependency}) if(NOT is_ctk_library) # Make sure ctk_target_dependency is not a static library get_filename_component(ctk_target_dependency_ext ${ctk_target_dependency} EXT) if(NOT ctk_target_dependency_ext STREQUAL CMAKE_STATIC_LIBRARY_SUFFIX) list(APPEND CTK_EXTERNAL_LIBRARIES ${link_type} ${ctk_target_dependency}) endif() set(link_type) endif() endif() endforeach() #----------------------------------------------------------------------------- # Create the CTKConfig.cmake file containing the CTK configuration. # Since it might generate configuration file depending include(CTKGenerateCTKConfig.cmake) ctk-2026.09.02/CMake/LastConfigureStep/CTKGenerateCTKConfig.cmake000066400000000000000000000251351524622605700240630ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### ########################################################################### # # Program: Visualization Toolkit # Module: vtkGenerateVTKConfig.cmake # # Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen # # All rights reserved. # See Copyright.txt or http://www.kitware.com/Copyright.htm for details. # # This software is distributed WITHOUT ANY WARRANTY; without even # the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR # PURPOSE. See the above copyright notice for more information. # ########################################################################### # # Generate the CTKConfig.cmake file in the build tree. Also configure # one for installation. The file tells external projects how to use CTK. # include(CMakePackageConfigHelpers) include(ctkFunctionGeneratePluginUseFile) set(CTKTesting_CMAKE_DIR_CONFIG "${CTKTesting_SOURCE_DIR}/CMake") # Plug-in output directory if(WIN32) set(_plugin_output_type "RUNTIME") else() set(_plugin_output_type "LIBRARY") endif() if(DEFINED CTK_PLUGIN_${_plugin_output_type}_OUTPUT_DIRECTORY) if(IS_ABSOLUTE "${CTK_PLUGIN_${_plugin_output_type}_OUTPUT_DIRECTORY}") set(CTK_PLUGIN_LIBRARIES_DIR_CONFIG "${CTK_PLUGIN_${_plugin_output_type}_OUTPUT_DIRECTORY}") else() set(CTK_PLUGIN_LIBRARIES_DIR_CONFIG "${CMAKE_${_plugin_output_type}_OUTPUT_DIRECTORY}/${CTK_PLUGIN_${_plugin_output_type}_OUTPUT_DIRECTORY}") endif() else() set(CTK_PLUGIN_LIBRARIES_DIR_CONFIG "${CMAKE_${_plugin_output_type}_OUTPUT_DIRECTORY}/plugins") endif() # CMake extension module directory. set(CTK_CMAKE_DIR_CONFIG ${CTK_CMAKE_DIR}) set(CTK_CMAKE_UTILITIES_DIR_CONFIG ${CTK_CMAKE_UTILITIES_DIR}) # Build configuration information. set(CTK_CONFIGURATION_TYPES_CONFIG ${CMAKE_CONFIGURATION_TYPES}) set(CTK_BUILD_TYPE_CONFIG ${CMAKE_BUILD_TYPE}) #----------------------------------------------------------------------------- configure_file( ${CTK_SOURCE_DIR}/CMake/ctkConfig.h.in ${CTK_CONFIG_H_INCLUDE_DIR}/ctkConfig.h @ONLY ) install( FILES ${CTK_CONFIG_H_INCLUDE_DIR}/ctkConfig.h DESTINATION ${CTK_INSTALL_INCLUDE_DIR} COMPONENT Development ) #----------------------------------------------------------------------------- # Generate a file containing plugin specific variables set(ctk_plugin_use_file "${CTK_SUPERBUILD_BINARY_DIR}/CTKPluginUseFile.cmake") ctkFunctionGeneratePluginUsefile(${ctk_plugin_use_file}) install( FILES ${ctk_plugin_use_file} DESTINATION ${CTK_INSTALL_CMAKE_DIR} COMPONENT Development ) #----------------------------------------------------------------------------- # Generate list of target to exports set(CTK_TARGETS_TO_EXPORT ${CTK_LIBRARIES} ${CTK_PLUGIN_LIBRARIES}) # Append CTK PythonQt static libraries if(NOT CTK_BUILD_SHARED_LIBS) foreach(lib ${CTK_WRAPPED_LIBRARIES_PYTHONQT}) list(APPEND CTK_TARGETS_TO_EXPORT ${lib}PythonQt) endforeach() endif() # Export targets so they can be imported by a project using CTK # as an external library export(TARGETS ${CTK_TARGETS_TO_EXPORT} FILE ${CTK_SUPERBUILD_BINARY_DIR}/CTKExports.cmake) install(EXPORT CTKExports DESTINATION ${CTK_INSTALL_CMAKE_DIR}) #----------------------------------------------------------------------------- # Configure 'CTKConfig.cmake' for a build tree # CTK external projects variables set(CTK_SUPERBUILD_EP_VARS_CONFIG) foreach(varname ${CTK_EP_LABEL_FIND_PACKAGE_VARS} ${CTK_EP_LABEL_FIND_PACKAGE}) set(CTK_SUPERBUILD_EP_VARS_CONFIG "${CTK_SUPERBUILD_EP_VARS_CONFIG} set(${varname} \"${${varname}}\")") endforeach() foreach(varname ${CTK_EP_LABEL_FIND_PACKAGE}) string(REPLACE "_DIR" "" package_name "${varname}") set(CTK_SUPERBUILD_EP_VARS_CONFIG "${CTK_SUPERBUILD_EP_VARS_CONFIG} find_dependency(${package_name})") endforeach() set(CTK_CONFIG_DIR_CONFIG ${CTK_SUPERBUILD_BINARY_DIR}) set(CTK_CMAKE_DIR_CONFIG ${CTK_CMAKE_DIR}) set(CTK_CMAKE_UTILITIES_DIR_CONFIG ${CTK_CMAKE_UTILITIES_DIR}) set(CTK_CONFIG_H_INCLUDE_DIR_CONFIG ${CTK_CONFIG_H_INCLUDE_DIR}) set(CTK_EXPORT_HEADER_TEMPLATE_DIR_CONFIG ${CTK_SOURCE_DIR}/Libs) set(CTK_LIBRARY_DIR_CONFIG ${CMAKE_LIBRARY_OUTPUT_DIRECTORY}) set(CTK_CONFIG_CODE "####### Expanded from \@CTK_CONFIG_CODE\@ #######\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# The CTK DGraph executable used to compute target dependency graphs\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(CTK_DGRAPH_EXECUTABLE \"${DGraph_EXECUTABLE}\")\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# Qt configuration\n") if(DEFINED Qt5_DIR) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(CTK_Qt5_DIR \"${Qt5_DIR}\")\n") elseif(DEFINED CMAKE_PREFIX_PATH) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(CTK_CMAKE_PREFIX_PATH \"${CMAKE_PREFIX_PATH}\")\n") endif() set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# The CTK Qt designer plugins directory\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(CTK_QTDESIGNERPLUGINS_DIR \"${CMAKE_LIBRARY_OUTPUT_DIRECTORY}\")\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# CTK library include directories\n") set(_include_dirs) foreach(lib ${CTK_LIBRARIES} CTKTesting) set(${lib}_INCLUDE_DIRS ${${lib}_SOURCE_DIR} ${${lib}_BINARY_DIR}) ctkFunctionGetIncludeDirs(${lib}_INCLUDE_DIRS ${lib}) list(APPEND _include_dirs ${${lib}_INCLUDE_DIRS}) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(${lib}_INCLUDE_DIRS \"${${lib}_INCLUDE_DIRS}\")\n") endforeach() # ctkDeprecated.h lives directly under Libs/; build-tree consumers need it on the include path. list(APPEND _include_dirs ${CTK_SOURCE_DIR}/Libs) list(REMOVE_DUPLICATES _include_dirs) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(CTK_INCLUDE_DIRS \"${_include_dirs}\")\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# CTK library directories that could be used for linking\n") foreach(lib ${CTK_LIBRARIES}) set(${lib}_LIBRARY_DIRS "") ctkFunctionGetLibraryDirs(${lib}_LIBRARY_DIRS ${lib}) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(${lib}_LIBRARY_DIRS \"${${lib}_LIBRARY_DIRS}\")\n") endforeach() set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# External project libraries\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(CTK_EXTERNAL_LIBRARIES \"${CTK_EXTERNAL_LIBRARIES}\")\n") if(DEFINED DCMTK_HAVE_CONFIG_H_OPTIONAL AND NOT DCMTK_HAVE_CONFIG_H_OPTIONAL AND TARGET CTKDICOMCore) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# Definition required to build DCMTK dependent libraries\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set_target_properties(CTKDICOMCore PROPERTIES INTERFACE_COMPILE_DEFINITIONS ${DCMTK_DEFINITIONS})\n") endif() set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}##################################################") set(ctk_config ${CTK_SUPERBUILD_BINARY_DIR}/CTKConfig.cmake) configure_package_config_file( ${CMAKE_SOURCE_DIR}/CMake/CTKConfig.cmake.in ${ctk_config} INSTALL_DESTINATION ${CTK_SUPERBUILD_BINARY_DIR} PATH_VARS CTK_CONFIG_DIR_CONFIG CTK_CMAKE_DIR_CONFIG CTK_CMAKE_UTILITIES_DIR_CONFIG CTK_CONFIG_H_INCLUDE_DIR_CONFIG CTK_EXPORT_HEADER_TEMPLATE_DIR_CONFIG CTK_LIBRARY_DIR_CONFIG NO_CHECK_REQUIRED_COMPONENTS_MACRO ) #----------------------------------------------------------------------------- # Configure 'CTKConfig.cmake' for an install tree # CTK external projects. We rely on externally set # _DIR variables or a proper CMAKE_PREFIX_PATH such # that find_dependency/find_package can successfully # find the external project. set(CTK_SUPERBUILD_EP_VARS_CONFIG) foreach(varname ${CTK_EP_LABEL_FIND_PACKAGE}) string(REPLACE "_DIR" "" package_name "${varname}") set(CTK_SUPERBUILD_EP_VARS_CONFIG "${CTK_SUPERBUILD_EP_VARS_CONFIG} find_dependency(${package_name})") endforeach() set(CTK_CONFIG_DIR_CONFIG ${CTK_INSTALL_CMAKE_DIR}) set(CTK_CMAKE_DIR_CONFIG ${CTK_INSTALL_CMAKE_DIR}) set(CTK_CMAKE_UTILITIES_DIR_CONFIG ${CTK_INSTALL_CMAKE_DIR}) set(CTK_CONFIG_H_INCLUDE_DIR_CONFIG ${CTK_INSTALL_INCLUDE_DIR}) set(CTK_EXPORT_HEADER_TEMPLATE_DIR_CONFIG ${CTK_INSTALL_CMAKE_DIR}) set(CTK_LIBRARY_DIR_CONFIG ${CTK_INSTALL_LIB_DIR}) set(CTK_CONFIG_CODE "####### Expanded from \@CTK_CONFIG_CODE\@ #######\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# CTK library include directories\n") foreach(libname ${CTK_LIBRARIES}) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(${libname}_INCLUDE_DIRS \"\${PACKAGE_PREFIX_DIR}/${CTK_INSTALL_INCLUDE_DIR}\")\n") endforeach() set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(CTK_INCLUDE_DIRS \"\${PACKAGE_PREFIX_DIR}/${CTK_INSTALL_INCLUDE_DIR}\")\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# CTK library directories that could be used for linking\n") foreach(lib ${CTK_LIBRARIES}) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set(${lib}_LIBRARY_DIRS \"\")\n") endforeach() if(DEFINED DCMTK_HAVE_CONFIG_H_OPTIONAL AND NOT DCMTK_HAVE_CONFIG_H_OPTIONAL AND TARGET CTKDICOMCore) set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}# Definition required to build DCMTK dependent libraries\n") set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}set_target_properties(CTKDICOMCore PROPERTIES INTERFACE_COMPILE_DEFINITIONS ${DCMTK_DEFINITIONS})\n") endif() set(CTK_CONFIG_CODE "${CTK_CONFIG_CODE}##################################################") set(ctk_install_config ${CMAKE_BINARY_DIR}/CMakeFiles/CTKConfig.cmake) configure_package_config_file( ${CMAKE_SOURCE_DIR}/CMake/CTKConfig.cmake.in ${ctk_install_config} INSTALL_DESTINATION ${CTK_INSTALL_CMAKE_DIR} PATH_VARS CTK_CONFIG_DIR_CONFIG CTK_CMAKE_DIR_CONFIG CTK_CMAKE_UTILITIES_DIR_CONFIG CTK_CONFIG_H_INCLUDE_DIR_CONFIG CTK_EXPORT_HEADER_TEMPLATE_DIR_CONFIG CTK_LIBRARY_DIR_CONFIG NO_CHECK_REQUIRED_COMPONENTS_MACRO ) install( FILES ${ctk_install_config} DESTINATION ${CTK_INSTALL_CMAKE_DIR} COMPONENT Development ) #----------------------------------------------------------------------------- # Configure and install 'CTKConfigVersion.cmake' set(ctk_config_version ${CTK_SUPERBUILD_BINARY_DIR}/CTKConfigVersion.cmake) write_basic_package_version_file( ${ctk_config_version} VERSION ${CTK_MAJOR_VERSION}.${CTK_MINOR_VERSION}.${CTK_PATCH_VERSION} COMPATIBILITY SameMajorVersion ) install( FILES ${ctk_config_version} DESTINATION ${CTK_INSTALL_CMAKE_DIR} COMPONENT Development ) ctk-2026.09.02/CMake/MANIFEST.MF.in000066400000000000000000000000241524622605700157210ustar00rootroot00000000000000@_manifest_content@ ctk-2026.09.02/CMake/Testing/000077500000000000000000000000001524622605700153035ustar00rootroot00000000000000ctk-2026.09.02/CMake/Testing/CMakeLists.txt000066400000000000000000000006231524622605700200440ustar00rootroot00000000000000# # Helper macro # macro(add_cmakescript_test testname script) add_test(cmake_${testname} ${CMAKE_COMMAND} -DTEST_${testname}:BOOL=ON -P ${CMAKE_SOURCE_DIR}/CMake/${script}.cmake) set_tests_properties(cmake_${testname} PROPERTIES LABELS CMake PASS_REGULAR_EXPRESSION "SUCCESS") endmacro() # # Add 'CMake script' Tests # add_cmakescript_test(ctk_list_to_string_test ctkListToString) ctk-2026.09.02/CMake/UseCTK.cmake.in000066400000000000000000000033221524622605700163730ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # This module is provided as CTK_USE_FILE by CTKConfig.cmake. It can # be INCLUDED in a project to load the needed compiler and linker # settings to use CTK. # if(NOT CTK_USE_FILE_INCLUDED) set(CTK_USE_FILE_INCLUDED 1) # Add include directories needed to use CTK. get_directory_property(existing_include_directories INCLUDE_DIRECTORIES) set(new_include_directories ${CTK_INCLUDE_DIRS}) if(existing_include_directories) list(REMOVE_ITEM new_include_directories ${existing_include_directories}) endif() include_directories(${new_include_directories}) if(CTK_QT_VERSION STREQUAL "5") if(NOT DEFINED Qt5_DIR AND DEFINED CTK_Qt5_DIR) # Setting "Qt5_DIR" is the preferred approach set(Qt5_DIR ${CTK_Qt5_DIR}) elseif(NOT DEFINED CMAKE_PREFIX_PATH AND DEFINED CTK_CMAKE_PREFIX_PATH) # Support for "CMAKE_PREFIX_PATH" is here for backward compatibility set(CMAKE_PREFIX_PATH ${CTK_CMAKE_PREFIX_PATH}) endif() endif() endif() ctk-2026.09.02/CMake/WindowsApplicationUseUtf8.manifest000066400000000000000000000005171524622605700224630ustar00rootroot00000000000000 UTF-8 ctk-2026.09.02/CMake/ctkBlockCheckDependencies.cmake000066400000000000000000000134631524622605700217000ustar00rootroot00000000000000 # # Independently of the value of CTK_SUPERBUILD, each external project definition will # provides either the include and library directories or a variable name # used by the corresponding Find.cmake files. # # Within top-level CMakeLists.txt file, the variable names will be expanded if not in # superbuild mode. The include and library dirs are then used in # ctkMacroBuildApp, ctkMacroBuildLib, and ctkMacroBuildPlugin # #----------------------------------------------------------------------------- # Collect CTK library target dependencies # ctkMacroCollectAllTargetLibraries("${CTK_LIBS}" "Libs" ALL_TARGET_LIBRARIES) ctkMacroCollectAllTargetLibraries("${CTK_PLUGINS}" "Plugins" ALL_TARGET_LIBRARIES) ctkMacroCollectAllTargetLibraries("${CTK_APPS}" "Applications" ALL_TARGET_LIBRARIES) #message(STATUS ALL_TARGET_LIBRARIES:${ALL_TARGET_LIBRARIES}) #----------------------------------------------------------------------------- # Initialize NON_CTK_DEPENDENCIES variable # # Using the variable ALL_TARGET_LIBRARIES initialized above with the help # of the macro ctkMacroCollectAllTargetLibraries, let's get the list of all Non-CTK dependencies. # NON_CTK_DEPENDENCIES is expected by the macro ctkMacroShouldAddExternalProject ctkMacroGetAllNonProjectTargetLibraries("${ALL_TARGET_LIBRARIES}" NON_CTK_DEPENDENCIES) #message(NON_CTK_DEPENDENCIES:${NON_CTK_DEPENDENCIES}) #----------------------------------------------------------------------------- # Enable and setup External project global properties # if(CTK_SUPERBUILD) set(ep_install_dir ${CMAKE_BINARY_DIR}/CMakeExternals/Install) set(ep_suffix "-cmake") set(ep_common_c_flags "${CMAKE_C_FLAGS_INIT} ${ADDITIONAL_C_FLAGS}") set(ep_common_cxx_flags "${CMAKE_CXX_FLAGS_INIT} ${ADDITIONAL_CXX_FLAGS}") set(ep_cxx_standard_arg) if(CMAKE_CXX_STANDARD) set(ep_cxx_standard_arg "-DCMAKE_CXX_STANDARD:STRING=${CMAKE_CXX_STANDARD}") endif() # macOS-specific architecture settings set(ep_osx_arch_args) if(APPLE) if(CMAKE_OSX_ARCHITECTURES) list(APPEND ep_osx_arch_args -DCMAKE_OSX_ARCHITECTURES:STRING=${CMAKE_OSX_ARCHITECTURES}) endif() if(CMAKE_OSX_DEPLOYMENT_TARGET) list(APPEND ep_osx_arch_args -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${CMAKE_OSX_DEPLOYMENT_TARGET}) endif() if(CMAKE_OSX_SYSROOT) list(APPEND ep_osx_arch_args -DCMAKE_OSX_SYSROOT:PATH=${CMAKE_OSX_SYSROOT}) endif() endif() set(ep_common_cache_args -DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE} -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} -DCMAKE_C_FLAGS:STRING=${ep_common_c_flags} -DCMAKE_CXX_FLAGS:STRING=${ep_common_cxx_flags} -DCMAKE_INSTALL_PREFIX:PATH=${ep_install_dir} -DCMAKE_PREFIX_PATH:STRING=${CMAKE_PREFIX_PATH} -DBUILD_TESTING:BOOL=OFF -DCMAKE_MACOSX_RPATH:BOOL=${CMAKE_MACOSX_RPATH} ${ep_cxx_standard_arg} ${ep_osx_arch_args} ) endif() if(NOT DEFINED CTK_DEPENDENCIES) message(FATAL_ERROR "error: CTK_DEPENDENCIES variable is not defined !") endif() set(DCMTK_enabling_variable DCMTK_LIBRARIES) set(${DCMTK_enabling_variable}_INCLUDE_DIRS DCMTK_INCLUDE_DIR) set(${DCMTK_enabling_variable}_FIND_PACKAGE_CMD DCMTK) set(ITK_enabling_variable ITK_LIBRARIES) set(${ITK_enabling_variable}_LIBRARY_DIRS ITK_LIBRARY_DIRS) set(${ITK_enabling_variable}_INCLUDE_DIRS ITK_INCLUDE_DIRS) set(${ITK_enabling_variable}_FIND_PACKAGE_CMD ITK) set(Log4Qt_enabling_variable Log4Qt_LIBRARIES) set(${Log4Qt_enabling_variable}_INCLUDE_DIRS Log4Qt_INCLUDE_DIRS) set(${Log4Qt_enabling_variable}_FIND_PACKAGE_CMD Log4Qt) set(PythonQt_enabling_variable PYTHONQT_LIBRARIES) set(${PythonQt_enabling_variable}_INCLUDE_DIRS PYTHONQT_INCLUDE_DIR PYTHON_INCLUDE_DIRS) set(${PythonQt_enabling_variable}_FIND_PACKAGE_CMD PythonQt) set(QtSOAP_enabling_variable QtSOAP_LIBRARIES) set(${QtSOAP_enabling_variable}_LIBRARY_DIRS QtSOAP_LIBRARY_DIRS) set(${QtSOAP_enabling_variable}_INCLUDE_DIRS QtSOAP_INCLUDE_DIRS) set(${QtSOAP_enabling_variable}_FIND_PACKAGE_CMD QtSOAP) set(QtTesting_enabling_variable QtTesting_LIBRARIES) set(${QtTesting_enabling_variable}_INCLUDE_DIRS QtTesting_INCLUDE_DIRS) set(${QtTesting_enabling_variable}_FIND_PACKAGE_CMD QtTesting) set(qxmlrpc_enabling_variable qxmlrpc_LIBRARY) set(${qxmlrpc_enabling_variable}_LIBRARY_DIRS qxmlrpc_LIBRARY_DIRS) set(${qxmlrpc_enabling_variable}_INCLUDE_DIRS qxmlrpc_INCLUDE_DIRS) set(${qxmlrpc_enabling_variable}_FIND_PACKAGE_CMD qxmlrpc) set(qRestAPI_enabling_variable qRestAPI_LIBRARIES) set(${qRestAPI_enabling_variable}_LIBRARY_DIRS qRestAPI_LIBRARY_DIRS) set(${qRestAPI_enabling_variable}_INCLUDE_DIRS qRestAPI_INCLUDE_DIRS) set(${qRestAPI_enabling_variable}_FIND_PACKAGE_CMD qRestAPI) set(VTK_enabling_variable VTK_LIBRARIES) set(${VTK_enabling_variable}_LIBRARY_DIRS VTK_LIBRARY_DIRS) set(${VTK_enabling_variable}_INCLUDE_DIRS VTK_INCLUDE_DIRS) set(${VTK_enabling_variable}_FIND_PACKAGE_CMD VTK) macro(superbuild_is_external_project_includable possible_proj output_var) if(DEFINED ${possible_proj}_enabling_variable) ctkMacroShouldAddExternalProject(${${possible_proj}_enabling_variable} ${output_var}) if(NOT ${${output_var}}) if(${possible_proj} STREQUAL "VTK" AND CTK_LIB_Scripting/Python/Core_PYTHONQT_USE_VTK) set(${output_var} 1) else() unset(${${possible_proj}_enabling_variable}_INCLUDE_DIRS) unset(${${possible_proj}_enabling_variable}_LIBRARY_DIRS) unset(${${possible_proj}_enabling_variable}_FIND_PACKAGE_CMD) endif() endif() else() set(${output_var} 1) endif() endmacro() set(proj CTK) ExternalProject_Include_Dependencies(CTK PROJECT_VAR proj DEPENDS_VAR CTK_DEPENDENCIES USE_SYSTEM_VAR ${CMAKE_PROJECT_NAME}_USE_SYSTEM_${proj} ) #message("Updated CTK_DEPENDENCIES:") #foreach(dep ${CTK_DEPENDENCIES}) # message(" ${dep}") #endforeach() ctk-2026.09.02/CMake/ctkBlockSetCMakeOSXVariables.cmake000066400000000000000000000065031524622605700222300ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # ctkBlockSetCMakeOSXVariables # # # Adapted from Paraview/Superbuild/CMakeLists.txt # # Note: Change architecture *before* any enable_language() or project() # calls so that it's set properly to detect 64-bit-ness... # if(APPLE) # Waiting universal binaries are supported and tested, complain if # multiple architectures are specified. if(NOT "${CMAKE_OSX_ARCHITECTURES}" STREQUAL "") list(LENGTH CMAKE_OSX_ARCHITECTURES arch_count) if(arch_count GREATER 1) message(FATAL_ERROR "error: Only one value (i386 or x86_64) should be associated with CMAKE_OSX_ARCHITECTURES.") endif() endif() # See CMake/Modules/Platform/Darwin.cmake) # 8.x == Mac OSX 10.4 (Tiger) # 9.x == Mac OSX 10.5 (Leopard) # 10.x == Mac OSX 10.6 (Snow Leopard) # 10.x == Mac OSX 10.7 (Lion) set(OSX_SDK_104_NAME "Tiger") set(OSX_SDK_105_NAME "Leopard") set(OSX_SDK_106_NAME "Snow Leopard") set(OSX_SDK_107_NAME "Lion") set(OSX_SDK_ROOTS /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs /Developer/SDKs ) set(SDK_VERSIONS_TO_CHECK 10.7 10.6 10.5) foreach(SDK_VERSION ${SDK_VERSIONS_TO_CHECK}) if(NOT CMAKE_OSX_DEPLOYMENT_TARGET OR "${CMAKE_OSX_DEPLOYMENT_TARGET}" STREQUAL "") foreach(SDK_ROOT ${OSX_SDK_ROOTS}) set(TEST_OSX_SYSROOT "${SDK_ROOT}/MacOSX${SDK_VERSION}.sdk") if(EXISTS "${TEST_OSX_SYSROOT}") # Retrieve OSX target name string(REPLACE "." "" sdk_version_no_dot ${SDK_VERSION}) set(OSX_NAME ${OSX_SDK_${sdk_version_no_dot}_NAME}) set(CMAKE_OSX_ARCHITECTURES "x86_64" CACHE STRING "Force build for 64-bit ${OSX_NAME}." FORCE) set(CMAKE_OSX_DEPLOYMENT_TARGET "${SDK_VERSION}" CACHE STRING "Force build for 64-bit ${OSX_NAME}." FORCE) set(CMAKE_OSX_SYSROOT "${TEST_OSX_SYSROOT}" CACHE PATH "Force build for 64-bit ${OSX_NAME}." FORCE) message(STATUS "Setting OSX_ARCHITECTURES to '${CMAKE_OSX_ARCHITECTURES}' as none was specified.") message(STATUS "Setting OSX_DEPLOYMENT_TARGET to '${SDK_VERSION}' as none was specified.") message(STATUS "Setting OSX_SYSROOT to '${TEST_OSX_SYSROOT}' as none was specified.") endif() endforeach() endif() endforeach() if(NOT "${CMAKE_OSX_SYSROOT}" STREQUAL "") if(NOT EXISTS "${CMAKE_OSX_SYSROOT}") message(FATAL_ERROR "error: CMAKE_OSX_SYSROOT='${CMAKE_OSX_SYSROOT}' does not exist") endif() endif() mark_as_advanced( CMAKE_OSX_ARCHITECTURES ) mark_as_advanced( CMAKE_OSX_DEPLOYMENT_TARGET ) mark_as_advanced( CMAKE_OSX_SYSROOT ) endif() ctk-2026.09.02/CMake/ctkCheckoutRepo.cmake.in000066400000000000000000000005661524622605700204010ustar00rootroot00000000000000 project(${_NAME}) cmake_minimum_required(VERSION 3.20.6) include(ExternalProject) ExternalProject_Add(${_NAME} SOURCE_DIR ${_CHECKOUT_DIR}/${_NAME} BINARY_DIR bin PREFIX ep GIT_REPOSITORY ${_GIT_PROTOCOL}://${_GIT_URL} GIT_TAG ${_GIT_TAG} CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" ) ctk-2026.09.02/CMake/ctkConfig.h.in000066400000000000000000000002331524622605700163510ustar00rootroot00000000000000#ifndef __ctkConfig_h #define __ctkConfig_h #define CTK_PLUGIN_DIR "@CTK_PLUGIN_LIBRARIES_DIR_CONFIG@/" #define CTK_SOURCE_DIR "@CTK_SOURCE_DIR@" #endif ctk-2026.09.02/CMake/ctkDashboardDriverScript.cmake000066400000000000000000000200631524622605700216230ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Included from a dashboard script, this cmake file will drive the configure and build # steps of the different CTK sub-project (library, application or plugins) # # ctkDashboardDriverScript.cmake is automatically downloaded by the dashboard script # from the url http://commontk.org/ctkDashboardDriverScript.cmake # \note Any change to the file should also be backported on http://commontk.org/ # # XXX This allows to support older scripts having the typo if(DEFINED ADDITIONNAL_CMAKECACHE_OPTION) set(ADDITIONAL_CMAKECACHE_OPTION ${ADDITIONNAL_CMAKECACHE_OPTION}) endif() #----------------------------------------------------------------------------- # The following variable are expected to be define in the top-level script: set(expected_variables ADDITIONAL_CMAKECACHE_OPTION CTEST_NOTES_FILES CTEST_SITE CTEST_DASHBOARD_ROOT CTEST_CMAKE_GENERATOR WITH_MEMCHECK WITH_COVERAGE WITH_DOCUMENTATION CTEST_BUILD_CONFIGURATION CTEST_TEST_TIMEOUT CTEST_BUILD_FLAGS TEST_TO_EXCLUDE_REGEX CTEST_PROJECT_NAME CTEST_SOURCE_DIRECTORY CTEST_BINARY_DIRECTORY CTEST_BUILD_NAME SCRIPT_MODE CTEST_COVERAGE_COMMAND CTEST_MEMORYCHECK_COMMAND CTEST_GIT_COMMAND QT_QMAKE_EXECUTABLE ) if(WITH_DOCUMENTATION) list(APPEND expected_variables DOCUMENTATION_ARCHIVES_OUTPUT_DIRECTORY) endif() foreach(var ${expected_variables}) if(NOT DEFINED ${var}) message(FATAL_ERROR "Variable ${var} should be defined in top-level script !") endif() endforeach() # If the dashscript doesn't define a GIT_REPOSITORY variable, let's define it here. if(NOT DEFINED GIT_REPOSITORY OR GIT_REPOSITORY STREQUAL "") set(GIT_REPOSITORY https://github.com/commontk/CTK.git) endif() set(repository ${GIT_REPOSITORY}) set(git_branch_option "") if(NOT "${GIT_TAG}" STREQUAL "") set(git_branch_option "-b ${GIT_TAG}") endif() message("GIT_REPOSITORY ......: ${GIT_REPOSITORY}") message("GIT_TAG .............: ${GIT_TAG}") # Should binary directory be cleaned? set(empty_binary_directory FALSE) # Attempt to build and test also if 'ctest_update' returned an error set(force_build FALSE) # Ensure SCRIPT_MODE is lowercase string(TOLOWER ${SCRIPT_MODE} SCRIPT_MODE) # Set model options set(model "") if(SCRIPT_MODE STREQUAL "experimental") set(empty_binary_directory FALSE) set(force_build TRUE) set(model Experimental) elseif(SCRIPT_MODE STREQUAL "continuous") set(empty_binary_directory TRUE) set(force_build FALSE) set(model Continuous) elseif(SCRIPT_MODE STREQUAL "nightly") set(empty_binary_directory TRUE) set(force_build TRUE) set(model Nightly) else() message(FATAL_ERROR "Unknown script mode: '${SCRIPT_MODE}'. Script mode should be either 'experimental', 'continuous' or 'nightly'") endif() # For more details, see http://www.kitware.com/blog/home/post/11 set(CTEST_USE_LAUNCHERS 1) if(NOT "${CTEST_CMAKE_GENERATOR}" MATCHES "Make") set(CTEST_USE_LAUNCHERS 0) endif() set(ENV{CTEST_USE_LAUNCHERS_DEFAULT} ${CTEST_USE_LAUNCHERS}) if(empty_binary_directory) message("Directory ${CTEST_BINARY_DIRECTORY} cleaned !") ctest_empty_binary_directory(${CTEST_BINARY_DIRECTORY}) endif() if(NOT EXISTS "${CTEST_SOURCE_DIRECTORY}") set(CTEST_CHECKOUT_COMMAND "${CTEST_GIT_COMMAND} clone ${git_branch_option} ${GIT_REPOSITORY} ${CTEST_SOURCE_DIRECTORY}") endif() set(CTEST_UPDATE_COMMAND "${CTEST_GIT_COMMAND}") # # run_ctest macro # macro(run_ctest) message("----------- [ Start ${CTEST_PROJECT_NAME} ] -----------") ctest_start(${model}) message("----------- [ Update ${CTEST_PROJECT_NAME} ] -----------") ctest_update(SOURCE "${CTEST_SOURCE_DIRECTORY}" RETURN_VALUE res) # force a build if this is the first run and the build dir is empty if(NOT EXISTS "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt") message("First time build - Initialize CMakeCache.txt") set(res 1) # Write initial cache. file(WRITE "${CTEST_BINARY_DIRECTORY}/CMakeCache.txt" " QT_QMAKE_EXECUTABLE:FILEPATH=${QT_QMAKE_EXECUTABLE} WITH_COVERAGE:BOOL=${WITH_COVERAGE} DOCUMENTATION_TARGET_IN_ALL:BOOL=${WITH_DOCUMENTATION} DOCUMENTATION_ARCHIVES_OUTPUT_DIRECTORY:PATH=${DOCUMENTATION_ARCHIVES_OUTPUT_DIRECTORY} ${ADDITIONAL_CMAKECACHE_OPTION} ") endif() if(res GREATER 0 OR force_build) #----------------------------------------------------------------------------- # Update #----------------------------------------------------------------------------- ctest_submit(PARTS Update) #----------------------------------------------------------------------------- # Configure #----------------------------------------------------------------------------- message("----------- [ Configure ${CTEST_PROJECT_NAME} ] -----------") ctest_configure(BUILD "${CTEST_BINARY_DIRECTORY}") ctest_read_custom_files("${CTEST_BINARY_DIRECTORY}") ctest_submit(PARTS Configure) #----------------------------------------------------------------------------- # Build top level #----------------------------------------------------------------------------- set(build_errors) message("----------- [ Build ${CTEST_PROJECT_NAME} ] -----------") ctest_build(BUILD "${CTEST_BINARY_DIRECTORY}" NUMBER_ERRORS build_errors APPEND) ctest_submit(PARTS Build) #----------------------------------------------------------------------------- # Inner build directory #----------------------------------------------------------------------------- set(ctk_build_dir "${CTEST_BINARY_DIRECTORY}/CTK-build") #----------------------------------------------------------------------------- # Test #----------------------------------------------------------------------------- message("----------- [ Test ${CTEST_PROJECT_NAME} ] -----------") ctest_test( BUILD "${ctk_build_dir}" PARALLEL_LEVEL ${CTEST_PARALLEL_LEVEL} EXCLUDE ${TEST_TO_EXCLUDE_REGEX}) ctest_submit(PARTS Test) #----------------------------------------------------------------------------- # Global coverage ... #----------------------------------------------------------------------------- if(WITH_COVERAGE AND CTEST_COVERAGE_COMMAND) # HACK Unfortunately ctest_coverage ignores the build argument, try to force it... file(READ ${ctk_build_dir}/CMakeFiles/TargetDirectories.txt ctk_build_coverage_dirs) file(APPEND "${CTEST_BINARY_DIRECTORY}/CMakeFiles/TargetDirectories.txt" "${ctk_build_coverage_dirs}") message("----------- [ Coverage ] -----------") ctest_coverage(BUILD "${ctk_build_dir}") ctest_submit(PARTS Coverage) endif() #----------------------------------------------------------------------------- # Global dynamic analysis ... #----------------------------------------------------------------------------- if(WITH_MEMCHECK AND CTEST_MEMORYCHECK_COMMAND) message("----------- [ Memcheck ] -----------") ctest_memcheck(BUILD "${ctk_build_dir}") ctest_submit(PARTS MemCheck) endif() # Note should be at the end ctest_submit(PARTS Notes) endif() endmacro() if(SCRIPT_MODE STREQUAL "continuous") while(${CTEST_ELAPSED_TIME} LESS 46800) # Lasts 13 hours (Assuming it starts at 9am, it will end around 10pm) set(START_TIME ${CTEST_ELAPSED_TIME}) run_ctest() # Loop no faster than once every 5 minutes message("Wait for 5 minutes ...") ctest_sleep(${START_TIME} 300 ${CTEST_ELAPSED_TIME}) endwhile() else() run_ctest() endif() ctk-2026.09.02/CMake/ctkDashboardScript.TEMPLATE.cmake000066400000000000000000000163521524622605700216670ustar00rootroot00000000000000#################################################################################### # OS : # Hardware: # GPU : #################################################################################### # WARNING - The specific version and processor type of this machine should be reported # in the header above. Indeed, this file will be send to the dashboard as a NOTE file. # # On linux, you could run: # 'uname -o' and 'cat /etc/*-release' to obtain the OS name. # 'uname -mpi' to obtain hardware details. # 'glxinfo | grep OpenGL' to obtain GPU details. #################################################################################### cmake_minimum_required(VERSION 3.20.6) # # For additional information, see http://commontk.org/index.php/Dashboard_setup # #----------------------------------------------------------------------------- # Experimental: # - run_ctest() macro will be called *ONE* time # - binary directory will *NOT* be cleaned # Continuous: # - run_ctest() macro will be called EVERY 5 minutes ... # - binary directory will *NOT* be cleaned # - configure/build will be executed *ONLY* if the repository has been updated # Nightly: # - run_ctest() macro will be called *ONE* time # - binary directory *WILL BE* cleaned set(SCRIPT_MODE "Experimental") # "Experimental", "Continuous", "Nightly" # You could invoke the script with the following syntax: # ctest -S karakoram_Slicer4_nightly.cmake -C -V # # Note that '-C ' is mandatory on windows #----------------------------------------------------------------------------- # Dashboard properties #----------------------------------------------------------------------------- set(MY_OPERATING_SYSTEM "Ubuntu-13.10") # Windows, Linux, Darwin... set(MY_COMPILER "g++4.8.1") set(MY_QT_VERSION "4.8.5") set(QT_QMAKE_EXECUTABLE "$ENV{HOME}/Support/qt-everywhere-opensource-release-build-4.8.5/bin/qmake") set(CTEST_SITE "karakoram.kitware") # for example: mymachine.kitware, mymachine.dkfz, ... set(CTEST_DASHBOARD_ROOT "$ENV{HOME}/Dashboards/${SCRIPT_MODE}") # set(GIT_REPOSITORY http://github.com/YOURUSERNAME/CTK.git) set(GIT_TAG "") # origin/next # Each dashboard script should specify a unique ID per CTEST_DASHBOARD_ROOT. # It means the following directories will be created: # /- # Source directory # /--build # Build directory set(DIRECTORY_IDENTIFIER "0") # Open a shell and type in "cmake --help" to obtain the proper spelling of the generator set(CTEST_CMAKE_GENERATOR "Unix Makefiles") set(MY_BITNESS "64") #----------------------------------------------------------------------------- # Dashboard options #----------------------------------------------------------------------------- set(WITH_KWSTYLE FALSE) set(WITH_MEMCHECK FALSE) set(WITH_COVERAGE FALSE) set(WITH_DOCUMENTATION FALSE) #set(DOCUMENTATION_ARCHIVES_OUTPUT_DIRECTORY ) # for example: $ENV{HOME}/Projects/Doxygen set(CTEST_BUILD_CONFIGURATION "Release") set(CTEST_TEST_TIMEOUT 500) set(CTEST_BUILD_FLAGS "") # Use multiple CPU cores to build. For example "-j -l4" on unix set(CTEST_PARALLEL_LEVEL 8) # Number of tests running in parallel #----------------------------------------------------------------------------- # Additional CMakeCache options #----------------------------------------------------------------------------- set(ADDITIONAL_CMAKECACHE_OPTION " ") #----------------------------------------------------------------------------- # List of test that should be explicitly disabled on this machine #----------------------------------------------------------------------------- set(TEST_TO_EXCLUDE_REGEX "") #----------------------------------------------------------------------------- # Set any extra environment variables here #----------------------------------------------------------------------------- if(UNIX) set(ENV{DISPLAY} ":0") endif() #----------------------------------------------------------------------------- # Required executables #----------------------------------------------------------------------------- find_program(CTEST_GIT_COMMAND NAMES git) find_program(CTEST_COVERAGE_COMMAND NAMES gcov) find_program(CTEST_MEMORYCHECK_COMMAND NAMES valgrind) #----------------------------------------------------------------------------- # Build Name #----------------------------------------------------------------------------- # Update the following variable to match the chosen build options. This variable is used to # generate both the build directory and the build name. # See http://my.cdash.org/CDash/index.php?project=CTK for examples set(BUILD_OPTIONS_STRING "${MY_BITNESS}bits-QT${MY_QT_VERSION}") #----------------------------------------------------------------------------- # Directory name #----------------------------------------------------------------------------- set(DIRECTORY_NAME "CTK") #----------------------------------------------------------------------------- # Build directory #----------------------------------------------------------------------------- set(CTEST_BINARY_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${DIRECTORY_NAME}-${DIRECTORY_IDENTIFIER}-build") file(WRITE "${CTEST_DASHBOARD_ROOT}/${DIRECTORY_NAME}-${DIRECTORY_IDENTIFIER}-build - ${BUILD_OPTIONS_STRING}-${CTEST_BUILD_CONFIGURATION}-${SCRIPT_MODE}.txt" "Generated by ${CTEST_SCRIPT_NAME}") #----------------------------------------------------------------------------- # Source directory #----------------------------------------------------------------------------- set(CTEST_SOURCE_DIRECTORY "${CTEST_DASHBOARD_ROOT}/${DIRECTORY_NAME}-${DIRECTORY_IDENTIFIER}") ########################################## # WARNING: DO NOT EDIT BEYOND THIS POINT # ########################################## set(CTEST_NOTES_FILES "${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}") # # Project specific properties # set(CTEST_PROJECT_NAME "CTK") set(CTEST_BUILD_NAME "${MY_OPERATING_SYSTEM}-${MY_COMPILER}-${BUILD_OPTIONS_STRING}-${CTEST_BUILD_CONFIGURATION}") # # Display build info # message("CTEST_SITE ................: ${CTEST_SITE}") message("CTEST_BUILD_NAME ..........: ${CTEST_BUILD_NAME}") message("SCRIPT_MODE ...............: ${SCRIPT_MODE}") message("CTEST_BUILD_CONFIGURATION .: ${CTEST_BUILD_CONFIGURATION}") message("WITH_KWSTYLE ..............: ${WITH_KWSTYLE}") message("WITH_COVERAGE: ............: ${WITH_COVERAGE}") message("WITH_MEMCHECK .............: ${WITH_MEMCHECK}") message("WITH_PACKAGES .............: ${WITH_PACKAGES}") message("WITH_DOCUMENTATION ........: ${WITH_DOCUMENTATION}") message("DOCUMENTATION_ARCHIVES_OUTPUT_DIRECTORY: ${DOCUMENTATION_ARCHIVES_OUTPUT_DIRECTORY}") # # Convenient function allowing to download a file # function(download_file url dest) file(DOWNLOAD ${url} ${dest} STATUS status) list(GET status 0 error_code) list(GET status 1 error_msg) if(error_code) message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}") endif() endfunction() # # Download and include dashboard driver script # set(url https://raw.githubusercontent.com/commontk/CTK/master/CMake/ctkDashboardDriverScript.cmake) set(dest ${CTEST_SCRIPT_DIRECTORY}/${CTEST_SCRIPT_NAME}.driver) download_file(${url} ${dest}) include(${dest}) ctk-2026.09.02/CMake/ctkFunctionAddExecutableUtf8.cmake000066400000000000000000000007311524622605700223420ustar00rootroot00000000000000#! Usage: #! \code #! ctk_add_executable_utf8(args) #! \endcode #! #! This macro adds an executable that uses UTF-8 code page. #! #! Linux and Mac OSX already uses this code page by default but on Windows #! it has to be set explicitly, by using a manifest file. #! #! \ingroup CMakeUtilities function(ctk_add_executable_utf8) if(WIN32) add_executable(${ARGN} ${CTK_CMAKE_DIR}/WindowsApplicationUseUtf8.manifest) else() add_executable(${ARGN}) endif() endfunction() ctk-2026.09.02/CMake/ctkFunctionAddPluginRepo.cmake000066400000000000000000000037451524622605700216060ustar00rootroot00000000000000function(ctkFunctionAddPluginRepo) ctkMacroParseArguments("" "NAME;GIT_URL;GIT_TAG;GIT_PROTOCOL" "" ${ARGN}) foreach(_required_arg NAME) if(NOT _${_required_arg}) message(FATAL_ERROR "${_required_arg} is empty") endif() endforeach() if(NOT _GIT_URL AND NOT ${_NAME}_DIR) message(FATAL_ERROR "Either ${_NAME}_DIR or GIT_URL must be set") endif() if(NOT ${_NAME}_DIR) ctkFunctionCheckoutRepo( NAME ${_NAME} GIT_URL ${_GIT_URL} GIT_TAG ${_GIT_TAG} GIT_PROTOCOL ${_GIT_PROTOCOL} ) endif() set(_gitmodules_files ${${_NAME}_DIR}/.gitmodules) if(NOT EXISTS ${_gitmodules_files}) message(FATAL_ERROR "The repository at ${${_NAME}_DIR} does not contain a .gitmodules file") endif() # Parse the .gitmodules file and add the submodules as contributed plugins file(STRINGS "${_gitmodules_files}" _plugin_paths REGEX "path =.*") foreach(_plugin_path ${_plugin_paths}) string(REPLACE " = " ";" _plugin_path_list ${_plugin_path}) list(GET _plugin_path_list 1 _plugin_name) ctk_plugin_option(${_plugin_name} "Build the ${_plugin_name} plugin." OFF) # Push the value which might have been changed in ctk_plugin_option to the parent scope set(CTK_PLUGIN_${_plugin_name} ${CTK_PLUGIN_${_plugin_name}} PARENT_SCOPE) set(${_plugin_name}_SOURCE_DIR ${${_NAME}_DIR}/${_plugin_name}) set(${_plugin_name}_SOURCE_DIR ${${_plugin_name}_SOURCE_DIR} PARENT_SCOPE) if(CTK_PLUGIN_${_plugin_name} AND NOT EXISTS ${${_plugin_name}_SOURCE_DIR}) execute_process( COMMAND ${GIT_EXECUTABLE} submodule update ${_plugin_name} WORKING_DIRECTORY ${${_NAME}_DIR} RESULT_VARIABLE return_code ERROR_VARIABLE error_msg ) if(return_code) message(FATAL_ERROR "Could not invoke git submodule update for ${${_plugin_name}_SOURCE_DIR}") endif() endif() endforeach() set(CTK_PLUGINS ${CTK_PLUGINS} PARENT_SCOPE) set(${_NAME}_DIR ${${_NAME}_DIR} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionApplyPatches.cmake000066400000000000000000000026641524622605700215050ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Depends on: # CTK/CMake/ctkFunctionLFtoCRLF.cmake # #! \ingroup CMakeUtilities function(ctkFunctionApplyPatches PATCH_EXE SRC_DIR PATCH_FILES) # Make sure patch executable exists if(NOT EXISTS ${PATCH_EXE}) message(FATAL_ERROR "ERROR: Program [${PATCH_EXE}] doesn't exist !") endif() # Apply patches foreach(patch_file ${PATCH_FILES}) message("Applying patch: ${patch_file}") if(WIN32) ctkFunctionLFtoCRLF("${patch_file}" "${patch_file}") endif() execute_process(COMMAND ${PATCH_EXE} -p0 -i "${patch_file}" -d "${SRC_DIR}" RESULT_VARIABLE result_var) if(result_var) message("ERROR: ${result_var}") endif() endforeach() endfunction() ctk-2026.09.02/CMake/ctkFunctionCMakeDoxygenFilterCompile.cmake000066400000000000000000000055441524622605700241050ustar00rootroot00000000000000#! #! \brief Compile a CMake doxygen input filter #! #! \param OUT <out-file> (optional) Supply an absolute filename for #! the generated executable. #! \param NAMESPACE <namespace> (optional) Supply a C++ namespace in #! which the generated function declrarations #! should be wrapped. #! #! \return This function sets the CMakeDoxygenFilter_EXECUTABLE #! variable to the absolute path of the generated input filter executable #! in the parent scope. If is specified, they will be the same. #! #! This CMake function compiles the http://github.com/saschazelzer/CMakeDoxygenFilter #! project into a doxygen input filter executable. See #! http://github.com/saschazelzer/CMakeDoxygenFilter/blob/master/README for more details. #! #! \ingroup CMakeUtilities function(ctkFunctionCMakeDoxygenFilterCompile) #-------------------- parse function arguments ------------------- set(DEFAULT_ARGS) set(prefix "FILTER") set(arg_names "OUT;NAMESPACE") set(option_names "") foreach(arg_name ${arg_names}) set(${prefix}_${arg_name}) endforeach() foreach(option ${option_names}) set(${prefix}_${option} FALSE) endforeach() set(current_arg_name DEFAULT_ARGS) set(current_arg_list) foreach(arg ${ARGN}) set(larg_names ${arg_names}) list(FIND larg_names "${arg}" is_arg_name) if(is_arg_name GREATER -1) set(${prefix}_${current_arg_name} ${current_arg_list}) set(current_arg_name "${arg}") set(current_arg_list) else() set(loption_names ${option_names}) list(FIND loption_names "${arg}" is_option) if(is_option GREATER -1) set(${prefix}_${arg} TRUE) else() set(current_arg_list ${current_arg_list} "${arg}") endif() endif() endforeach() set(${prefix}_${current_arg_name} ${current_arg_list}) #------------------- finished parsing arguments ---------------------- if(FILTER_OUT) set(copy_file "${FILTER_OUT}") else() set(copy_file "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/CMakeDoxygenFilter${CMAKE_EXECUTABLE_SUFFIX}") endif() set(compile_defs "") if(FILTER_NAMESPACE) set(compile_defs "${compile_defs} -DUSE_NAMESPACE=${FILTER_NAMESPACE}") endif() set(cmake_doxygen_filter_src "${CTK_SOURCE_DIR}/Documentation/CMakeDoxygenFilter.cpp") try_compile(result_var "${CMAKE_CURRENT_BINARY_DIR}" "${cmake_doxygen_filter_src}" COMPILE_DEFINITIONS ${compile_defs} OUTPUT_VARIABLE compile_output COPY_FILE ${copy_file} ) if(NOT result_var) message(FATAL_ERROR "error: Failed to compile ${cmake_doxygen_filter_src} (result: ${result_var})\n${compile_output}") endif() set(CMakeDoxygenFilter_EXECUTABLE "${copy_file}" PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionCheckCompilerFlags.cmake000066400000000000000000000032551524622605700225720ustar00rootroot00000000000000 # # Helper macro allowing to check if the given flags are supported # by the underlying build tool # # If the flag(s) is/are supported, they will be appended to the string identified by RESULT_VAR # # Usage: # ctkFunctionCheckCompilerFlags(FLAGS_TO_CHECK VALID_FLAGS_VAR) # # Example: # # set(myflags) # ctkFunctionCheckCompilerFlags("-fprofile-arcs" myflags) # message(1-myflags:${myflags}) # ctkFunctionCheckCompilerFlags("-fauto-bugfix" myflags) # message(2-myflags:${myflags}) # ctkFunctionCheckCompilerFlags("-Wall" myflags) # message(1-myflags:${myflags}) # # The output will be: # 1-myflags: -fprofile-arcs # 2-myflags: -fprofile-arcs # 3-myflags: -fprofile-arcs -Wall include(TestCXXAcceptsFlag) #! \ingroup CMakeUtilities function(ctkFunctionCheckCompilerFlags CXX_FLAG_TO_TEST RESULT_VAR) if(CXX_FLAG_TO_TEST STREQUAL "") message(FATAL_ERROR "CXX_FLAG_TO_TEST shouldn't be empty") endif() # Internally, the macro CMAKE_CXX_ACCEPTS_FLAG calls TRY_COMPILE. To avoid # the cost of compiling the test each time the project is configured, the variable set by # the macro is added to the cache so that following invocation of the macro with # the same variable name skip the compilation step. # For that same reason, ctkFunctionCheckCompilerFlags function appends a unique suffix to # the HAS_FLAG variable. This suffix is created using a 'clean version' of the flag to test. string(REGEX REPLACE "-\\s\\$\\+\\*\\{\\}\\(\\)\\#" "" suffix ${CXX_FLAG_TO_TEST}) CHECK_CXX_ACCEPTS_FLAG(${CXX_FLAG_TO_TEST} HAS_FLAG_${suffix}) if(HAS_FLAG_${suffix}) set(${RESULT_VAR} "${${RESULT_VAR}} ${CXX_FLAG_TO_TEST}" PARENT_SCOPE) endif() endfunction() ctk-2026.09.02/CMake/ctkFunctionCheckoutRepo.cmake000066400000000000000000000030031524622605700214670ustar00rootroot00000000000000function(ctkFunctionCheckoutRepo) ctkMacroParseArguments("" "NAME;GIT_URL;GIT_TAG;GIT_PROTOCOL;CHECKOUT_DIR" "" ${ARGN}) if(${_NAME}_DIR) # if a *_DIR variable is supplied, the repository is not cloned. return() endif() foreach(_required_arg NAME GIT_URL) if(NOT _${_required_arg}) message(FATAL_ERROR "${_required_arg} is empty") endif() endforeach() if(NOT _GIT_PROTOCOL) set(_GIT_PROTOCOL ${EP_GIT_PROTOCOL}) endif() if(NOT _CHECKOUT_DIR) set(_CHECKOUT_DIR ${CMAKE_CURRENT_BINARY_DIR}) endif() if(NOT IS_ABSOLUTE "${_CHECKOUT_DIR}") message(FATAL_ERROR "The value of the CHECKOUT_DIR argument must be an absolute path.") endif() if(NOT _GIT_TAG) set(_GIT_TAG origin/master) endif() set(_repo_build_dir ${CMAKE_CURRENT_BINARY_DIR}/${_NAME}-proj) configure_file(${CTK_CMAKE_DIR}/ctkCheckoutRepo.cmake.in ${_repo_build_dir}/CMakeLists.txt) execute_process( COMMAND ${CMAKE_COMMAND} . WORKING_DIRECTORY ${_repo_build_dir} RESULT_VARIABLE _result_code ERROR_VARIABLE _err_msg ) if(_result_code) message(FATAL_ERROR "Configuring directory ${_repo_build_dir} failed: ${_err_msg}") endif() execute_process( COMMAND ${CMAKE_COMMAND} --build ${_repo_build_dir} RESULT_VARIABLE _result_code ERROR_VARIABLE _err_msg ) if(_result_code) message(FATAL_ERROR "Building directory ${_repo_build_dir} failed: ${_err_msg}") endif() set(${_NAME}_DIR ${_CHECKOUT_DIR}/${_NAME} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionCompileSnippets.cmake000066400000000000000000000050351524622605700222210ustar00rootroot00000000000000 #! Compile code snippets from a given directory #! #! This CMake function globs all files called \e main.cpp in the #! directory given by snippet_path and creates #! an executable for each found main.cpp. #! #! If a \e files.cmake file exists in the same directory where a #! main.cpp file was found, it is included. This function assumes #! that the files.cmake file sets a list named \e snippet_src_files #! containing a list of files which should be compiled into the #! executable. If no files.cmake file is found, all files in the #! directory are compiled into the executable. #! #! This function uses all additionally passed arguments as link #! dependencies for the created executable. #! function(ctkFunctionCompileSnippets snippet_path) # get all files called "main.cpp" file(GLOB_RECURSE main_cpp_list "${snippet_path}/main.cpp") foreach(main_cpp_file ${main_cpp_list}) # get the directory containing the main.cpp file get_filename_component(main_cpp_dir "${main_cpp_file}" PATH) set(snippet_src_files ) # If there exists a "files.cmake" file in the snippet directory, # include it and assume it sets the variable "snippet_src_files" # to a list of source files for the snippet. if(EXISTS "${main_cpp_dir}/files.cmake") include("${main_cpp_dir}/files.cmake") set(_tmp_src_files ${snippet_src_files}) set(snippet_src_files ) foreach(_src_file ${_tmp_src_files}) if(IS_ABSOLUTE ${_src_file}) list(APPEND snippet_src_files ${_src_file}) else() list(APPEND snippet_src_files ${main_cpp_dir}/${_src_file}) endif() endforeach() else() # glob all files in the directory and add them to the snippet src list file(GLOB_RECURSE snippet_src_files "${main_cpp_dir}/*") endif() # Uset the top-level directory name as the executable name string(REPLACE "/" ";" main_cpp_dir_tokens "${main_cpp_dir}") list(GET main_cpp_dir_tokens -1 snippet_exec_name) set(snippet_target_name "Snippet-${snippet_exec_name}") ctk_add_executable_utf8(${snippet_target_name} ${snippet_src_files}) if(ARGN) target_link_libraries(${snippet_target_name} ${ARGN}) endif() set_target_properties(${snippet_target_name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/snippets" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_ARCHIVE_OUTPUT_DIRECTORY}/snippets" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/snippets" OUTPUT_NAME ${snippet_exec_name} ) endforeach() endfunction() ctk-2026.09.02/CMake/ctkFunctionDownloadData.cmake000066400000000000000000000071661524622605700214530ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### #! #! Fetch data from a MIDAS server #! #! Usage: #! \code #! ctkFunctionDownloadData( #! MIDAS_SERVER_URL http://www.insight-journal.org/midas/item/download/ #! ITEMID 2461 #! OUTPUT_DIRECTORY /home/jchris/Projects/Data #! [FORCE_DOWNLOAD] #! ) #! \endcode #! #! The downloaded file will have the from: midas_item_.tar #! #! \ingroup CMakeUtilities function( ctkFunctionDownloadData) ctkMacroParseArguments(MY "MIDAS_SERVER_URL;ITEMID;OUTPUT_DIRECTORY" "FORCE_DOWNLOAD" ${ARGN} ) # Sanity checks foreach(arg MIDAS_SERVER_URL ITEMID OUTPUT_DIRECTORY) if(NOT DEFINED MY_${arg}) message(FATAL_ERROR "${arg} is mandatory") endif() endforeach() # Make sure output directory exists if(NOT EXISTS "${MY_OUTPUT_DIRECTORY}") message(FATAL_ERROR "OUTPUT_DIRECTORY '${MY_OUTPUT_DIRECTORY}' doesn't exist !") endif() # Is download required ? set(dest_file ${MY_OUTPUT_DIRECTORY}/midas_item_${MY_ITEMID}.tar) IF (NOT EXISTS ${dest_file} OR MY_FORCE_DOWNLOAD) set(url ${MY_MIDAS_SERVER_URL}/${MY_ITEMID}) file(DOWNLOAD ${url} ${dest_file} STATUS status) list(GET status 0 error_code) list(GET status 1 error_msg) if(error_code) message(FATAL_ERROR "error: Failed to download ${url} - ${error_msg}") endif() message(STATUS "info: downloaded '${dest_file}'") endif() endfunction() # # Test - Use cmake -DMACRO_TESTING:BOOL=ON -P ctkFunctionDownloadData.cmake # if(FUNCTION_TESTING) include(ctkMacroParseArguments.cmake) message("Testing ctkFunctionDownloadData ...") # # Test1 # set(url http://www.insight-journal.org/midas/item/download/) set(output_dir $ENV{HOME}/Projects/Data) set(itemid 2461) message(STATUS "downloading... [http://www.insight-journal.org/midas/item/download/${itemid}]") ctkFunctionDownloadData( MIDAS_SERVER_URL ${url} ITEMID ${itemid} OUTPUT_DIRECTORY ${output_dir} ) set(expected_file ${output_dir}/midas_item_${itemid}.tar) # Make sure the file exists if(NOT EXISTS ${expected_file}) message(FATAL_ERROR "File '${expected_file}' doesn't exists") endif() set(extract_destination_dir ${output_dir}/item_${itemid}) # Create a folder message(STATUS "creating directory ... [${extract_destination_dir}]") file(MAKE_DIRECTORY ${extract_destination_dir}) # Extract set(tar_args xf) message(STATUS "extracting... [tar midas_item_${itemid}.tar]") execute_process(COMMAND ${CMAKE_COMMAND} -E tar ${tar_args} ${expected_file} WORKING_DIRECTORY ${extract_destination_dir} RESULT_VARIABLE rv) if(NOT rv EQUAL 0) message(STATUS "extracting... [error clean up]") file(REMOVE_RECURSE ${extract_destination_dir}) message(FATAL_ERROR "error: extract of '${expected_file}' failed") endif() # Remove archive #file(REMOVE ${expected_file}) #file(REMOVE_RECURSE ${extract_destination_dir}) endif() ctk-2026.09.02/CMake/ctkFunctionExtractOptimizedLibrary.cmake000066400000000000000000000022451524622605700237270ustar00rootroot00000000000000#! #! Extracts the optimized library filepath from a list in the target_link_libraries() #! format, e. g. "optimized;release.lib;debug;debug.lib". #! #! If the list is a single filepath, return it instead. #! #! \param lib_list A target_link_libraries() library list or a single filepath. #! \param var_optimized_lib A variable name containing the output. #! function(ctkFunctionExtractOptimizedLibrary lib_list var_optimized_lib) list(LENGTH ${lib_list} lib_list_length) if(lib_list_length EQUAL 1) set(${var_optimized_lib} "${${lib_list}}" PARENT_SCOPE) return() endif() list(FIND ${lib_list} "optimized" optimized_keyword_index) if(optimized_keyword_index EQUAL -1) message(FATAL_ERROR "List \"${${lib_list}}\" does not contain \"optimized\" keyword") endif() math(EXPR last_lib_list_index "${lib_list_length} - 1") if(NOT optimized_keyword_index LESS last_lib_list_index) message(FATAL_ERROR "List \"${${lib_list}}\" ended unexpectedly") endif() math(EXPR optimized_lib_index "${optimized_keyword_index} + 1") list(GET ${lib_list} ${optimized_lib_index} optimized_lib) set(${var_optimized_lib} "${optimized_lib}" PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionExtractOptionNameAndValue.cmake000066400000000000000000000031221524622605700241220ustar00rootroot00000000000000 # # # #! \ingroup CMakeUtilities function(ctkFunctionExtractOptionNameAndValue my_opt var_opt_name var_opt_value) # Make sure option is correctly formatted if(NOT "${my_opt}" MATCHES "^[- :/A-Za-z0-9._]+:(ON|OFF)$") message(FATAL_ERROR "Option ${my_opt} is incorrect. Options should be specified using the following format OPT1:[ON|OFF]. For example OPT1:OFF or OPT2:ON") endif() # Extract option name and option default value string(REGEX REPLACE ":(ON|OFF)$" "\\\\;\\1" my_opt_list ${my_opt}) set(my_opt_list ${my_opt_list}) list(GET my_opt_list 0 opt_name) list(GET my_opt_list 1 opt_value) set(${var_opt_name} ${opt_name} PARENT_SCOPE) set(${var_opt_value} ${opt_value} PARENT_SCOPE) endfunction() # # Test - Use cmake -DMACRO_TESTING:BOOL=ON -P ctkFunctionExtractOptionNameAndValue.cmake # if(MACRO_TESTING) message("Testing ctkFunctionExtractOptionNameAndValue ...") # # Test1 # set(test1 "john:ON") ctkFunctionExtractOptionNameAndValue(${test1} test1_name test1_value) if(NOT test1_name STREQUAL "john") message(FATAL_ERROR "test1_name:${test1_name} - Expected:john") endif() if(NOT test1_value STREQUAL "ON") message(FATAL_ERROR "test1_value:${test1_value} - Expected:ON") endif() # # Test2 # set(test2 "doe/john:OFF") ctkFunctionExtractOptionNameAndValue(${test2} test2_name test2_value) if(NOT test2_name STREQUAL "doe/john") message(FATAL_ERROR "test1_name:${test2_name} - Expected:doe/john") endif() if(NOT test2_value STREQUAL "OFF") message(FATAL_ERROR "test2_value:${test2_value} - Expected:OFF") endif() endif() ctk-2026.09.02/CMake/ctkFunctionExtractPluginTargets.cmake000066400000000000000000000033131524622605700232230ustar00rootroot00000000000000#! #! Extracts target names from a string containing CMake option values. #! #! Example usage: #! \code #! set(build_options Plugins/org.mydomain.core:ON Plugins/org.mydomain.logic:ON) #! ctkFunctionExtractPluginTargets("${build_options}" ALL target_names) #! message("targets: ${target_names}") #! \endcode #! will print targets: org_mydomain_core;org_mydomain_logic. #! #! \param my_opts A string containing a list of options. #! \param my_filter One of ON, OFF or ALL. Checks the actual build option of the plugin. #! \param var_targets A variable name containing the output. #! function(ctkFunctionExtractPluginTargets my_opts my_filter var_targets) if("${my_filter}" STREQUAL "ON" OR "${my_filter}" STREQUAL "OFF" OR "${my_filter}" STREQUAL "ALL") set(valid_input 1) else() set(valid_input 0) set(error_msg "${my_filter} is not one of ON, OFF or ALL") endif() if(NOT valid_input) message(FATAL_ERROR "${error_msg}") endif() set(plugin_targets ) foreach(opt ${my_opts}) ctkFunctionExtractOptionNameAndValue(${opt} plugin_name_with_dirs plugin_value) string(REPLACE "/" ";" _tokens ${plugin_name_with_dirs}) list(GET _tokens -1 plugin_name) string(REPLACE "." "_" plugin_target ${plugin_name}) if("${my_filter}" STREQUAL "ALL") list(APPEND plugin_targets ${plugin_target}) elseif("${my_filter}" STREQUAL "ON") if(${${plugin_name_with_dirs}_option_name}) list(APPEND plugin_targets ${plugin_target}) endif() else() if(NOT ${${plugin_name_with_dirs}_option_name}) list(APPEND plugin_targets ${plugin_target}) endif() endif() endforeach() set(${var_targets} ${plugin_targets} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionGenerateDGraphInput.cmake000066400000000000000000000113061524622605700227410ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### #! #! Generate a DGrapgh input file expected by DGraph executable. #! #! \ingroup CMakeAPI function(ctkFunctionGenerateDGraphInput dir target_directories) if(NOT EXISTS ${dir}) message(FATAL_ERROR "Directory ${dir} doesn't exist!") endif() CtkMacroParseArguments(MY "" "WITH_OPTION;WITH_EXTERNALS" ${ARGN} ) set(dgraph_list ) set(edges) set(vertices) set(isolated_vertex_candidates) foreach(target_info ${target_directories}) # extract target_dir and option_name string(REPLACE "^^" "\\;" target_info ${target_info}) set(target_info_list ${target_info}) list(GET target_info_list 0 target_dir) list(GET target_info_list 1 option_name) #message(STATUS target_dir:${target_dir}) #message(STATUS option_name:${option_name}) #message(STATUS option_name-value:${${option_name}}) # make sure the directory exists if(NOT EXISTS ${target_dir}/CMakeLists.txt) message(FATAL_ERROR "Target directory ${target_dir}/CMakeLists.txt doesn't exists !") endif() set(include_dep 1) if(MY_WITH_OPTION) set(include_dep ${${option_name}}) endif() if(${include_dep}) # extract project name from CMakeLists.txt file(STRINGS "${target_dir}/CMakeLists.txt" project_string REGEX "^ *(P|p)(R|r)(O|o)(J|j)(E|e)(C|c)(T|t)\\(" LIMIT_COUNT 10) string(REGEX MATCH "\\((.*)\\)" target_project_name ${project_string}) string(REGEX REPLACE "\\(|\\)" "" target_project_name ${target_project_name}) if(${target_project_name} STREQUAL "") message(FATAL_ERROR "Failed to extract project name from ${target_dir}/CMakeLists.txt") endif() #message(STATUS target_project_name:${target_project_name}) # Make sure the variable is cleared set(dependencies ) # get dependencies ctkFunctionCollectTargetLibraryNames(${target_dir} dependencies) if(${target_project_name}_OPTIONAL_DEPENDENCIES) list(APPEND dependencies ${${target_project_name}_OPTIONAL_DEPENDENCIES}) endif() # Make sure the variable is cleared set(ctk_dependencies) if(MY_WITH_EXTERNALS) set(ctk_dependencies ${dependencies}) else() # filter dependencies starting with CTK org org_commontk_ ctkMacroGetAllProjectTargetLibraries("${dependencies}" ctk_dependencies) endif() if(ctk_dependencies) list(APPEND vertices ${target_project_name}) else() # isolated vertex candidate list(APPEND isolated_vertex_candidates ${target_project_name}) endif() # Generate XML related to the dependencies foreach(dependency_name ${ctk_dependencies}) list(APPEND edges ${dependency_name}) set(dgraph_list ${dgraph_list} "${target_project_name} ${dependency_name}\n") list(APPEND vertices ${dependency_name}) endforeach() endif() endforeach() foreach(isolated_vertex_candidate ${isolated_vertex_candidates}) set(_found 0) foreach(dgraph_entry ${dgraph_list}) string(REPLACE "\n" "" dgraph_entry "${dgraph_entry}") string(REPLACE " " ";" dgraph_entry "${dgraph_entry}") list(FIND dgraph_entry ${isolated_vertex_candidate} _index) if(_index GREATER -1) set(_found 1) break() endif() endforeach() if(NOT _found) list(APPEND vertices ${isolated_vertex_candidate}) set(dgraph_list "${isolated_vertex_candidate}\n" ${dgraph_list}) endif() endforeach() if(vertices) list(REMOVE_DUPLICATES vertices) endif() list(LENGTH vertices numberOfVertices) list(LENGTH edges numberOfEdges) set(dgraph_list "${numberOfVertices} ${numberOfEdges}\n" ${dgraph_list}) if(MY_WITH_OPTION) set(filename "${dir}/DGraphInput.txt") elseif(MY_WITH_EXTERNALS) set(filename "${dir}/DGraphInput-alldep-withext.txt") else() set(filename "${dir}/DGraphInput-alldep.txt") endif() file(WRITE ${filename} ${dgraph_list}) message(STATUS "Generated: ${filename}") endfunction() ctk-2026.09.02/CMake/ctkFunctionGeneratePluginManifest.cmake000066400000000000000000000073101524622605700235010ustar00rootroot00000000000000# # Depends on: # CTK/CMake/ctkMacroParseArguments.cmake # #! \ingroup CMakeUtilities function(ctkFunctionGeneratePluginManifest MANIFEST_QRC_FILEPATH_VAR) CtkMacroParseArguments(MY "ACTIVATIONPOLICY;CATEGORY;CONTACT_ADDRESS;COPYRIGHT;DESCRIPTION;DOC_URL;ICON;LICENSE;NAME;REQUIRE_PLUGIN;SYMBOLIC_NAME;VENDOR;VERSION;CUSTOM_HEADERS" "SKIP_QT5_ADD_RESOURCES" ${ARGN} ) # Sanity checks if(NOT DEFINED MY_SYMBOLIC_NAME) message(FATAL_ERROR "SYMBOLIC_NAME is mandatory") endif() # Defaults if(NOT DEFINED MY_SKIP_QT5_ADD_RESOURCES) set(MY_SKIP_QT5_ADD_RESOURCES FALSE) endif() set(_manifest_content "Plugin-SymbolicName: ${MY_SYMBOLIC_NAME}") if(DEFINED MY_ACTIVATIONPOLICY) string(TOLOWER "${MY_ACTIVATIONPOLICY}" _activation_policy) if(_activation_policy STREQUAL "eager") set(_manifest_content "${_manifest_content}\nPlugin-ActivationPolicy: eager") else() message(FATAL_ERROR "ACTIVATIONPOLICY is set to '${MY_ACTIVATIONPOLICY}', which is not supported") endif() endif() if(DEFINED MY_CATEGORY) set(_manifest_content "${_manifest_content}\nPlugin-Category: ${MY_CATEGORY}") endif() if(DEFINED MY_CONTACT_ADDRESS) set(_manifest_content "${_manifest_content}\nPlugin-ContactAddress: ${MY_CONTACT_ADDRESS}") endif() if(DEFINED MY_COPYRIGHT) set(_manifest_content "${_manifest_content}\nPlugin-Copyright: ${MY_COPYRIGHT}") endif() if(DEFINED MY_DESCRIPTION) set(_manifest_content "${_manifest_content}\nPlugin-Description: ${MY_DESCRIPTION}") endif() if(DEFINED MY_DOC_URL) set(_manifest_content "${_manifest_content}\nPlugin-DocURL: ${MY_DOC_URL}") endif() if(DEFINED MY_ICON) set(_manifest_content "${_manifest_content}\nPlugin-Icon: ${MY_ICON}") endif() if(DEFINED MY_LICENSE) set(_manifest_content "${_manifest_content}\nPlugin-License: ${MY_LICENSE}") endif() if(DEFINED MY_NAME) set(_manifest_content "${_manifest_content}\nPlugin-Name: ${MY_NAME}") endif() if(DEFINED MY_REQUIRE_PLUGIN) string(REPLACE ";" "," require_plugin "${MY_REQUIRE_PLUGIN}") set(_manifest_content "${_manifest_content}\nRequire-Plugin: ${require_plugin}") endif() if(DEFINED MY_VENDOR) set(_manifest_content "${_manifest_content}\nPlugin-Vendor: ${MY_VENDOR}") endif() if(DEFINED MY_VERSION) set(_manifest_content "${_manifest_content}\nPlugin-Version: ${MY_VERSION}") endif() if(DEFINED MY_CUSTOM_HEADERS) set(_manifest_content "${_manifest_content}\n") foreach(_custom_header ${MY_CUSTOM_HEADERS}) set(_manifest_content "${_manifest_content}\n${_custom_header}: ${${_custom_header}}") endforeach() endif() set(_manifest_filename "MANIFEST.MF") set(_manifest_filepath "${CMAKE_CURRENT_BINARY_DIR}/${_manifest_filename}") string(REPLACE "." "_" _symbolic_name ${MY_SYMBOLIC_NAME}) set(_manifest_qrc_filepath "${CMAKE_CURRENT_BINARY_DIR}/${_symbolic_name}_manifest.qrc") set(_manifest_qrc_content " ${_manifest_filename} ") configure_file("${CTK_CMAKE_DIR}/MANIFEST.MF.in" "${_manifest_filepath}" @ONLY) configure_file("${CTK_CMAKE_DIR}/plugin_manifest.qrc.in" "${_manifest_qrc_filepath}" @ONLY) if(MY_SKIP_QT5_ADD_RESOURCES) set(${MANIFEST_QRC_FILEPATH_VAR} ${_manifest_qrc_filepath} PARENT_SCOPE) else() if(CTK_QT_VERSION MATCHES "^(5|6)$") qt_add_resources(_qrc_src ${_manifest_qrc_filepath}) else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") endif() set(QRC_SRCS_VAR "${MANIFEST_QRC_FILEPATH_VAR}") set(${QRC_SRCS_VAR} ${${QRC_SRCS_VAR}} ${_qrc_src} PARENT_SCOPE) endif() endfunction() ctk-2026.09.02/CMake/ctkFunctionGeneratePluginUseFile.cmake000066400000000000000000000044111524622605700232660ustar00rootroot00000000000000########################################################################### # # Library: CTK # # Copyright (c) German Cancer Research Center, # Division of Medical and Biological Informatics # # 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 # # 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. # ########################################################################### #! Write a set of variables containing CTK plugin specific include and library directories #! \ingroup CMakeAPI function(ctkFunctionGeneratePluginUseFile filename) set(CTK_PLUGIN_INCLUDE_DIRS_CONFIG) foreach(plugin ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES}) set(${plugin}_INCLUDE_DIRS ) # The call to ctkFunctionGetIncludeDirs returns all include dirs # the plugin itself needs. This does not include the plugin's # source dir, so we add it explicitly. if(${plugin}_INCLUDE_SUFFIXES) foreach(_suffix ${${plugin}_INCLUDE_SUFFIXES}) list(APPEND ${plugin}_INCLUDE_DIRS ${${plugin}_SOURCE_DIR}/${_suffix}) endforeach() else() list(APPEND ${plugin}_INCLUDE_DIRS ${${plugin}_SOURCE_DIR}) endif() list(APPEND ${plugin}_INCLUDE_DIRS ${${plugin}_BINARY_DIR}) ctkFunctionGetIncludeDirs(${plugin}_INCLUDE_DIRS ${plugin}) set(CTK_PLUGIN_INCLUDE_DIRS_CONFIG "${CTK_PLUGIN_INCLUDE_DIRS_CONFIG} set(${plugin}_INCLUDE_DIRS \"${${plugin}_INCLUDE_DIRS}\")") ctkFunctionGetLibraryDirs(${plugin}_LIBRARY_DIRS ${plugin}) set(CTK_PLUGIN_LIBRARY_DIRS_CONFIG "${CTK_PLUGIN_LIBRARY_DIRS_CONFIG} set(${plugin}_LIBRARY_DIRS \"${${plugin}_LIBRARY_DIRS}\")") endforeach() set(_ctk_plugin_libraries_variable ${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES) set(_ctk_plugin_libraries ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES}) configure_file("${CTK_CMAKE_DIR}/../CMake/CTKPluginUseFile.cmake.in" "${filename}" @ONLY) endfunction() ctk-2026.09.02/CMake/ctkFunctionGetAllPluginTargets.cmake000066400000000000000000000014301524622605700227570ustar00rootroot00000000000000#! #! Stores all known plug-in targets (potentially also from external projects) #! in the variable specified by the first argument. #! #! \param var_targets A variable name containing the output. #! \ingroup CMakeUtilities function(ctkFunctionGetAllPluginTargets var_targets) if(NOT var_targets) message(FATAL_ERROR "Missing variable name in argument list") endif() set(plugin_targets ) get_property(CTK_PLUGIN_LIBRARIES_VARS GLOBAL PROPERTY CTK_PLUGIN_LIBRARIES_VARS) if(CTK_PLUGIN_LIBRARIES_VARS) list(REMOVE_DUPLICATES CTK_PLUGIN_LIBRARIES_VARS) foreach(_var ${CTK_PLUGIN_LIBRARIES_VARS}) if(${_var}) list(APPEND plugin_targets ${${_var}}) endif() endforeach() endif() set(${var_targets} ${plugin_targets} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionGetCompilerVisibilityFlags.cmake000066400000000000000000000042461524622605700243450ustar00rootroot00000000000000 #! #! \brief Helper macro which appends gcc compatible visibility flags to the #! variable given by RESULT_VAR. #! #! If supported, the flags -fvisibility=hidden and -fvisibility-inlines-hidden #! will be added. This applies to gcc >= 4.5 and Clang. #! #! Usage: #! ctkFunctionGetCompilerVisibilityFlags(RESULT_VAR) #! #! Example: #! #! \code #! set(myflags "-Werror") #! ctkFunctionGetCompilerVisibilityFlags(myflags) #! \endcode #! #! The variable \emph myflags will contain the string "-Werror -fvisibility -fvisibility-inlines-hidden" #! if for example gcc 4.6 is used. #! #! \ingroup CMakeUtilities function(ctkFunctionGetCompilerVisibilityFlags RESULT_VAR) # We only support hidden visibility for gcc for now. Clang 3.0 still has troubles with # correctly marking template declarations and explicit template instantiations as exported. # See http://comments.gmane.org/gmane.comp.compilers.clang.scm/50028 # and http://llvm.org/bugs/show_bug.cgi?id=10113 set(use_visibility_flags 0) if(CMAKE_COMPILER_IS_GNUCXX) set(use_visibility_flags 1) ctkFunctionGetGccVersion(${CMAKE_CXX_COMPILER} GCC_VERSION) # MinGW does not export all symbols automatically, so no need to set flags. # # With gcc < 4.5, RTTI symbols from classes declared in third-party libraries # which are not "gcc visibility aware" are marked with hidden visibility in # DSOs which include the class declaration and which are compiled with # hidden visibility. This leads to dynamic_cast and exception handling problems. # While this problem could be worked around by sandwiching the include # directives for the third-party headers between "#pragma visibility push/pop" # statements, it is generally safer to just use default visibility with # gcc < 4.5. if(${GCC_VERSION} VERSION_LESS "4.5" OR MINGW) set(use_visibility_flags 0) endif() endif() if(use_visibility_flags) set(visibility_flags "") ctkFunctionCheckCompilerFlags("-fvisibility=hidden" visibility_flags) ctkFunctionCheckCompilerFlags("-fvisibility-inlines-hidden" visibility_flags) set(${RESULT_VAR} "${${RESULT_VAR}} ${visibility_flags}" PARENT_SCOPE) endif() endfunction() ctk-2026.09.02/CMake/ctkFunctionGetGccVersion.cmake000066400000000000000000000024531524622605700216060ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### #! \ingroup CMakeUtilities function(ctkFunctionGetGccVersion path_to_gcc output_var) if(CMAKE_COMPILER_IS_GNUCXX) execute_process( COMMAND ${path_to_gcc} -dumpversion RESULT_VARIABLE result OUTPUT_VARIABLE output ERROR_VARIABLE error OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_STRIP_TRAILING_WHITESPACE ) if(result) message(FATAL_ERROR "Failed to obtain compiler version running [${path_to_gcc} -dumpversion]: ${error}") endif() set(${output_var} ${output} PARENT_SCOPE) endif() endfunction() ctk-2026.09.02/CMake/ctkFunctionGetIncludeDirs.cmake000066400000000000000000000075541524622605700217600ustar00rootroot00000000000000########################################################################### # # Library: CTK # # Copyright (c) German Cancer Research Center, # Division of Medical and Biological Informatics # # 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 # # 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. # ########################################################################### #! \ingroup CMakeUtilities function(ctkFunctionGetIncludeDirs var_include_dirs) if(NOT ARGN) message(FATAL_ERROR "No targets given") endif() get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) set(_include_dirs ${${var_include_dirs}} ${CTK_CONFIG_H_INCLUDE_DIR}) foreach(_target ${ARGN}) # Add the include directories from the plugin dependencies # The variable ${_target}_DEPENDENCIES is set in the # macro ctkMacroValidateBuildOptions set(ctk_deps ) set(ext_deps ) ctkMacroGetAllProjectTargetLibraries("${${_target}_DEPENDENCIES}" ctk_deps) ctkMacroGetAllNonProjectTargetLibraries("${${_target}_DEPENDENCIES}" ext_deps) foreach(dep ${ctk_deps}) if(${dep}_INCLUDE_SUFFIXES) foreach(_suffix ${${dep}_INCLUDE_SUFFIXES}) list(APPEND _include_dirs ${${dep}_SOURCE_DIR}/${_suffix}) endforeach() list(APPEND _include_dirs ${${dep}_BINARY_DIR}) else() list(APPEND _include_dirs ${${dep}_SOURCE_DIR} ${${dep}_BINARY_DIR} ) endif() list(APPEND _include_dirs # Ensure AUTOUIC-generated headers (ui_*.h) are on the include path. # # By default CMake writes them to: # # - Single-config generators (Ninja/Makefiles): # /include # # - Multi-config generators (VS, Xcode, Ninja Multi-Config): # /include_ # # where AUTOGEN_BUILD_DIR defaults to: # /_autogen # # References: # - https://cmake.org/cmake/help/latest/manual/cmake-qt.7.html#autouic # - https://cmake.org/cmake/help/latest/prop_tgt/AUTOGEN_BUILD_DIR.html ${${dep}_BINARY_DIR}/${dep}_autogen/include$<$:_$> ) # For external projects, CTKConfig.cmake contains variables # listening the include dirs for CTK libraries and plugins if(${dep}_INCLUDE_DIRS) list(APPEND _include_dirs ${${dep}_INCLUDE_DIRS}) endif() endforeach() foreach(dep ${ext_deps}) if(${dep}_INCLUDE_DIRS) string(REPLACE "^" ";" _ext_include_dirs "${${dep}_INCLUDE_DIRS}") list(APPEND _include_dirs ${_ext_include_dirs}) endif() # This is for resolving include dependencies between # libraries / plugins from external projects using CTK if(${dep}_SOURCE_DIR AND ${dep}_INCLUDE_SUFFIXES) foreach(_suffix ${${dep}_INCLUDE_SUFFIXES}) list(APPEND _include_dirs ${${dep}_SOURCE_DIR}/${_suffix}) endforeach() list(APPEND _include_dirs ${${dep}_BINARY_DIR}) elseif(${dep}_SOURCE_DIR) list(APPEND _include_dirs ${${dep}_SOURCE_DIR}) endif() if(${dep}_BINARY_DIR) list(APPEND _include_dirs ${${dep}_BINARY_DIR}) endif() endforeach() endforeach() if(_include_dirs) list(REMOVE_DUPLICATES _include_dirs) endif() set(${var_include_dirs} ${_include_dirs} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionGetLibraryDirs.cmake000066400000000000000000000032421524622605700217670ustar00rootroot00000000000000########################################################################### # # Library: CTK # # Copyright (c) German Cancer Research Center, # Division of Medical and Biological Informatics # # 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 # # 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. # ########################################################################### #! \ingroup CMakeUtilities function(ctkFunctionGetLibraryDirs var_library_dirs) if(NOT ARGN) message(FATAL_ERROR "No targets given") endif() set(_library_dirs ${${var_library_dirs}}) foreach(_target ${ARGN}) # Add the library directories from the external project # The variable ${_target}_DEPENDENCIES is set in the # macro ctkMacroValidateBuildOptions set(ext_deps ) ctkMacroGetAllNonProjectTargetLibraries("${${_target}_DEPENDENCIES}" ext_deps) foreach(dep ${ext_deps}) if(${dep}_LIBRARY_DIRS) string(REPLACE "^" ";" _ext_library_dirs "${${dep}_LIBRARY_DIRS}") list(APPEND _library_dirs ${_ext_library_dirs}) endif() endforeach() endforeach() if(_library_dirs) list(REMOVE_DUPLICATES _library_dirs) endif() set(${var_library_dirs} ${_library_dirs} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionGetPluginDependencies.cmake000066400000000000000000000021741524622605700233110ustar00rootroot00000000000000#! #! \brief Stores all known plug-in dependencies (potentially also from external projects) #! in the variable specified by the first argument. #! #! \param var_deps (required) A variable name containing the output. #! \param PLUGINS (required) A list of plug-ins (target names or symbolic names) for which the #! set of dependencies should be obtained. #! \param ALL (option) Include external dependencies. #! \ingroup CMakeUtilities function(ctkFunctionGetPluginDependencies var_deps) ctkMacroParseArguments(MY "PLUGINS" "ALL" ${ARGN}) # Sanity checks if(NOT var_deps) message(FATAL_ERROR "Missing variable name as the first argument for storing the result") endif() if(NOT MY_PLUGINS) message(FATAL_ERROR "Missing plug-in names") endif() if(MY_ALL) ctkFunctionGetTargetDependencies(_targets TARGETS ${MY_PLUGINS} ALL) else() ctkFunctionGetTargetDependencies(_targets TARGETS ${MY_PLUGINS}) endif() set(_plugins ) foreach(_target ${_targets}) if(_target MATCHES _) list(APPEND _plugins ${_target}) endif() endforeach() set(${var_deps} ${_plugins} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionGetTargetDependencies.cmake000066400000000000000000000026301524622605700232760ustar00rootroot00000000000000#! #! \brief Stores all target dependencies (potentially also from external projects) #! in the variable specified by the first argument. #! #! \param var_deps (required) A variable name containing the output. #! \param TARGETS (required) A list of targets (library targets or plug-in targets/symbolic names) #! for which the set of dependencies should be obtained. #! \param ALL (option) Include external dependencies. #! \ingroup CMakeUtilities function(ctkFunctionGetTargetDependencies var_deps) ctkMacroParseArguments(MY "TARGETS" "ALL" ${ARGN}) # Sanity checks if(NOT var_deps) message(FATAL_ERROR "Missing variable name as the first argument for storing the result") endif() if(NOT MY_TARGETS) message(FATAL_ERROR "Missing target names") endif() set(_targets ) foreach(_target ${MY_TARGETS}) # convenience conversion for plug-in targets string(REPLACE "." "_" _target ${_target}) # assume the variable ${_target}_DEPENDENCIES was set during # a previous invocation of the ctkMacroValidateBuildOptions macro. list(APPEND _targets ${${_target}_DEPENDENCIES}) endforeach() if (_targets) list(REMOVE_DUPLICATES _targets) if(NOT MY_ALL) # remove external targets not belonging to the current project ctkMacroGetAllProjectTargetLibraries("${_targets}" _targets) endif() endif() set(${var_deps} ${_targets} PARENT_SCOPE) endfunction() ctk-2026.09.02/CMake/ctkFunctionLFtoCRLF.cmake000066400000000000000000000036211524622605700204150ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### #! \ingroup CMakeUtilities function(ctkFunctionLFtoCRLF input_file output_file) # Make sure the file exists if(NOT EXISTS ${input_file}) message(FATAL_ERROR "Failed to convert LF to CRLF - File [${input_file}] does NOT exist !") endif() # Read lines file(STRINGS "${input_file}" lines) set(string_with_crlf) set(first_line TRUE) # Loop over lines and append \r\n foreach(line ${lines}) if(first_line) set(string_with_crlf ${line}) set(first_line FALSE) else() set(string_with_crlf "${string_with_crlf}\r\n${line}") endif() endforeach() file(WRITE ${output_file} ${string_with_crlf}) endfunction() # # Test - Use cmake -DFUNCTION_TESTING:BOOL=ON -DINPUT_FILE:FILEPATH= -DOUTPUT_FILE:FILEPATH= -P ctkFunctionLFtoCRLF.cmake # if(FUNCTION_TESTING) if(NOT DEFINED INPUT_FILE) message(FATAL_ERROR "INPUT_FILE is not defined !") endif() if(NOT DEFINED OUTPUT_FILE) message(FATAL_ERROR "OUTPUT_FILE is not defined !") endif() #message(STATUS "INPUT_FILE [${INPUT_FILE}]") #message(STATUS "OUTPUT_FILE [${OUTPUT_FILE}]") ctkFunctionLFtoCRLF("${INPUT_FILE}" "${OUTPUT_FILE}") endif() ctk-2026.09.02/CMake/ctkLinkerAsNeededFlagCheck.cmake000066400000000000000000000047371524622605700217520ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Linker --as-needed flag check # # Check if the linker will resolve symbols of underlinked libraries # # This script set the variable CTK_LINKER_NO_AS_NEEDED_FLAG_REQUIRED # to either TRUE or FALSE. # if(NOT DEFINED CTK_LINKER_NO_AS_NEEDED_FLAG_REQUIRED) message(STATUS "Checking if --no-as-needed linker flag is required") set(LINK_TEST_SOURCE_DIR ${CTK_CMAKE_DIR}/ctkLinkerAsNeededFlagCheck) set(LINK_TEST_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/ctkLinkerAsNeededFlagCheck) execute_process(COMMAND ${CMAKE_COMMAND} -E remove_directory ${LINK_TEST_BINARY_DIR}) try_compile(CTK_LINKER_LINKS_UNDERLINKED_LIBS ${LINK_TEST_BINARY_DIR} ${LINK_TEST_SOURCE_DIR} LINK_TEST ) if(CTK_LINKER_LINKS_UNDERLINKED_LIBS) set(CTK_LINKER_NO_AS_NEEDED_FLAG_REQUIRED FALSE CACHE INTERNAL "Test CTK_LINKER_NO_AS_NEEDED_FLAG_REQUIRED") message(STATUS "Checking if --no-as-needed linker flag is required - no") else() try_compile(CTK_LINKER_NO_AS_NEEDED_LINKS_UNDERLINKED_LIBS ${LINK_TEST_BINARY_DIR} ${LINK_TEST_SOURCE_DIR} LINK_TEST_FLAGS CMAKE_FLAGS -DCMAKE_EXE_LINKER_FLAGS=-Wl,--no-as-needed ) if(CTK_LINKER_NO_AS_NEEDED_LINKS_UNDERLINKED_LIBS) set(CTK_LINKER_NO_AS_NEEDED_FLAG_REQUIRED TRUE CACHE INTERNAL "Test CTK_LINKER_NO_AS_NEEDED_FLAG_REQUIRED") message(STATUS "Checking if --no-as-needed linker flag is required - yes") else() message(STATUS "Checking if --no-as-needed linker flag is required - failed.") message(WARNING "Could not compile test code." "Linker could fail trying to resolve symbols for underlinked libraries." "See issue 2321 (http://na-mic.org/Mantis/view.php?id=2321) for more details.") endif() endif() endif() ctk-2026.09.02/CMake/ctkLinkerAsNeededFlagCheck/000077500000000000000000000000001524622605700207355ustar00rootroot00000000000000ctk-2026.09.02/CMake/ctkLinkerAsNeededFlagCheck/A.cpp000066400000000000000000000000431524622605700216160ustar00rootroot00000000000000int B(); int A() { return B(); } ctk-2026.09.02/CMake/ctkLinkerAsNeededFlagCheck/B.cpp000066400000000000000000000000311524622605700216140ustar00rootroot00000000000000int B() { return 10; } ctk-2026.09.02/CMake/ctkLinkerAsNeededFlagCheck/C.cpp000066400000000000000000000000461524622605700216230ustar00rootroot00000000000000int A(); int main() { return A(); } ctk-2026.09.02/CMake/ctkLinkerAsNeededFlagCheck/CMakeLists.txt000066400000000000000000000004601524622605700234750ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.20.6 FATAL_ERROR) project(ctkLinkerAsNeededFlagCheck) add_library(A SHARED A.cpp) add_library(B SHARED B.cpp) # No need to use ctk_add_executable_utf8 since there are # no special characters are involved in this test. add_executable(C C.cpp) target_link_libraries(C B A) ctk-2026.09.02/CMake/ctkListToString.cmake000066400000000000000000000115531524622605700200040ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### function(ctk_list_to_string separator input_list output_string_var) if(${CMAKE_VERSION} VERSION_EQUAL "3.12" OR ${CMAKE_VERSION} VERSION_GREATER "3.12") string(JOIN "${separator}" _string ${input_list}) set(${output_string_var} ${_string} PARENT_SCOPE) return() endif() set(_string "") cmake_policy(PUSH) cmake_policy(SET CMP0007 OLD) # Get list length list(LENGTH input_list list_length) # If the list has 0 or 1 element, there is no need to loop over. if(list_length LESS 2) set(_string "${input_list}") else() math(EXPR last_element_index "${list_length} - 1") foreach(index RANGE ${last_element_index}) # Get current item_value list(GET input_list ${index} item_value) # .. and append to output string set(_string "${_string}${item_value}") # Append separator if current element is NOT the last one. if(NOT index EQUAL last_element_index) set(_string "${_string}${separator}") endif() endforeach() endif() set(${output_string_var} ${_string} PARENT_SCOPE) cmake_policy(POP) endfunction() # # cmake -DTEST_ctk_list_to_string_test:BOOL=ON -P ListToString.cmake # function(ctk_list_to_string_test) function(ctk_list_to_string_test_check id current_output expected_output) if(NOT "${current_output}" STREQUAL "${expected_output}") message(FATAL_ERROR "Problem with ctk_list_to_string() - See testcase: ${id}\n" "current_output:${current_output}\n" "expected_output:${expected_output}") endif() endfunction() set(id 1) set(case${id}_input "") set(case${id}_expected_output "") ctk_list_to_string("^^" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 2) set(case${id}_input item1) set(case${id}_expected_output "item1") ctk_list_to_string("^^" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 3) set(case${id}_input item1 item2) set(case${id}_expected_output "item1^^item2") ctk_list_to_string("^^" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 4) set(case${id}_input item1 item2 item3) set(case${id}_expected_output "item1^^item2^^item3") ctk_list_to_string("^^" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 5) set(case${id}_input item1 item2 item3 item4) set(case${id}_expected_output "item1^^item2^^item3^^item4") ctk_list_to_string("^^" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 6) set(case${id}_input item1 "" item3 item4) set(case${id}_expected_output "item1^^item3^^item4") ctk_list_to_string("^^" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 7) set(case${id}_input item1 ^^item2 item3 item4) set(case${id}_expected_output "item1^^^^item2^^item3^^item4") ctk_list_to_string("^^" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 8) set(case${id}_input item1 item2 item3 item4) set(case${id}_expected_output "item1item2item3item4") ctk_list_to_string("" "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") set(id 9) set(case${id}_input item1 item2 item3 item4) set(case${id}_expected_output "item1 item2 item3 item4") ctk_list_to_string(" " "${case${id}_input}" case${id}_current_output) ctk_list_to_string_test_check(${id} "${case${id}_current_output}" "${case${id}_expected_output}") message("SUCCESS") endfunction() if(TEST_ctk_list_to_string_test) ctk_list_to_string_test() endif() ctk-2026.09.02/CMake/ctkMacroAddCtkLibraryOptions.cmake000066400000000000000000000030441524622605700224100ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### #! \ingroup CMakeUtilities macro(ctkMacroAddCtkLibraryOptions lib) set(filepath ${CMAKE_CURRENT_SOURCE_DIR}/Libs/${lib}/ctk_library_options.cmake) # Add options only if "ctk_library_option.cmake" file exists if(EXISTS ${filepath}) # Make sure the variable is cleared set(ctk_library_options ) include(${filepath}) foreach(option ${ctk_library_options}) ctkFunctionExtractOptionNameAndValue(${option} option_name option_value) option(CTK_LIB_${lib}_${option_name} "Enable ${lib} Library ${option_name} option." ${option_value}) message(STATUS "CTK_LIB_${lib}_${option_name} is ${CTK_LIB_${lib}_${option_name}}") mark_as_advanced(CTK_LIB_${lib}_${option_name}) mark_as_superbuild(CTK_LIB_${lib}_${option_name}) endforeach() endif() endmacro() ctk-2026.09.02/CMake/ctkMacroBuildApp.cmake000066400000000000000000000071451524622605700200630ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Depends on: # CTK/CMake/ctkMacroParseArguments.cmake # #! \ingroup CMakeAPI macro(ctkMacroBuildApp) ctkMacroParseArguments(MY "NAME;SRCS;MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;RESOURCES" "INSTALL" ${ARGN} ) # Keep parameter 'INCLUDE_DIRECTORIES' for backward compatibility # Sanity checks if(NOT DEFINED MY_NAME) message(FATAL_ERROR "NAME is mandatory") endif() # Make sure either the source or the binary directory associated with the application # contains a file named ${MY_NAME}Main.cpp set(expected_mainfile ${MY_NAME}Main.cpp) if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${expected_mainfile} AND NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${expected_mainfile}.in AND NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/${expected_mainfile}) message(FATAL_ERROR "Application directory: ${MY_NAME} should contain" " a file named ${expected_mainfile} or ${expected_mainfile}.in") endif() # Define library name set(proj_name ${MY_NAME}) # -------------------------------------------------------------------------- # Include dirs set(my_includes ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # Add the include directories from the library dependencies ctkFunctionGetIncludeDirs(my_includes ${proj_name}) include_directories(${my_includes}) # Add the library directories from the external project ctkFunctionGetLibraryDirs(my_library_dirs ${proj_name}) link_directories( ${my_library_dirs} ) source_group("Resources" FILES ${MY_RESOURCES} ${MY_UI_FORMS} ) # Create executable ctk_add_executable_utf8(${proj_name} ${MY_SRCS} ${MY_RESOURCES} ) target_compile_definitions(${proj_name} PRIVATE HAVE_QT${CTK_QT_VERSION} ) # Configure CMake Qt automatic code generation set(uic_search_paths) foreach(ui_src IN LISTS MY_UI_FORMS) if(NOT IS_ABSOLUTE ${ui_src}) set(ui_src "${CMAKE_CURRENT_SOURCE_DIR}/${ui_src}") endif() get_filename_component(ui_path ${ui_src} PATH) list(APPEND uic_search_paths ${ui_path}) endforeach() list(REMOVE_DUPLICATES uic_search_paths) set_target_properties(${proj_name} PROPERTIES AUTOMOC ON AUTORCC ON AUTOUIC ON AUTOUIC_SEARCH_PATHS "${uic_search_paths}" ) # Set labels associated with the target. set_target_properties(${proj_name} PROPERTIES LABELS ${proj_name}) # Install rules install(TARGETS ${proj_name} RUNTIME DESTINATION ${CTK_INSTALL_BIN_DIR} COMPONENT RuntimeApplications ) set(my_libs ${MY_TARGET_LIBRARIES} ) target_link_libraries(${proj_name} ${my_libs}) # Install headers if(MY_INSTALL) file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h") install(FILES ${headers} ${dynamicHeaders} DESTINATION ${CTK_INSTALL_INCLUDE_DIR} COMPONENT Development ) endif() endmacro() ctk-2026.09.02/CMake/ctkMacroBuildLib.cmake000066400000000000000000000126411524622605700200460ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Depends on: # CTK/CMake/ctkMacroParseArguments.cmake # #! \brief Build a CTK library. #! #! \ingroup CMakeAPI macro(ctkMacroBuildLib) ctkMacroParseArguments(MY "NAME;EXPORT_DIRECTIVE;SRCS;MOC_SRCS;GENERATE_MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;RESOURCES;LIBRARY_TYPE;EXPORT_CUSTOM_CONTENT_FROM_VARIABLE" "ENABLE_QTTESTING" ${ARGN} ) # Keep parameter 'INCLUDE_DIRECTORIES' for backward compatibility # Sanity checks if(NOT DEFINED MY_NAME) message(FATAL_ERROR "NAME is mandatory") endif() string(REGEX MATCH "^CTK.+" valid_library_name ${MY_NAME}) if(NOT valid_library_name) message(FATAL_ERROR "CTK library name [${MY_NAME}] should start with 'CTK' uppercase !") endif() if(NOT DEFINED MY_EXPORT_DIRECTIVE) message(FATAL_ERROR "EXPORT_DIRECTIVE is mandatory") endif() if(NOT DEFINED MY_LIBRARY_TYPE) set(MY_LIBRARY_TYPE "SHARED") endif() # Define library name set(lib_name ${MY_NAME}) # Library target names must not contain a '_' (reserved for plug-in target names) if(lib_name MATCHES _) message(FATAL_ERROR "The library name ${lib_name} must not contain a '_' character.") endif() # -------------------------------------------------------------------------- # Include dirs set(my_includes ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CTK_SOURCE_DIR}/Libs # for ctkDeprecated.h ) # Add the include directories from the library dependencies ctkFunctionGetIncludeDirs(my_includes ${lib_name}) include_directories( ${my_includes} ) # Add the library directories from the external project ctkFunctionGetLibraryDirs(my_library_dirs ${lib_name}) link_directories( ${my_library_dirs} ) set(MY_LIBRARY_EXPORT_DIRECTIVE ${MY_EXPORT_DIRECTIVE}) set(MY_EXPORT_HEADER_PREFIX ${MY_NAME}) string(REGEX REPLACE "^CTK" "ctk" MY_EXPORT_HEADER_PREFIX ${MY_EXPORT_HEADER_PREFIX}) set(MY_LIBNAME ${lib_name}) set(CTK_EXPORT_CUSTOM_CONTENT "") if(MY_EXPORT_CUSTOM_CONTENT_FROM_VARIABLE) if(DEFINED "${MY_EXPORT_CUSTOM_CONTENT_FROM_VARIABLE}") set(CTK_EXPORT_CUSTOM_CONTENT "// ------- Expanded from \@CTK_EXPORT_CUSTOM_CONTENT\@ ------- ${${MY_EXPORT_CUSTOM_CONTENT_FROM_VARIABLE}} // ------------------------------------------------ ") endif() endif() configure_file( ${CTK_SOURCE_DIR}/Libs/ctkExport.h.in ${CMAKE_CURRENT_BINARY_DIR}/${MY_EXPORT_HEADER_PREFIX}Export.h ) set(dynamicHeaders "${dynamicHeaders};${CMAKE_CURRENT_BINARY_DIR}/${MY_EXPORT_HEADER_PREFIX}Export.h") source_group("Resources" FILES ${MY_RESOURCES} ${MY_UI_FORMS} ) add_library(${lib_name} ${MY_LIBRARY_TYPE} ${MY_SRCS} ${MY_RESOURCES} ) target_compile_definitions(${lib_name} PUBLIC CTK_DISABLE_DEPRECATED_BEFORE=${CTK_DISABLE_DEPRECATED_BEFORE} PRIVATE HAVE_QT${CTK_QT_VERSION} ) # Configure CMake Qt automatic code generation set_target_properties(${lib_name} PROPERTIES AUTOMOC ON AUTORCC ON AUTOUIC ON AUTOUIC_SEARCH_PATHS "${CMAKE_CURRENT_SOURCE_DIR}/Resources/UI" ) # Set labels associated with the target. set_target_properties(${lib_name} PROPERTIES LABELS ${lib_name}) # Apply user-defined properties to the library target. if(CTK_LIBRARY_PROPERTIES AND MY_LIBRARY_TYPE STREQUAL "SHARED") set_target_properties(${lib_name} PROPERTIES ${CTK_LIBRARY_PROPERTIES}) endif() set_target_properties(${lib_name} PROPERTIES CTK_LIB_TARGET_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) # Library properties specific to STATIC build if(MY_LIBRARY_TYPE STREQUAL "STATIC") if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit set_target_properties(${lib_name} PROPERTIES COMPILE_FLAGS "-fPIC") endif() endif() # Install rules if(MY_LIBRARY_TYPE STREQUAL "SHARED") install(TARGETS ${lib_name} EXPORT CTKExports RUNTIME DESTINATION ${CTK_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries LIBRARY DESTINATION ${CTK_INSTALL_LIB_DIR} COMPONENT RuntimeLibraries ARCHIVE DESTINATION ${CTK_INSTALL_LIB_DIR} COMPONENT Development) endif() set(my_libs ${MY_TARGET_LIBRARIES} ) if(MINGW) list(APPEND my_libs ssp) # add stack smash protection lib endif() target_link_libraries(${lib_name} ${my_libs}) # Update CTK_BASE_LIBRARIES set(CTK_BASE_LIBRARIES ${my_libs} ${lib_name} CACHE INTERNAL "CTK base libraries" FORCE) set(CTK_LIBRARIES ${CTK_LIBRARIES} ${lib_name} CACHE INTERNAL "CTK libraries" FORCE) # Install headers file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.tpp") install(FILES ${headers} ${dynamicHeaders} DESTINATION ${CTK_INSTALL_INCLUDE_DIR} COMPONENT Development ) endmacro() ctk-2026.09.02/CMake/ctkMacroBuildLibWrapper.cmake000066400000000000000000000145631524622605700214140ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Depends on: # CTK/CMake/ctkMacroParseArguments.cmake # #! When CTK is built as shared library, the following macro builds a python module #! associated with the generated PythonQt wrappers. When loaded, it will #! dynamically loads both the (1) generated decorators and the (2) hand written one. #! On the other hand, when CTK is built statically, it creates a #! static library providing a initialization function that will allow to load #! both (1) and (2). # Function copied from https://github.com/scikit-build/scikit-build/pull/299 # XXX Update this CMake module to use function from scikit-build to build the wrapper function(_ctk_set_python_extension_symbol_visibility _target) set(_modinit_prefix "PyInit_") if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") set_target_properties(${_target} PROPERTIES LINK_FLAGS "/EXPORT:${_modinit_prefix}${_target}" ) elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") set(_script_path ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target}-version-script.map ) file(WRITE ${_script_path} "{global: ${_modinit_prefix}${_target}; local: *; };" ) set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS " -Wl,--version-script=${_script_path}" ) endif() endfunction() #! \ingroup CMakeAPI macro(ctkMacroBuildLibWrapper) ctkMacroParseArguments(MY "NAMESPACE;TARGET;SRCS;WRAPPER_LIBRARY_TYPE;ARCHIVE_OUTPUT_DIRECTORY;LIBRARY_OUTPUT_DIRECTORY;RUNTIME_OUTPUT_DIRECTORY;INSTALL_BIN_DIR;INSTALL_LIB_DIR" "NO_INSTALL" ${ARGN} ) # Sanity checks if(NOT DEFINED MY_TARGET) message(FATAL_ERROR "NAME is mandatory") endif() if(NOT DEFINED MY_WRAPPER_LIBRARY_TYPE OR "${MY_WRAPPER_LIBRARY_TYPE}" STREQUAL "SHARED") set(MY_WRAPPER_LIBRARY_TYPE "MODULE") endif() if(NOT DEFINED MY_NAMESPACE) set(MY_NAMESPACE "org.commontk") endif() foreach(type RUNTIME LIBRARY ARCHIVE) if(NOT DEFINED MY_${type}_OUTPUT_DIRECTORY) set(MY_${type}_OUTPUT_DIRECTORY ${CMAKE_${type}_OUTPUT_DIRECTORY}) endif() endforeach() if(NOT DEFINED MY_INSTALL_BIN_DIR) set(MY_INSTALL_BIN_DIR ${CTK_INSTALL_BIN_DIR}) endif() if(NOT DEFINED MY_INSTALL_LIB_DIR) set(MY_INSTALL_LIB_DIR ${CTK_INSTALL_LIB_DIR}) endif() # Define library name set(lib_name ${MY_TARGET}) # Include dirs set(my_includes ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # Since the PythonQt decorator depends on PythonQt, Python and VTK, let's link against # these ones to avoid complaints of MSVC # Note: "LINK_DIRECTORIES" has to be invoked before "ADD_LIBRARY" ctkFunctionExtractOptimizedLibrary(PYTHON_LIBRARIES PYTHON_LIBRARY) set(my_EXTRA_PYTHON_LIBRARIES ${PYTHON_LIBRARY} ${PYTHONQT_LIBRARIES}) # Does a header having the expected filename exists ? string(REGEX REPLACE "^CTK" "ctk" lib_name_lc_ctk ${lib_name}) set(DECORATOR_HEADER ${lib_name_lc_ctk}PythonQtDecorators.h) set(HAS_DECORATOR FALSE) set(_msg "Looking for decorator header ${DECORATOR_HEADER}") message(STATUS "${_msg}") set(_status "Not found") if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${DECORATOR_HEADER}) set(HAS_DECORATOR TRUE) set(DECORATOR_HEADER ${DECORATOR_HEADER}) set_source_files_properties(${DECORATOR_HEADER} WRAP_EXCLUDE) set(_status "Found") endif() message(STATUS "${_msg} - ${_status}") #message("path/to/DECORATOR_HEADER:${CMAKE_CURRENT_SOURCE_DIR}/${DECORATOR_HEADER}") set(KIT_PYTHONQT_SRCS) # Clear variable ctkMacroWrapPythonQt(${MY_NAMESPACE} ${lib_name} KIT_PYTHONQT_SRCS "${MY_SRCS}" FALSE ${HAS_DECORATOR}) if(HAS_DECORATOR) list(APPEND KIT_PYTHONQT_SRCS ${DECORATOR_HEADER}) endif() add_library(${lib_name}PythonQt ${MY_WRAPPER_LIBRARY_TYPE} ${KIT_PYTHONQT_SRCS}) target_link_libraries(${lib_name}PythonQt ${lib_name} ${my_EXTRA_PYTHON_LIBRARIES}) if(MY_WRAPPER_LIBRARY_TYPE STREQUAL "STATIC") if(CMAKE_SIZEOF_VOID_P EQUAL 8) # 64-bit set_target_properties(${lib_name}PythonQt PROPERTIES COMPILE_FLAGS "-fPIC") endif() endif() if(MY_WRAPPER_LIBRARY_TYPE STREQUAL "MODULE") # Make sure that no prefix is set on the library set_target_properties(${lib_name}PythonQt PROPERTIES PREFIX "") # Python extension modules on Windows must have the extension ".pyd" # instead of ".dll" as of Python 2.5. Older python versions do support # this suffix. # See http://docs.python.org/faq/windows.html#is-a-pyd-file-the-same-as-a-dll if(WIN32 AND NOT CYGWIN) set_target_properties(${lib_name}PythonQt PROPERTIES SUFFIX ".pyd") endif() endif() _ctk_set_python_extension_symbol_visibility(${lib_name}PythonQt) set_target_properties(${lib_name}PythonQt PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${MY_RUNTIME_OUTPUT_DIRECTORY}" LIBRARY_OUTPUT_DIRECTORY "${MY_LIBRARY_OUTPUT_DIRECTORY}" ARCHIVE_OUTPUT_DIRECTORY "${MY_ARCHIVE_OUTPUT_DIRECTORY}" ) # Configure CMake Qt automatic code generation set_target_properties(${lib_name}PythonQt PROPERTIES AUTOMOC ON ) # Set labels associated with the target. set_target_properties(${lib_name}PythonQt PROPERTIES LABELS ${lib_name}) # Update list of libraries wrapped with PythonQt set(CTK_WRAPPED_LIBRARIES_PYTHONQT ${CTK_WRAPPED_LIBRARIES_PYTHONQT} ${lib_name} CACHE INTERNAL "CTK libraries wrapped using PythonQt" FORCE) # Install rules if(NOT MY_NO_INSTALL AND MY_WRAPPER_LIBRARY_TYPE STREQUAL "MODULE") install(TARGETS ${lib_name}PythonQt RUNTIME DESTINATION ${MY_INSTALL_LIB_DIR} COMPONENT RuntimePlugins LIBRARY DESTINATION ${MY_INSTALL_LIB_DIR} COMPONENT RuntimePlugins ARCHIVE DESTINATION ${MY_INSTALL_LIB_DIR} COMPONENT Development) endif() endmacro() ctk-2026.09.02/CMake/ctkMacroBuildPlugin.cmake000066400000000000000000000274251524622605700206040ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Depends on: # CTK/CMake/ctkMacroParseArguments.cmake # CTK/CMake/ctkMacroGeneratePluginManifest.cmake # #! \brief Build a CTK plug-in. #! #! This macro takes the usual arguments for building #! a shared library using Qt. Additionally, it generates #! plugin meta-data by creating a MANIFEST.MF text file #! which is embedded in the share library as a Qt resource. #! #! The following variables can be set in a file named #! manifest_headers.cmake, which will then be read by #! this macro: #! #! - Plugin-ActivationPolicy #! - Plugin-Category #! - Plugin-ContactAddress #! - Plugin-Copyright #! - Plugin-Description #! - Plugin-DocURL #! - Plugin-Icon #! - Plugin-License #! - Plugin-Name #! - Require-Plugin #! - Plugin-Vendor #! - Plugin-Version #! #! \ingroup CMakeAPI macro(ctkMacroBuildPlugin) CtkMacroParseArguments(MY "EXPORT_DIRECTIVE;SRCS;MOC_SRCS;MOC_OPTIONS;UI_FORMS;INCLUDE_DIRECTORIES;EXPORTED_INCLUDE_SUFFIXES;TARGET_LIBRARIES;RESOURCES;CACHED_RESOURCEFILES;TRANSLATIONS;OUTPUT_DIR" "TEST_PLUGIN;NO_INSTALL" ${ARGN} ) # Keep parameter 'INCLUDE_DIRECTORIES' for backward compatibility # Sanity checks if(NOT DEFINED MY_EXPORT_DIRECTIVE) message(FATAL_ERROR "EXPORT_DIRECTIVE is mandatory") endif() # Print a warning if the project name does not match the directory name get_filename_component(_dir_name ${CMAKE_CURRENT_SOURCE_DIR} NAME) string(REPLACE "." "_" _dir_name_with_ ${_dir_name}) if(NOT _dir_name_with_ STREQUAL ${PROJECT_NAME}) message(WARNING "Discouraged mismatch of plug-in project name [${PROJECT_NAME}] and top-level directory name [${CMAKE_CURRENT_SOURCE_DIR}].") endif() # Define library name set(lib_name ${PROJECT_NAME}) # Plug-in target names must contain at least one _ if(NOT lib_name MATCHES _) message(FATAL_ERROR "The plug-in project name ${lib_name} must contain at least one '_' character") endif() # Plugin are expected to be shared library set(MY_LIBRARY_TYPE "SHARED") # Clear the variables for the manifest headers set(Plugin-ActivationPolicy ) set(Plugin-Category ) set(Plugin-ContactAddress ) set(Plugin-Copyright ) set(Plugin-Description ) set(Plugin-DocURL ) set(Plugin-Icon ) set(Plugin-License ) set(Plugin-Name ) set(Require-Plugin ) set(Plugin-SymbolicName ) set(Plugin-Vendor ) set(Plugin-Version ) set(Custom-Headers ) if(MY_TEST_PLUGIN) # Since the test plug-ins are not considered when calculating # target dependencies via DGraph, we add the dependencies # manually here #message("${lib_name}_DEPENDENCIES ${MY_TARGET_LIBRARIES}") list(APPEND ${lib_name}_DEPENDENCIES ${MY_TARGET_LIBRARIES}) endif() # If a file named manifest_headers.cmake exists, read it set(manifest_headers_dep ) if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/manifest_headers.cmake") include(${CMAKE_CURRENT_SOURCE_DIR}/manifest_headers.cmake) set(manifest_headers_dep "${CMAKE_CURRENT_SOURCE_DIR}/manifest_headers.cmake") endif() string(REPLACE "_" "." Plugin-SymbolicName ${lib_name}) # -------------------------------------------------------------------------- # Include dirs if(MY_EXPORTED_INCLUDE_SUFFIXES) set(${lib_name}_INCLUDE_SUFFIXES ${MY_EXPORTED_INCLUDE_SUFFIXES} CACHE INTERNAL "List of exported plugin include dirs") set(my_includes ) foreach(_suffix ${MY_EXPORTED_INCLUDE_SUFFIXES}) list(APPEND my_includes ${CMAKE_CURRENT_SOURCE_DIR}/${_suffix}) endforeach() else() set(${lib_name}_INCLUDE_SUFFIXES "" CACHE INTERNAL "List of exported plugin include dirs") set(my_includes ) endif() list(APPEND my_includes ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ) # Add the include directories from the plugin dependencies # and external dependencies ctkFunctionGetIncludeDirs(my_includes ${lib_name}) find_package(Qt${CTK_QT_VERSION} COMPONENTS LinguistTools REQUIRED) # Add the library directories from the external project ctkFunctionGetLibraryDirs(my_library_dirs ${lib_name}) link_directories( ${my_library_dirs} ) set(MY_LIBRARY_EXPORT_DIRECTIVE ${MY_EXPORT_DIRECTIVE}) set(MY_EXPORT_HEADER_PREFIX "${lib_name}_") set(MY_LIBNAME ${lib_name}) configure_file( ${CTK_EXPORT_HEADER_TEMPLATE} ${CMAKE_CURRENT_BINARY_DIR}/${MY_EXPORT_HEADER_PREFIX}Export.h ) set(dynamicHeaders "${dynamicHeaders};${CMAKE_CURRENT_BINARY_DIR}/${MY_EXPORT_HEADER_PREFIX}Export.h") # Make sure variable are cleared set(MY_RESOURCES) # Add the generated manifest qrc file set(manifest_qrc_filepath ) ctkFunctionGeneratePluginManifest(manifest_qrc_filepath ACTIVATIONPOLICY ${Plugin-ActivationPolicy} CATEGORY ${Plugin-Category} CONTACT_ADDRESS ${Plugin-ContactAddress} COPYRIGHT ${Plugin-Copyright} DESCRIPTION ${Plugin-Description} DOC_URL ${Plugin-DocURL} ICON ${Plugin-Icon} LICENSE ${Plugin-License} NAME ${Plugin-Name} REQUIRE_PLUGIN ${Require-Plugin} SYMBOLIC_NAME ${Plugin-SymbolicName} VENDOR ${Plugin-Vendor} VERSION ${Plugin-Version} CUSTOM_HEADERS ${Custom-Headers} SKIP_QT5_ADD_RESOURCES ) list(APPEND MY_RESOURCES ${manifest_qrc_filepath} ) # Create translation files (.ts and .qm) set(_plugin_qm_files ) set(_plugin_cached_resources_in_binary_tree ) set(_translations_dir "${CMAKE_CURRENT_BINARY_DIR}/CTK-INF/l10n") if(MY_TRANSLATIONS) set_source_files_properties(${MY_TRANSLATIONS} PROPERTIES OUTPUT_LOCATION ${_translations_dir}) if(CTK_QT_VERSION MATCHES "^(5|6)$") qt_create_translation(_plugin_qm_files ${MY_SRCS} ${MY_UI_FORMS} ${MY_TRANSLATIONS}) else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") endif() endif() if(_plugin_qm_files) foreach(_qm_file ${_plugin_qm_files}) file(RELATIVE_PATH _relative_qm_file ${CMAKE_CURRENT_BINARY_DIR} ${_qm_file}) list(APPEND _plugin_cached_resources_in_binary_tree ${_relative_qm_file}) endforeach() endif() set(_plugin_cached_resources_in_source_tree ) if(MY_CACHED_RESOURCEFILES) foreach(_cached_resource ${MY_CACHED_RESOURCEFILES}) if(IS_ABSOLUTE "${_cached_resource}") # create a path relative to the current binary dir file(RELATIVE_PATH _relative_cached_resource ${CMAKE_CURRENT_BINARY_DIR} ${_cached_resource}) list(APPEND _plugin_cached_resources_in_binary_tree ${_relative_cached_resource}) else() list(APPEND _plugin_cached_resources_in_source_tree ${_cached_resource}) endif() endforeach() endif() # Add any other additional resource files if(_plugin_cached_resources_in_source_tree OR _plugin_cached_resources_in_binary_tree) string(REPLACE "." "_" _plugin_symbolicname ${Plugin-SymbolicName}) set(plugin_qrc_filepath) ctkMacroGeneratePluginResourcefile(plugin_qrc_filepath NAME ${_plugin_symbolicname}_cached.qrc PREFIX ${Plugin-SymbolicName} RESOURCES ${_plugin_cached_resources_in_source_tree} BINARY_RESOURCES ${_plugin_cached_resources_in_binary_tree} SKIP_QT5_ADD_RESOURCES ) list(APPEND MY_RESOURCES ${plugin_qrc_filepath} ) endif() source_group("Resources" FILES ${MY_RESOURCES} ${MY_UI_FORMS} ${MY_TRANSLATIONS} ) source_group("Generated" FILES ${_plugin_qm_files} ) add_library(${lib_name} ${MY_LIBRARY_TYPE} ${MY_SRCS} ${MY_RESOURCES} ${_plugin_qm_files} ) target_compile_definitions(${lib_name} PRIVATE HAVE_QT${CTK_QT_VERSION} ) target_include_directories(${lib_name} PUBLIC "$" "$" ) # Configure CMake Qt automatic code generation set(uic_search_paths) foreach(ui_src IN LISTS MY_UI_FORMS) if(NOT IS_ABSOLUTE ${ui_src}) set(ui_src "${CMAKE_CURRENT_SOURCE_DIR}/${ui_src}") endif() get_filename_component(ui_path ${ui_src} PATH) list(APPEND uic_search_paths ${ui_path}) endforeach() list(REMOVE_DUPLICATES uic_search_paths) set_target_properties(${lib_name} PROPERTIES AUTOMOC ON AUTORCC ON AUTOUIC ON AUTOUIC_SEARCH_PATHS "${uic_search_paths}" ) if(MY_TEST_PLUGIN) find_package(Qt${CTK_QT_VERSION} COMPONENTS Test REQUIRED) target_link_libraries(${lib_name} PRIVATE Qt${CTK_QT_VERSION}::Test) endif() # Set the output directory for the plugin if(MY_OUTPUT_DIR) set(output_dir_suffix "/${MY_OUTPUT_DIR}") else() set(output_dir_suffix "") endif() foreach(type RUNTIME LIBRARY ARCHIVE) if(NOT DEFINED CTK_PLUGIN_${type}_OUTPUT_DIRECTORY AND CMAKE_${type}_OUTPUT_DIRECTORY) # Put plug-ins by default into a "plugins" subdirectory set(CTK_PLUGIN_${type}_OUTPUT_DIRECTORY "${CMAKE_${type}_OUTPUT_DIRECTORY}/plugins") endif() if(IS_ABSOLUTE "${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}") set(plugin_${type}_output_dir "${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}${output_dir_suffix}") elseif(CMAKE_${type}_OUTPUT_DIRECTORY) set(plugin_${type}_output_dir "${CMAKE_${type}_OUTPUT_DIRECTORY}/${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}${output_dir_suffix}") else() set(plugin_${type}_output_dir "${CMAKE_CURRENT_BINARY_DIR}/${CTK_PLUGIN_${type}_OUTPUT_DIRECTORY}${output_dir_suffix}") endif() if(MY_TEST_PLUGIN) # Test plug-ins will always be put in a separate directory if(CMAKE_${type}_OUTPUT_DIRECTORY) set(plugin_${type}_output_dir "${CMAKE_${type}_OUTPUT_DIRECTORY}/test_plugins") else() set(plugin_${type}_output_dir "${PROJECT_BINARY_DIR}/test_plugins") endif() endif() endforeach() set(plugin_compile_flags "-DQT_PLUGIN") ctkFunctionGetCompilerVisibilityFlags(plugin_compile_flags) # Apply properties to the library target. set_target_properties(${lib_name} PROPERTIES COMPILE_FLAGS "${plugin_compile_flags}" RUNTIME_OUTPUT_DIRECTORY ${plugin_RUNTIME_output_dir} LIBRARY_OUTPUT_DIRECTORY ${plugin_LIBRARY_output_dir} ARCHIVE_OUTPUT_DIRECTORY ${plugin_ARCHIVE_output_dir} PREFIX "lib" ) if(NOT MY_TEST_PLUGIN AND NOT MY_NO_INSTALL) # Install rules install(TARGETS ${lib_name} EXPORT CTKExports RUNTIME DESTINATION ${CTK_INSTALL_PLUGIN_DIR} COMPONENT RuntimePlugins LIBRARY DESTINATION ${CTK_INSTALL_PLUGIN_DIR} COMPONENT RuntimePlugins ARCHIVE DESTINATION ${CTK_INSTALL_PLUGIN_DIR} COMPONENT Development) endif() set(my_libs ${MY_TARGET_LIBRARIES} ) if(MINGW) list(APPEND my_libs ssp) # add stack smash protection lib endif() target_link_libraries(${lib_name} PUBLIC ${my_libs}) if(NOT MY_TEST_PLUGIN) set(${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES ${${CMAKE_PROJECT_NAME}_PLUGIN_LIBRARIES} ${lib_name} CACHE INTERNAL "CTK plugins" FORCE) endif() if(NOT MY_TEST_PLUGIN AND NOT MY_NO_INSTALL) # Install headers file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h" "${CMAKE_CURRENT_SOURCE_DIR}/*.tpp") install(FILES ${headers} ${dynamicHeaders} DESTINATION ${CTK_INSTALL_PLUGIN_INCLUDE_DIR}/${Plugin-SymbolicName} COMPONENT Development ) endif() endmacro() ctk-2026.09.02/CMake/ctkMacroBuildQtPlugin.cmake000066400000000000000000000157471524622605700211150ustar00rootroot00000000000000########################################################################### # # 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. # ########################################################################### # # Depends on: # cmake_parse_arguments ( >= CMake 2.8.3) # #! \ingroup CMakeAPI macro(ctkMacroBuildQtPlugin) cmake_parse_arguments(MY "" # no options "NAME;EXPORT_DIRECTIVE;FOLDER;PLUGIN_DIR" # one value args "SRCS;MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;RESOURCES" # multi value args ${ARGN} ) # Sanity checks if(NOT DEFINED MY_NAME) message(FATAL_ERROR "NAME is mandatory") endif() if(NOT DEFINED MY_EXPORT_DIRECTIVE) message(FATAL_ERROR "EXPORT_DIRECTIVE is mandatory") endif() if (NOT DEFINED MY_PLUGIN_DIR) message(FATAL_ERROR "PLUGIN_DIR (e.g. designer, iconengines, imageformats...) is mandatory") endif() set(MY_LIBRARY_TYPE "MODULE") # Define library name set(lib_name ${MY_NAME}) # -------------------------------------------------------------------------- # Include dirs set(my_includes ${QT_QTDESIGNER_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${MY_INCLUDE_DIRECTORIES} ) if(CTK_SOURCE_DIR) # Add the include directories from the library dependencies ctkFunctionGetIncludeDirs(my_includes ${MY_TARGET_LIBRARIES}) endif() include_directories( ${my_includes} ) set(MY_LIBRARY_EXPORT_DIRECTIVE ${MY_EXPORT_DIRECTIVE}) set(MY_EXPORT_HEADER_PREFIX ${MY_NAME}) string(REGEX REPLACE "^CTK" "ctk" MY_EXPORT_HEADER_PREFIX ${MY_EXPORT_HEADER_PREFIX}) set(MY_LIBNAME ${lib_name}) if(NOT CTK_EXPORT_HEADER_TEMPLATE) message(FATAL_ERROR "CTK_EXPORT_HEADER_TEMPLATE is mandatory") endif() configure_file( ${CTK_EXPORT_HEADER_TEMPLATE} ${CMAKE_CURRENT_BINARY_DIR}/${MY_EXPORT_HEADER_PREFIX}Export.h ) set(dynamicHeaders "${dynamicHeaders};${CMAKE_CURRENT_BINARY_DIR}/${MY_EXPORT_HEADER_PREFIX}Export.h") source_group("Resources" FILES ${MY_RESOURCES} ${MY_UI_FORMS} ) add_library(${lib_name} ${MY_LIBRARY_TYPE} ${MY_SRCS} ${MY_RESOURCES} ) target_compile_definitions(${lib_name} PRIVATE HAVE_QT${CTK_QT_VERSION} ) # Configure CMake Qt automatic code generation set(uic_search_paths) foreach(ui_src IN LISTS MY_UI_FORMS) if(NOT IS_ABSOLUTE ${ui_src}) set(ui_src "${CMAKE_CURRENT_SOURCE_DIR}/${ui_src}") endif() get_filename_component(ui_path ${ui_src} PATH) list(APPEND uic_search_paths ${ui_path}) endforeach() list(REMOVE_DUPLICATES uic_search_paths) set_target_properties(${lib_name} PROPERTIES AUTOMOC ON AUTORCC ON AUTOUIC ON AUTOUIC_SEARCH_PATHS "${uic_search_paths}" ) # Extract library name associated with the plugin and use it as label string(REGEX REPLACE "(.*)Plugin[s]?" "\\1" label ${lib_name}) # Apply properties to the library target. set(compile_flags "-DQT_PLUGIN") if(CTK_QT_VERSION VERSION_EQUAL "5") set(compile_flags "${compile_flags} -DHAVE_QT5") elseif(CTK_QT_VERSION VERSION_EQUAL "6") set(compile_flags "${compile_flags} -DHAVE_QT6") else() message(FATAL_ERROR "Support for Qt${CTK_QT_VERSION} is not implemented") endif() set_target_properties(${lib_name} PROPERTIES COMPILE_FLAGS "${compile_flags}" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_LIBRARY_OUTPUT_DIRECTORY}/${MY_PLUGIN_DIR}" LABELS ${label} ) set(my_libs ${MY_TARGET_LIBRARIES} ${QT_QTDESIGNER_LIBRARY} ) target_link_libraries(${lib_name} ${my_libs}) if(NOT "${MY_FOLDER}" STREQUAL "") set_target_properties(${lib_name} PROPERTIES FOLDER ${MY_FOLDER}) endif() # Install the library # CTK_INSTALL_QTPLUGIN_DIR:STRING can be passed when configuring CTK # By default, it is the same path as CTK_INSTALL_LIB_DIR # Plugins are installed in a subdirectory corresponding to their types (e.g. designer, iconengines, imageformats...) install(TARGETS ${lib_name} RUNTIME DESTINATION ${CTK_INSTALL_QTPLUGIN_DIR}/${MY_PLUGIN_DIR} COMPONENT RuntimePlugins LIBRARY DESTINATION ${CTK_INSTALL_QTPLUGIN_DIR}/${MY_PLUGIN_DIR} COMPONENT RuntimePlugins ARCHIVE DESTINATION ${CTK_INSTALL_QTPLUGIN_DIR}/${MY_PLUGIN_DIR} COMPONENT Development ) # Install headers - Are headers required ? #file(GLOB headers "${CMAKE_CURRENT_SOURCE_DIR}/*.h") #install(FILES # ${headers} # DESTINATION ${CTK_INSTALL_INCLUDE_DIR} COMPONENT Development # ) # Since Qt expects plugins to be directly located under the # subdirectory (e.g. 'designer') but not deeper (e.g. designer/Debug), let's copy them. if(NOT CMAKE_CFG_INTDIR STREQUAL ".") get_target_property(DIR_PATH ${lib_name} LIBRARY_OUTPUT_DIRECTORY) add_custom_command( TARGET ${lib_name} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy $ ${DIR_PATH}/../${MY_PLUGIN_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}${lib_name}${CMAKE_BUILD_TYPE}${CMAKE_SHARED_LIBRARY_SUFFIX} ) endif() endmacro() macro(ctkMacroBuildQtDesignerPlugin) find_package(Qt${CTK_QT_VERSION} COMPONENTS Designer REQUIRED) if(CTK_QT_VERSION VERSION_EQUAL "5") # Variables like Qt*_DEFINITIONS may include generator expressions (genex) in newer Qt versions, # which cannot be directly passed to "add_definitions()". For example, the list may include elements # like "$<$>:QDESIGNER_EXPORT_WIDGETS>". Stripping these using # "string(GENEX_STRIP ...)" would result in an incomplete set of definitions. # Therefore, we maintain the use of add_definitions()/include_directories() for Qt5 and encourage # developers to rely on target usage requirements for newer versions. add_definitions(${Qt5Designer_DEFINITIONS}) include_directories(${Qt5Designer_INCLUDE_DIRS}) else() # For newer Qt versions, use target usage requirements to handle definitions and include directories. endif() ctkMacroBuildQtPlugin( PLUGIN_DIR designer ${ARGN}) cmake_parse_arguments(MY "" # no options "NAME;EXPORT_DIRECTIVE;FOLDER;PLUGIN_DIR" # one value args "SRCS;MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;RESOURCES" # multi value args ${ARGN} ) target_link_libraries(${MY_NAME} Qt${CTK_QT_VERSION}::Designer) endmacro() macro(ctkMacroBuildQtIconEnginesPlugin) ctkMacroBuildQtPlugin( PLUGIN_DIR iconengines ${ARGN}) endmacro() macro(ctkMacroBuildQtStylesPlugin) ctkMacroBuildQtPlugin( PLUGIN_DIR styles ${ARGN}) endmacro() ctk-2026.09.02/CMake/ctkMacroCheckExternalProjectDependency.cmake000066400000000000000000001201661524622605700244300ustar00rootroot00000000000000#.rst: # ExternalProjectDependency # ------------------------- # # .. only:: html # # .. contents:: ########################################################################### # # 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 # # https://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. # ########################################################################### include(CMakeParseArguments) #.rst: # Global Variables # ^^^^^^^^^^^^^^^^ #.rst: # .. cmake:variable:: EXTERNAL_PROJECT_DIR # # This variable describes the directory in which external project files # matching ``.cmake`` expression are globbed. # if(NOT EXISTS "${EXTERNAL_PROJECT_DIR}") set(EXTERNAL_PROJECT_DIR ${CMAKE_SOURCE_DIR}/SuperBuild) endif() #.rst: # .. cmake:variable:: EXTERNAL_PROJECT_ADDITIONAL_DIR # # If set, this variable represents an other directory in which external project files # are searched for if not already found in ``EXTERNAL_PROJECT_DIR``. #.rst: # .. cmake:variable:: EXTERNAL_PROJECT_ADDITIONAL_DIRS # # If set, this variable represents additional directories in which external project files # are searched for if not already found in ``EXTERNAL_PROJECT_DIR`` and # ``EXTERNAL_PROJECT_ADDITIONAL_DIR``. #.rst: # .. cmake:variable:: EXTERNAL_PROJECT_FILE_PREFIX # # This variable describes the prefix of the external project files looked up in # ``EXTERNAL_PROJECT_DIR``. It defaults to ``External_``. # if(NOT DEFINED EXTERNAL_PROJECT_FILE_PREFIX) set(EXTERNAL_PROJECT_FILE_PREFIX "External_") endif() #.rst: # .. cmake:variable:: SUPERBUILD_TOPLEVEL_PROJECT # # This variable can be set to explicitly identify the name of the top-level project. # If not set, it default to the value of ``CMAKE_PROJECT_NAME``. if(NOT DEFINED SUPERBUILD_TOPLEVEL_PROJECT) if(NOT DEFINED CMAKE_PROJECT_NAME) message(FATAL_ERROR "Failed to initialize variable SUPERBUILD_TOPLEVEL_PROJECT. Variable CMAKE_PROJECT_NAME is not defined.") endif() set(SUPERBUILD_TOPLEVEL_PROJECT ${CMAKE_PROJECT_NAME}) endif() #.rst: # .. cmake:variable:: EP_LIST_SEPARATOR # # This variable is used to separate list items when passed in various external project # ``..._COMMAND`` options. # # If defaults to ``^^``. if(NOT DEFINED EP_LIST_SEPARATOR) set(EP_LIST_SEPARATOR "^^") endif() #.rst: # .. cmake:variable:: EP_GIT_PROTOCOL # # The value of this variable is always set to ``https``. # # Following the removal of git protocol by GitHub, the option # ``_USE_GIT_PROTOCOL`` is obsolete. # It allowed to toggle between ``git`` and ``https``. # If this option is enabled, a warning is reported and the option is forced to ``OFF``. # # Similarly, if the variable ``EP_GIT_PROTOCOL`` is already set to ``git``, a warning is reported # and the value is forced to ``https``. # # See details at https://github.blog/2021-09-01-improving-git-protocol-security-github # # The variable ``EP_GIT_PROTOCOL`` can be used when adding external project. For example: # # .. code-block:: cmake # # ExternalProject_Add(${proj} # ${${proj}_EP_ARGS} # GIT_REPOSITORY "${EP_GIT_PROTOCOL}://github.com/Foo/Foo.git" # [...] # ) # if(DEFINED ${SUPERBUILD_TOPLEVEL_PROJECT}_USE_GIT_PROTOCOL AND ${SUPERBUILD_TOPLEVEL_PROJECT}_USE_GIT_PROTOCOL) message(WARNING "Forcing ${SUPERBUILD_TOPLEVEL_PROJECT}_USE_GIT_PROTOCOL to OFF (Already set to ON in current scope)") set(${SUPERBUILD_TOPLEVEL_PROJECT}_USE_GIT_PROTOCOL OFF CACHE BOOL "" FORCE) endif() if(DEFINED EP_GIT_PROTOCOL) if("${EP_GIT_PROTOCOL}" STREQUAL "git") get_property(_value_set_in_cache CACHE EP_GIT_PROTOCOL PROPERTY VALUE SET) if(_value_set_in_cache) message(WARNING "Forcing EP_GIT_PROTOCOL cache variable to 'https' (Already set to '${EP_GIT_PROTOCOL}' in current scope)") set(EP_GIT_PROTOCOL "https" CACHE STRING "" FORCE) else() message(WARNING "Forcing EP_GIT_PROTOCOL variable to 'https' (Already set to '${EP_GIT_PROTOCOL}' in current scope)") set(EP_GIT_PROTOCOL "https") endif() endif() else() set(EP_GIT_PROTOCOL "https") endif() # Compute -G arg for configuring external projects with the same CMake generator: if(CMAKE_EXTRA_GENERATOR) set(EP_CMAKE_GENERATOR "${CMAKE_EXTRA_GENERATOR} - ${CMAKE_GENERATOR}") else() set(EP_CMAKE_GENERATOR "${CMAKE_GENERATOR}") endif() set(EP_CMAKE_GENERATOR_PLATFORM "${CMAKE_GENERATOR_PLATFORM}") set(EP_CMAKE_GENERATOR_TOOLSET "${CMAKE_GENERATOR_TOOLSET}") #.rst: # Functions # ^^^^^^^^^ #.rst: # .. cmake:function:: mark_as_superbuild # # .. code-block:: cmake # # mark_as_superbuild([:] [[:] [...]]) # # .. code-block:: cmake # # mark_as_superbuild( # VARS [:] [[:] [...]] # [PROJECTS [ [...]] | ALL_PROJECTS] # [LABELS [ [...]]] # ) # # .. code-block:: cmake # # PROJECTS corresponds to a list of that will be added using 'ExternalProject_Add' function. # If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'. # If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects. # # VARS is an expected list of variables specified as : to pass to # # # LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to # the as CMake CACHE args of the form: # -D_EP_LABEL_=;[...] # -D_EP_LABEL_=;[...] # function(mark_as_superbuild) set(options ALL_PROJECTS CMAKE_CMD) set(oneValueArgs) set(multiValueArgs VARS PROJECTS LABELS) cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) set(_vars ${_sb_UNPARSED_ARGUMENTS}) set(_named_parameters_expected 0) if(_sb_PROJECTS OR _sb_ALL_PROJECTS OR _sb_LABELS OR _sb_VARS) set(_named_parameters_expected 1) set(_vars ${_sb_VARS}) endif() if(_named_parameters_expected AND _sb_UNPARSED_ARGUMENTS) message(FATAL_ERROR "Arguments '${_sb_UNPARSED_ARGUMENTS}' should be associated with VARS parameter !") endif() if(_sb_PROJECTS AND _sb_ALL_PROJECTS) message(FATAL_ERROR "Arguments 'PROJECTS' and 'ALL_PROJECTS' are mutually exclusive !") endif() foreach(var ${_vars}) set(_type_specified 0) if(var MATCHES ":") set(_type_specified 1) endif() # XXX Display warning with variable type is also specified for cache variable. set(_var ${var}) if(NOT _type_specified) get_property(_type_set_in_cache CACHE ${_var} PROPERTY TYPE SET) set(_var_name ${_var}) set(_var_type "STRING") if(_type_set_in_cache) get_property(_var_type CACHE ${_var_name} PROPERTY TYPE) endif() set(_var ${_var_name}:${_var_type}) endif() list(APPEND _vars_with_type ${_var}) endforeach() if(_sb_ALL_PROJECTS) set(optional_arg_ALL_PROJECTS "ALL_PROJECTS") else() set(optional_arg_ALL_PROJECTS PROJECTS ${_sb_PROJECTS}) endif() _sb_append_to_cmake_args( VARS ${_vars_with_type} LABELS ${_sb_LABELS} ${optional_arg_ALL_PROJECTS}) endfunction() # # _sb_extract_varname_and_vartype( []) # # corresponds to variable name and variable type passed as ":" # # will be set to "" # # is an optional variable name that will be set to "" # function(_sb_extract_varname_and_vartype cmake_varname_and_type varname_var) set(_vartype_var "${ARGV2}") string(REPLACE ":" ";" varname_and_vartype ${cmake_varname_and_type}) list(GET varname_and_vartype 0 _varname) list(GET varname_and_vartype 1 _vartype) set(${varname_var} ${_varname} PARENT_SCOPE) if(_vartype_var MATCHES ".+") set(${_vartype_var} ${_vartype} PARENT_SCOPE) endif() endfunction() function(_sb_list_to_string separator input_list output_string_var) set(_string "") # Get list length list(LENGTH input_list list_length) # If the list has 0 or 1 element, there is no need to loop over. if(list_length LESS 2) set(_string "${input_list}") else() math(EXPR last_element_index "${list_length} - 1") foreach(index RANGE ${last_element_index}) # Get current item_value list(GET input_list ${index} item_value) if(NOT item_value STREQUAL "") # .. and append non-empty value to output string set(_string "${_string}${item_value}") # Append separator if current element is NOT the last one. if(NOT index EQUAL last_element_index) set(_string "${_string}${separator}") endif() endif() endforeach() endif() set(${output_string_var} ${_string} PARENT_SCOPE) endfunction() # # _sb_cmakevar_to_cmakearg( [ []]) # # corresponds to variable name and variable type passed as ":" # # is a variable name that will be set to "-D:=${}" # # is set to either TRUE or FALSE. # FALSE means that the value does NOT reference ${CMAKE_CFG_INTDIR} and # the generated cmake argument should be passed to ExternalProject_Add as CMAKE_CACHE_ARGS. # TRUEmeans that the value does reference ${CMAKE_CFG_INTDIR} and # the generated cmake argument should be passed to ExternalProject_Add as CMAKE_ARGS. # # is an optional variable name that will be set to "" # # is an optional variable name that will be set to "" # function(_sb_cmakevar_to_cmakearg cmake_varname_and_type cmake_arg_var has_cfg_intdir_var) set(_varname_var "${ARGV3}") set(_vartype_var "${ARGV4}") _sb_extract_varname_and_vartype(${cmake_varname_and_type} _varname _vartype) set(_var_value "${${_varname}}") # Use cache value unless it is INTERNAL if(_vartype STREQUAL "INTERNAL") set(_vartype "STRING") else() get_property(_value_set_in_cache CACHE ${_varname} PROPERTY VALUE SET) if(_value_set_in_cache) get_property(_var_value CACHE ${_varname} PROPERTY VALUE) endif() endif() set(_has_cfg_intdir FALSE) if(CMAKE_CONFIGURATION_TYPES) string(FIND "${_var_value}" ${CMAKE_CFG_INTDIR} _index) if(NOT _index EQUAL -1) # Separate list item with _sb_list_to_string(${EP_LIST_SEPARATOR} "${_var_value}" _var_value) set(_has_cfg_intdir TRUE) endif() endif() if(NOT _has_cfg_intdir) string(REPLACE "\"" "\\\"" _var_value "${_var_value}") endif() set(${cmake_arg_var} -D${_varname}:${_vartype}=${_var_value} PARENT_SCOPE) set(${has_cfg_intdir_var} ${_has_cfg_intdir} PARENT_SCOPE) if(_varname_var MATCHES ".+") set(${_varname_var} ${_varname} PARENT_SCOPE) endif() if(_vartype_var MATCHES ".+") set(${_vartype_var} ${_vartype} PARENT_SCOPE) endif() endfunction() set(_ALL_PROJECT_IDENTIFIER "ALLALLALL") # # _sb_append_to_cmake_args( # [VARS : [: [...]]] # [PROJECTS [ [...]] | ALL_PROJECTS] # [LABELS [ [...]]] # ) # # PROJECTS corresponds to a list of that will be added using 'ExternalProject_Add' function. # If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'. # If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects. # # VARS is an expected list of variables specified as : to pass to # # # LABELS is an optional list of label to associate with the variable names specified using 'VARS' and passed to # the as CMake CACHE args of the form: # -D_EP_LABEL_=;[...] # -D_EP_LABEL_=;[...] # function(_sb_append_to_cmake_args) set(options ALL_PROJECTS) set(oneValueArgs) set(multiValueArgs VARS PROJECTS LABELS) cmake_parse_arguments(_sb "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if(NOT _sb_PROJECTS AND NOT _sb_ALL_PROJECTS) set(_sb_PROJECTS ${SUPERBUILD_TOPLEVEL_PROJECT}) endif() if(_sb_ALL_PROJECTS) set(_sb_PROJECTS ${_ALL_PROJECT_IDENTIFIER}) endif() foreach(_sb_PROJECT ${_sb_PROJECTS}) set(_ep_varnames "") foreach(varname_and_vartype ${_sb_VARS}) if(NOT TARGET ${_sb_PROJECT}) set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_CMAKE_ARGS ${varname_and_vartype}) _sb_extract_varname_and_vartype(${varname_and_vartype} _varname) else() message(FATAL_ERROR "Function _sb_append_to_cmake_args not allowed because project '${_sb_PROJECT}' already added !") endif() list(APPEND _ep_varnames ${_varname}) endforeach() if(_sb_LABELS) set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABELS ${_sb_LABELS}) foreach(label ${_sb_LABELS}) set_property(GLOBAL APPEND PROPERTY ${_sb_PROJECT}_EP_LABEL_${label} ${_ep_varnames}) endforeach() endif() endforeach() endfunction() #.rst: # .. cmake:function:: ExternalProject_DeclareLabels # # .. code-block:: cmake # # ExternalProject_DeclareLabels( # [PROJECTS [ [...]] | ALL_PROJECTS] # LABELS [ [...]] # ) # # .. code-block:: cmake # # PROJECTS corresponds to a list of that will be added using 'ExternalProject_Add' function. # If not specified and called within a project file, it defaults to the value of 'SUPERBUILD_TOPLEVEL_PROJECT'. # If instead 'ALL_PROJECTS' is specified, the variables and labels will be passed to all projects. # # LABELS is a list of label to pass to the as CMake CACHE args of the # form -D_EP_LABEL_