diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIF3D.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIF3D.png new file mode 100644 index 0000000000..badee5e53f Binary files /dev/null and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIF3D.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIInitial.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIInitial.png index 67af9bd8fe..b728072ce6 100644 Binary files a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIInitial.png and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIInitial.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyReg.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyReg.png index 7c000de664..3932227e3e 100644 Binary files a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyReg.png and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyReg.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyRegRunning2.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyRegRunning2.png index 3aaa4f242a..9df12752c2 100644 Binary files a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyRegRunning2.png and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLINiftyRegRunning2.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferences.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferences.png index 2b83ec3b1a..35ab9f7ce8 100644 Binary files a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferences.png and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIPreferences.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIWithPrograms.png b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIWithPrograms.png index 51b7e08bbf..6ff8a032b9 100644 Binary files a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIWithPrograms.png and b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/CLIWithPrograms.png differ diff --git a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/Manual.dox b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/Manual.dox index 5315557349..c4748f0fe8 100644 --- a/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/Manual.dox +++ b/Plugins/org.mitk.gui.qt.cli/documentation/UserManual/Manual.dox @@ -1,145 +1,170 @@ /** \bundlemainpage{org.mitk.gui.qt.cli} The Command Line Interface (CLI) View \image html CLIIcon.png "Icon of CLI" \li \ref CLIIntroduction \li \ref CLIPreferences \li \ref CLIUsage \li \ref CLITechnicalNotes \section CLIPrefix Contribution This plugin was developed at the Centre For Medical Image Computing (CMIC), -part of University College London and contributed back to the +part of University College London (UCL) and contributed back to the MITK community with thanks. \section CLIIntroduction Introduction This view provides the facility to run third party command line programs, and load the data back into the DataManager for immediate visualisation. All that is required is that the command line application can be called with an argument of --xml and respond with a valid XML description of the necessary parameters. -This view can then generate a Graphical User Interface (GUI) dynamically to enable the user to interact with the -command line application. This provides an easy to use, and potentially very flexible way -to integrate almost any third party, medical imaging, command line application. +This view can then generate a Graphical User Interface (GUI) dynamically from the XML to enable the +user to interact with the command line application. This provides an easy to use, and potentially +very flexible way to integrate almost any third party, medical imaging, command line application. As a high level introduction, this view performs the following steps: \li The view searches for available programs to run, and for each valid module, stores the XML document describing the interface, and populates a searchable list of available programs. \li When a program is selected, the GUI is generated. \li The user can then set the necessary parameters and run the program. \li Multiple programs can be launched simultaneously, and where available on the host platform, the user can pause, resume or cancel running jobs and see console output for each job. As a consequence of the very flexible nature of this plugin, these instructions can only describe how to launch command line modules in a general sense. The examples shown have been constructed by downloading the latest version of the NiftyReg package, available here, and described further here. NiftyReg provides valid XML descriptors to enable the integration of the NiftyReg affine (RegAladin) and and non-rigid (RegF3D) image registration algorithms, as well as utility programs to resample an image, and calculate a Jacobian image. These same XML descriptors work within Slicer and MITK based applications. \section CLIPreferences Preferences -The first time that the CLI View is launched, it may be necessary to set the default preferences for the view. Please refer +The first time that the CLI View is launched, it is advisable to set the user preferences for the view. Please refer to Figure 1. \image html CLIPreferences.png "Figure 1. The CLI Preferences Page" -The first 4 preferences are to control where the view will search for valid command line programs. By default these are off +Each of these preferences is now explained in some detail. + +\li show debug output: If checked will output more messages to the console for debugging purposes. +\li XML validation mode: The user may select a different mode for XML validation. If this is changed, the application will +need to be restarted. There are 3 modes available. If the user selects "strict" mode, the XML schema produced by the +command line application must exactly conform to +this definition. For "none", there will be no validation. For "weak" validation, the application will report errors, +but try to carry on and load as many modules as possible. The XML validation errors are available as tool-tips on +the tab widget when the module is launched. Many third party modules included with Slicer currently have +incorrect XML, and so the "weak" or "none" mode may assist in loading them. By default the "strict" mode is chosen +so that only valid modules are loaded. +\li max concurrent processes: Sets the maximum number of concurrent jobs that can be run via this interface. The default is 4. +When the maximum number is reached, the green "Run" button is disabled until a job finishes. + +The next four preferences are to control where the view will search for valid command line programs. By default these are off as the searching process can take a long time and slow down the startup time of the GUI. The options provided are: \li scan home directory: Scan the users home directory. Most useful on unix systems where users can install their own software. \li scan current directory: This is the current working directory. Most useful on unix systems where users launch the application from the console. \li scan installation directory: This is the directory where the actual application is stored. \li scan CTK_MODULE_LOAD_PATH: If the environment variable CTK_MODULE_LOAD_PATH points to a valid directory, this will also be scanned. In addition, for the first 3 of these options, the sub-directory "cli-modules" will also be scanned if it exists. In most cases, the user will leave these options unchecked, as the user can also specify custom directories, and even cherry-pick specific command line programs to load. Figure 2 shows a selection box that enables the user to specify custom directories to scan, and Figure 3. shows a selection box that enables the user to select specific modules. \image html CLIPreferencesAdditionalDirectories.png "Figure 2. The User can specify specific directories to scan". \image html CLIPreferencesAdditionalModules.png "Figure 3. The User can specify specific command line programs to load". These directory and file selection boxes enable directories or files to be added, removed and updated in a similar fashion. The user must make sure that the list of files selected in the "additional modules" section are not already contained within the directories specified in the "additional module directories" section. In addition, the preferences page provides: \li temporary directory: Images stored in the DataManager are first written to a temporary folder as Nifti images before being passed to each command line program. This temporary directory will default to a platform specific temporary folder, but the user may select their preferred choice of temporary workspace. -\li debug output: If checked the view will try to provide more output, either on the console window or -event log depending on the host platform. -\li XML validation mode: The user may select a different mode for XML validation. If this is changed, the applicatioin will -need to be restarted. There are 3 modes available. If the user selects "strict" mode, the XML schema produced by the command line application -must exactly conform to -this definition. For "none", there will be no validation. For "weak" validation, the application will report errors, -but try to carry on and load as many modules as possible. Many third party modules included with Slicer currently have -incorrect XML, and so "weak" mode may assist in loading them. Future work will improve the error reporting. By default -the "strict" mode is chosen so that only valid modules are loaded. \section CLIUsage Usage When the view is launched, a simple interface is presented, as shown in Figure 4. \image html CLIInitial.png "Figure 4. The initial interface, with no command line programs available." In this example, all the above check-box preferences were off, and the "additional module directories" was empty, and the "additional modules" list was empty so no command line applications were found. The "Search" box displays zero entries, and there is nothing to search. If the available search paths contain programs that are compatible (i.e. runnable) with this view, the name of the programs are displayed in the "Search" box in a nested menu, shown in Figure 5. \image html CLIWithPrograms.png "Figure 5. When valid paths are set, and programs are discovered, the menu is recalculated to show available programs." -When a program is selected, the relevant interface is displayed: +When a program is selected, the relevant interface is displayed, by default as collapsed group boxes to save space. +Each section can be individually expanded if necessary to see the parameters. \image html CLINiftyReg.png "Figure 6. An example program, showing parameters for NiftyReg's program RegAladin." In this example, the parameters are displayed for NiftyReg produced at UCL, and more specifically for the affine registration program called -RegAladin. The interface can contain a wide variety of controls. If a parameter for a command line program is an image, +RegAladin. The interface can contain a wide variety of controls. If a parameter for a command line program is an input image, then the widget displayed is linked to the DataManager, so that as new images are loaded, the correct image can be easily -selected. +selected from the combo box. -In addition, the view contains an "About" tab containing details of the contributors, the licence and acknowledgements and also -a "Help" tab containing a description and a link to any on-line documentation. +At this stage, multiple tabs can be opened, with one tab for each command line program. Figure 7 shows 2 tabs, +for the RegAladin and RegF3D programs. -These documentation features are provided by the developers of the third party plugin, and not by the host program. -If information is missing, the user must contact the third party developers. +\image html CLIF3D.png "Figure 7. Multiple tabs can be opened, one for each command line program." + +The main view provides some simple controls: + +\li Green arrow: Launch (run) the command line executable of the currently selected tab. +\li Yellow undo arrow: Resets the GUI controls of the currently selected tab to default values, if and only if the original XML specified a default value. -The view provides some simple controls: +At this stage, nothing has been launched. When the user hits the green arrow button, a job is launched. +Each running job is shown as a new progress reporting widget under the main tabbed widget, as shown in Figure 8. -\li Green arrow: Launch (run) the current command line executable. -\li Yellow undo arrow: Resets the GUI controls to a default value, if and only if the original XML specified a default value. -\li Blue pause button: A toggle button to Pause/Resume the running program. -\li Red square: Stop (kill / cancel) the running application. Irreversible. -\li Black cross: Remove the widget from the display. +\image html CLINiftyRegRunning2.png "Figure 8. Multiple programs can be run, each with individual controls and console output." -When the module is launched the parameters are fixed, so the parameters box is disabled. When the -command line program is running, it may provide progress updates in the progress bar, or via -console output, which can be seen in the console box. Both the parameters box and console box are collapsible to save space. +The controls for each running job are: -It is possible to launch multiple jobs. The number of widgets just stack vertically, as shown in Figure 7. +\li Blue pause button: If supported on the host platform, this button will be enabled and can be toggled off (pause) or on (resume). +\li Red square: If supported on the host platform, this button will kill the command line program. +\li Black cross: Will remove the progress reporting widget from the GUI. -\image html CLINiftyRegRunning2.png "Figure 7. Multiple programs can be run, each with individual control and console output." +When the user hits the green arrow in the main view: + +\li The currently selected tab is designated the "current" job, and contains the "current" set of parameters. +\li A new progress reporting widget is created. +\li The current parameters are copied to the progress reporting widget. In Figure 8. a parameters section +is visible, and by default is collapsed, as they are simply for referring back to. +\li All the output for the command line program is shown in the console widget, with a separate console for each job. +\li Each new progress reporting widget is simply stacked vertically (newest is top-most), and it is up to the +user to delete them when they are finished. + +It is easy to run multiple jobs. The green button simply launches the job corresponding to the current tab repeatedly. +It is up to the user to make sure that any output file names are changed between successive invocations of the same command +line module to avoid overwritting output data. + +In addition, each set of parameters contains an "About" section containing details of the contributors, the licence and acknowledgements and also +a "Help" section containing a description and a link to any on-line documentation. + +These documentation features are provided by the developers of the third party plugin, and not by the host program. +If information is missing, the user must contact the third party developers. \section CLITechnicalNotes Technical Notes From a technical perspective, the Command Line Interface (CLI) View is a simple view, harnessing the power of the CTK command line modules framework. For technical information see: \li The doxygen generated manual page. \li The wiki page. and obviously the CTK code base. */ diff --git a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.cpp b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.cpp index 758d094f03..fc0bb89003 100644 --- a/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.cpp +++ b/Plugins/org.mitk.gui.qt.cli/src/internal/CommandLineModulesPreferencesPage.cpp @@ -1,194 +1,194 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) University College London (UCL). All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #include "CommandLineModulesPreferencesPage.h" #include "CommandLineModulesViewConstants.h" #include #include #include #include #include #include #include #include #include #include #include #include "QmitkDirectoryListWidget.h" #include "QmitkFileListWidget.h" //----------------------------------------------------------------------------- CommandLineModulesPreferencesPage::CommandLineModulesPreferencesPage() : m_MainControl(0) , m_TemporaryDirectory(0) , m_ModulesDirectories(0) , m_ModulesFiles(0) , m_LoadFromHomeDir(0) , m_LoadFromCurrentDir(0) , m_LoadFromApplicationDir(0) , m_LoadFromAutoLoadPathDir(0) , m_ValidationMode(0) , m_MaximumNumberProcesses(0) , m_CLIPreferencesNode(0) { } //----------------------------------------------------------------------------- CommandLineModulesPreferencesPage::~CommandLineModulesPreferencesPage() { } //----------------------------------------------------------------------------- void CommandLineModulesPreferencesPage::Init(berry::IWorkbench::Pointer ) { } //----------------------------------------------------------------------------- void CommandLineModulesPreferencesPage::CreateQtControl(QWidget* parent) { berry::IPreferencesService::Pointer prefService = berry::Platform::GetServiceRegistry() .GetServiceById(berry::IPreferencesService::ID); std::string id = "/" + CommandLineModulesViewConstants::VIEW_ID; m_CLIPreferencesNode = prefService->GetSystemPreferences()->Node(id); m_MainControl = new QWidget(parent); m_TemporaryDirectory = new ctkDirectoryButton(m_MainControl); m_TemporaryDirectory->setCaption("Select a directory for temporary files ... "); m_ModulesDirectories = new QmitkDirectoryListWidget(m_MainControl); m_ModulesDirectories->m_Label->setText("Select directories to scan:"); m_ModulesFiles = new QmitkFileListWidget(m_MainControl); m_ModulesFiles->m_Label->setText("Select additional executables:"); m_DebugOutput = new QCheckBox(m_MainControl); m_LoadFromApplicationDir = new QCheckBox(m_MainControl); m_LoadFromAutoLoadPathDir = new QCheckBox(m_MainControl); m_LoadFromHomeDir = new QCheckBox(m_MainControl); m_LoadFromCurrentDir = new QCheckBox(m_MainControl); m_ValidationMode = new QComboBox(m_MainControl); m_ValidationMode->addItem("strict", ctkCmdLineModuleManager::STRICT_VALIDATION); m_ValidationMode->addItem("none", ctkCmdLineModuleManager::SKIP_VALIDATION); m_ValidationMode->addItem("weak", ctkCmdLineModuleManager::WEAK_VALIDATION); m_ValidationMode->setCurrentIndex(0); m_MaximumNumberProcesses = new QSpinBox(m_MainControl); m_MaximumNumberProcesses->setMinimum(1); m_MaximumNumberProcesses->setMaximum(1000000); QFormLayout *formLayout = new QFormLayout; + formLayout->addRow("show debug output:", m_DebugOutput); + formLayout->addRow("XML validation mode:", m_ValidationMode); + formLayout->addRow("max. concurrent processes:", m_MaximumNumberProcesses); formLayout->addRow("scan home directory:", m_LoadFromHomeDir); formLayout->addRow("scan current directory:", m_LoadFromCurrentDir); formLayout->addRow("scan installation directory:", m_LoadFromApplicationDir); formLayout->addRow("scan CTK_MODULE_LOAD_PATH:", m_LoadFromAutoLoadPathDir); formLayout->addRow("additional module directories:", m_ModulesDirectories); formLayout->addRow("additional modules:", m_ModulesFiles); formLayout->addRow("temporary directory:", m_TemporaryDirectory); - formLayout->addRow("debug output:", m_DebugOutput); - formLayout->addRow("XML validation mode:", m_ValidationMode); - formLayout->addRow("max. concurrent:", m_MaximumNumberProcesses); m_MainControl->setLayout(formLayout); this->Update(); } //----------------------------------------------------------------------------- QWidget* CommandLineModulesPreferencesPage::GetQtControl() const { return m_MainControl; } //----------------------------------------------------------------------------- std::string CommandLineModulesPreferencesPage::ConvertToStdString(const QStringList& list) { std::string output; for (int i = 0; i < list.count(); i++) { QString path = list[i] + ";"; output += path.toStdString(); } return output; } //----------------------------------------------------------------------------- bool CommandLineModulesPreferencesPage::PerformOk() { m_CLIPreferencesNode->Put(CommandLineModulesViewConstants::TEMPORARY_DIRECTORY_NODE_NAME, m_TemporaryDirectory->directory().toStdString()); m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::DEBUG_OUTPUT_NODE_NAME, m_DebugOutput->isChecked()); m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR, m_LoadFromApplicationDir->isChecked()); m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR, m_LoadFromHomeDir->isChecked()); m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR, m_LoadFromCurrentDir->isChecked()); m_CLIPreferencesNode->PutBool(CommandLineModulesViewConstants::LOAD_FROM_AUTO_LOAD_DIR, m_LoadFromAutoLoadPathDir->isChecked()); std::string paths = this->ConvertToStdString(m_ModulesDirectories->directories()); m_CLIPreferencesNode->Put(CommandLineModulesViewConstants::MODULE_DIRECTORIES_NODE_NAME, paths); std::string modules = this->ConvertToStdString(m_ModulesFiles->files()); m_CLIPreferencesNode->Put(CommandLineModulesViewConstants::MODULE_FILES_NODE_NAME, modules); int currentValidationMode = m_CLIPreferencesNode->GetInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, 0); if (currentValidationMode != m_ValidationMode->currentIndex()) { QMessageBox msgBox; msgBox.setText("Changing the XML validation mode will require a restart of the application."); msgBox.exec(); } m_CLIPreferencesNode->PutInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, m_ValidationMode->currentIndex()); m_CLIPreferencesNode->PutInt(CommandLineModulesViewConstants::MAX_CONCURRENT, m_MaximumNumberProcesses->value()); return true; } //----------------------------------------------------------------------------- void CommandLineModulesPreferencesPage::PerformCancel() { } //----------------------------------------------------------------------------- void CommandLineModulesPreferencesPage::Update() { QString fallbackTmpDir = QDir::tempPath(); m_TemporaryDirectory->setDirectory(QString::fromStdString(m_CLIPreferencesNode->Get(CommandLineModulesViewConstants::TEMPORARY_DIRECTORY_NODE_NAME, fallbackTmpDir.toStdString()))); m_DebugOutput->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::DEBUG_OUTPUT_NODE_NAME, false)); m_LoadFromApplicationDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_APPLICATION_DIR, false)); m_LoadFromHomeDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_HOME_DIR, false)); m_LoadFromCurrentDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_CURRENT_DIR, false)); m_LoadFromAutoLoadPathDir->setChecked(m_CLIPreferencesNode->GetBool(CommandLineModulesViewConstants::LOAD_FROM_AUTO_LOAD_DIR, false)); QString paths = QString::fromStdString(m_CLIPreferencesNode->Get(CommandLineModulesViewConstants::MODULE_DIRECTORIES_NODE_NAME, "")); QStringList directoryList = paths.split(";", QString::SkipEmptyParts); m_ModulesDirectories->setDirectories(directoryList); QString files = QString::fromStdString(m_CLIPreferencesNode->Get(CommandLineModulesViewConstants::MODULE_FILES_NODE_NAME, "")); QStringList fileList = files.split(";", QString::SkipEmptyParts); m_ModulesFiles->setFiles(fileList); m_ValidationMode->setCurrentIndex(m_CLIPreferencesNode->GetInt(CommandLineModulesViewConstants::XML_VALIDATION_MODE, 0)); m_MaximumNumberProcesses->setValue(m_CLIPreferencesNode->GetInt(CommandLineModulesViewConstants::MAX_CONCURRENT, 4)); }