diff --git a/Modules/XNAT/files.cmake b/Modules/XNAT/files.cmake index e26d372495..08dc767045 100644 --- a/Modules/XNAT/files.cmake +++ b/Modules/XNAT/files.cmake @@ -1,33 +1,36 @@ file(GLOB_RECURSE H_FILES RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/include/*") set(CPP_FILES mitkXnatSessionTracker.cpp QmitkXnatTreeModel.cpp QmitkXnatProjectWidget.cpp QmitkXnatSubjectWidget.cpp QmitkXnatExperimentWidget.cpp QmitkXnatCreateObjectDialog.cpp + QmitkSelectXnatUploadDestinationDialog.cpp QmitkXnatUploadFromDataStorageDialog.cpp ) set(MOC_H_FILES include/mitkXnatSessionTracker.h include/QmitkXnatTreeModel.h include/QmitkXnatProjectWidget.h include/QmitkXnatSubjectWidget.h include/QmitkXnatExperimentWidget.h include/QmitkXnatCreateObjectDialog.h + include/QmitkSelectXnatUploadDestinationDialog.h include/QmitkXnatUploadFromDataStorageDialog.h ) set(QRC_FILES resources/xnat.qrc ) set(UI_FILES src/QmitkXnatExperimentWidgetControls.ui src/QmitkXnatProjectWidgetControls.ui + src/QmitkSelectXnatUploadDestinationDialog.ui src/QmitkXnatSubjectWidgetControls.ui src/QmitkXnatUploadFromDataStorageDialog.ui ) diff --git a/Modules/XNAT/include/QmitkSelectXnatUploadDestinationDialog.h b/Modules/XNAT/include/QmitkSelectXnatUploadDestinationDialog.h new file mode 100644 index 0000000000..5307d73cad --- /dev/null +++ b/Modules/XNAT/include/QmitkSelectXnatUploadDestinationDialog.h @@ -0,0 +1,45 @@ +#ifndef QMITKSELECTXNATUPLOADDESTINATIONDIALOG_H +#define QMITKSELECTXNATUPLOADDESTINATIONDIALOG_H + +#include + +#include + +namespace Ui { +class QmitkSelectXnatUploadDestinationDialog; +} + +class ctkXnatResource; +class ctkXnatSession; +class QModelIndex; +class QmitkXnatTreeModel; + +class MITKXNAT_EXPORT QmitkSelectXnatUploadDestinationDialog : public QDialog +{ + Q_OBJECT + +public: + explicit QmitkSelectXnatUploadDestinationDialog(ctkXnatSession* session, /*const QStringList&, */QWidget *parent = 0); + ~QmitkSelectXnatUploadDestinationDialog(); + + ctkXnatResource* GetUploadDestination(); + void SetXnatResourceFolderUrl(const QString& url); + +protected slots: + + void OnUpload(); + void OnSelectResource(bool selectResource); + void OnSelectFromTreeView(bool selectFromTreeView); + void OnResourceEntered(const QString &resourceEntered); + void OnResourceSelected(const QString &resource); + void OnXnatNodeSelected(const QModelIndex&); + void OnCancel(); + +private: + QmitkXnatTreeModel* m_TreeModel; + + ctkXnatResource* m_SelectedResource; + Ui::QmitkSelectXnatUploadDestinationDialog *ui; +}; + +#endif // QMITKSELECTXNATUPLOADDESTINATIONDIALOG_H diff --git a/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.cpp b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.cpp new file mode 100644 index 0000000000..b3af9ddf2d --- /dev/null +++ b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.cpp @@ -0,0 +1,127 @@ +#include "QmitkSelectXnatUploadDestinationDialog.h" +#include "ui_QmitkSelectXnatUploadDestinationDialog.h" + +#include +#include +#include + +#include "QmitkXnatTreeModel.h" + +#include + +QmitkSelectXnatUploadDestinationDialog::QmitkSelectXnatUploadDestinationDialog(ctkXnatSession* session, QWidget *parent) : + QDialog(parent), + ui(new Ui::QmitkSelectXnatUploadDestinationDialog) +{ + ui->setupUi(this); + + m_TreeModel = new QmitkXnatTreeModel(); + m_TreeModel->addDataModel(session->dataModel()); + ui->treeView->setModel(m_TreeModel); + + connect(ui->cbSelectResources, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(OnResourceSelected(const QString&))); + connect(ui->treeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(OnXnatNodeSelected(const QModelIndex&))); + connect(ui->rbSelectResource, SIGNAL(toggled(bool)), this, SLOT(OnSelectResource(bool))); + connect(ui->rbSelectFromTreeView, SIGNAL(toggled(bool)), this, SLOT(OnSelectFromTreeView(bool))); + connect(ui->leResourceName, SIGNAL(textChanged(const QString&)), this, SLOT(OnResourceEntered(const QString&))); + connect(ui->pbCancel, SIGNAL(clicked()), this, SLOT(OnCancel())); + connect(ui->pbUpload, SIGNAL(clicked()), this, SLOT(OnUpload())); + + // Initial Setup + ui->pbUpload->setEnabled(false); + ui->leResourceName->setVisible(false); + ui->rbSelectFromTreeView->hide(); + ui->rbSelectResource->hide(); + ui->cbSelectResources->hide(); + +// Temporarily disabled, only selection via treeview possible +// if (availableResources.isEmpty()) +// { +// ui->rbSelectFromTreeView->setChecked(true); +// ui->rbSelectResource->setEnabled(false); +// } +// else +// { +// foreach (QString resourceName, availableResources) +// { +// ui->cbSelectResources->addItem(resourceName); +// } +// ui->cbSelectResources->addItem("Create new resource folder..."); +// } +} + +QmitkSelectXnatUploadDestinationDialog::~QmitkSelectXnatUploadDestinationDialog() +{ + delete ui; +} + +void QmitkSelectXnatUploadDestinationDialog::OnCancel() +{ + this->done(QDialog::Rejected); +} + +void QmitkSelectXnatUploadDestinationDialog::OnUpload() +{ + this->done(QDialog::Accepted); +} + +void QmitkSelectXnatUploadDestinationDialog::OnSelectResource(bool selectResource) +{ + ui->pbUpload->setEnabled(false); + ui->cbSelectResources->setVisible(selectResource); + ui->leResourceName->setVisible(!selectResource); + ui->treeView->setVisible(!selectResource); + if (selectResource) + ui->cbSelectResources->setCurrentIndex(0); +} + +void QmitkSelectXnatUploadDestinationDialog::OnSelectFromTreeView(bool selectFromTreeView) +{ + ui->pbUpload->setEnabled(false); + ui->cbSelectResources->setVisible(!selectFromTreeView); + ui->leResourceName->setVisible(!selectFromTreeView); + ui->treeView->setVisible(selectFromTreeView); +} + +void QmitkSelectXnatUploadDestinationDialog::SetXnatResourceFolderUrl(const QString &/*url*/) +{ +// m_XnatResourceFolderUrl = url; +} + +ctkXnatResource *QmitkSelectXnatUploadDestinationDialog::GetUploadDestination() +{ + return m_SelectedResource; +} + +void QmitkSelectXnatUploadDestinationDialog::OnResourceSelected(const QString& resource) +{ + if (resource.isEmpty()) + ui->pbUpload->setEnabled(false); + + if (resource != "Create new resource folder...") + { + ui->pbUpload->setEnabled(true); + ui->leResourceName->hide(); + } + else if (resource == "Create new resource folder...") + { + ui->pbUpload->setEnabled(false); + ui->leResourceName->show(); + } +} + +void QmitkSelectXnatUploadDestinationDialog::OnResourceEntered(const QString& resourceEntered) +{ + ui->pbUpload->setEnabled(!resourceEntered.isEmpty()); +} + +void QmitkSelectXnatUploadDestinationDialog::OnXnatNodeSelected(const QModelIndex& index) +{ + if (!index.isValid()) + return; + + ctkXnatObject* selectedObject = m_TreeModel->xnatObject(index); + m_SelectedResource = dynamic_cast(selectedObject); + ui->pbUpload->setEnabled(m_SelectedResource != nullptr); +} + diff --git a/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.ui b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.ui new file mode 100644 index 0000000000..34ca4a3092 --- /dev/null +++ b/Modules/XNAT/src/QmitkSelectXnatUploadDestinationDialog.ui @@ -0,0 +1,98 @@ + + + QmitkSelectXnatUploadDestinationDialog + + + + 0 + 0 + 419 + 210 + + + + Dialog + + + + + + + + Select existing resource folder + + + false + + + buttonGroup + + + + + + + Select from Treebrowser + + + true + + + buttonGroup + + + + + + + + + + + + + + + true + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + Upload + + + + + + + + + + + + + diff --git a/Plugins/org.mitk.gui.qt.xnat/files.cmake b/Plugins/org.mitk.gui.qt.xnat/files.cmake index f0a27c0ce6..f87c5845f7 100644 --- a/Plugins/org.mitk.gui.qt.xnat/files.cmake +++ b/Plugins/org.mitk.gui.qt.xnat/files.cmake @@ -1,47 +1,50 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_xnatinterface_Activator.cpp + QmitkUploadToXNATAction.cpp QmitkXnatTreeBrowserView.cpp QmitkXnatConnectionPreferencePage.cpp QmitkXnatSessionManager.cpp ) set(UI_FILES src/internal/QmitkXnatTreeBrowserViewControls.ui src/internal/QmitkXnatConnectionPreferencePageControls.ui ) set(MOC_H_FILES src/internal/org_mitk_gui_qt_xnatinterface_Activator.h + src/internal/QmitkUploadToXNATAction.h src/internal/QmitkXnatTreeBrowserView.h src/internal/QmitkXnatConnectionPreferencePage.h ) # list of resource files which can be used by the plug-in # system without loading the plug-ins shared library, # for example the icon used in the menu and tabs for the # plug-in views in the workbench set(CACHED_RESOURCE_FILES resources/icon.xpm resources/xnat_treebrowser_icon.xpm + resources/xnat-icon.png plugin.xml ) # list of Qt .qrc files which contain additional resources # specific to this plugin set(QRC_FILES resources/xnat.qrc ) set(CPP_FILES ) foreach(file ${SRC_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/${file}) endforeach(file ${SRC_CPP_FILES}) foreach(file ${INTERNAL_CPP_FILES}) set(CPP_FILES ${CPP_FILES} src/internal/${file}) endforeach(file ${INTERNAL_CPP_FILES}) diff --git a/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake b/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake index 98df66b9e8..e2123e2708 100644 --- a/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake +++ b/Plugins/org.mitk.gui.qt.xnat/manifest_headers.cmake @@ -1,5 +1,5 @@ set(Plugin-Name "XNAT Plugin") set(Plugin-Version "0.1") set(Plugin-Vendor "DKFZ, Medical and Biological Informatics") set(Plugin-ContactAddress "") -set(Require-Plugin org.mitk.gui.qt.common) +set(Require-Plugin org.mitk.gui.qt.common org.mitk.gui.qt.datamanager) diff --git a/Plugins/org.mitk.gui.qt.xnat/plugin.xml b/Plugins/org.mitk.gui.qt.xnat/plugin.xml index 52064ddba4..b48b949465 100644 --- a/Plugins/org.mitk.gui.qt.xnat/plugin.xml +++ b/Plugins/org.mitk.gui.qt.xnat/plugin.xml @@ -1,49 +1,53 @@ Search, browse and view the data in a XNAT-Installation Search, browse and view the data in a XNAT-Installation + + + + diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-icon.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-icon.png new file mode 100644 index 0000000000..97d4e9b6df Binary files /dev/null and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-icon.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.cpp new file mode 100644 index 0000000000..b81511a7a8 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.cpp @@ -0,0 +1,208 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +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 "QmitkUploadToXNATAction.h" + +//needed for qApp +#include + +#include "org_mitk_gui_qt_xnatinterface_Activator.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +void ShowInfoMessage() +{ + QMessageBox infoBox; + infoBox.setIcon(QMessageBox::Information); + infoBox.setText("You are not connected to a XNAT server!"); + infoBox.setInformativeText("Please use the 'Connect' button in the Preferences."); + infoBox.exec(); +} + +QmitkUploadToXNATAction::QmitkUploadToXNATAction() +{ +} + +QmitkUploadToXNATAction::~QmitkUploadToXNATAction() +{ +} + +void QmitkUploadToXNATAction::Run( const QList &selectedNodes ) +{ + if (selectedNodes.size() != 1) + { + QMessageBox infoBox; + infoBox.setIcon(QMessageBox::Information); + infoBox.setText("Please select only one data node for upload"); + infoBox.exec(); + } + + // Try to get the XNAT session + us::ServiceReference modServiceRef = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference(); + + if (!modServiceRef) + { + ShowInfoMessage(); + return; + } + + us::ModuleContext* xnatModuleContext = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext(); + + if (xnatModuleContext == nullptr) + { + ShowInfoMessage(); + return; + } + + ctkXnatSession *session(nullptr); + session = xnatModuleContext->GetService(modServiceRef); + if (session == nullptr || !session->isOpen()) + { + ShowInfoMessage(); + return; + } + + mitk::DataNode* selectedNode = selectedNodes.at(0); + + if (selectedNode == nullptr) + return; + +///////////////////////////////////////////////////////////////////////////////////// + /* + * TODO + * Preselect possible upload destination by evaluating the xnat.url property of a parent node + * Problem here: We need a valid ctkXnatObject as parent for uploading the file + */ +///////////////////////////////////////////////////////////////////////////////////// +// ctkServiceTracker dataStorageServiceTracker (mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()); +// dataStorageServiceTracker.open(); +// mitk::IDataStorageService* dsService = dataStorageServiceTracker.getService(); +// mitk::DataStorage::Pointer dataStorage = dsService->GetDataStorage()->GetDataStorage(); + +// mitk::NodePredicateProperty::Pointer pred = mitk::NodePredicateProperty::New("xnat.url"); +// mitk::DataStorage::SetOfObjects::ConstPointer result = dataStorage->GetSources(selectedNode, pred); +// mitk::DataStorage::SetOfObjects::ConstIterator it = result->Begin(); + +// QList resourceFolders; +// QStringList resourceNames; +// QString url; +// for (;it != result->End(); ++it) +// { +// mitk::DataNode::Pointer node = it->Value(); + +// std::string xnatUrl(""); +// node->GetStringProperty("xnat.url", xnatUrl); +// url = QString::fromStdString(xnatUrl); + +// int start = url.lastIndexOf("resources/") + 10; //length of "resources/" +// url = url.left(start); + +// std::cout<<"node: "<GetName()<<" --- URL: "<httpGet(url); +// resourceFolders = session->httpResults(uid, ctkXnatDefaultSchemaTypes::XSI_RESOURCE); + +// foreach (ctkXnatObject* obj, resourceFolders) +// { +// resourceNames << obj->name(); +// } +// } +///////////////////////////////////////////////////////////////////////////////////// + + // Dialog for selecting the upload destination + QmitkSelectXnatUploadDestinationDialog dialog(session); + dialog.setWindowTitle("Select XNAT upload destination"); + int returnValue = dialog.exec(); + + if (returnValue == QDialog::Accepted) + { + // Save node + QString fileName (QString::fromStdString(selectedNode->GetName())); + + if (dynamic_cast(selectedNode->GetData())) + { + fileName.append(".nrrd"); + } + else if (dynamic_cast(selectedNode->GetData())) + { + fileName.append(".vtk"); + } + else if (dynamic_cast(selectedNode->GetData())) + { + fileName.append(".mps"); + } + else + { + MITK_WARN << "Could not upload file! File-type not supported"; + QMessageBox msgbox; + msgbox.setText("Could not upload file! File-type not supported"); + msgbox.setIcon(QMessageBox::Critical); + msgbox.exec(); + return; + } + + QString xnatFolder = "XNAT_UPLOADS"; + QDir dir(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()->getDataFile("").absoluteFilePath()); + dir.mkdir(xnatFolder); + + fileName = dir.path().append("/" + fileName); + mitk::IOUtil::Save (selectedNode->GetData(), fileName.toStdString()); + + // Upload the file to XNAT + ctkXnatResource* uploadDestination = dialog.GetUploadDestination(); + if (uploadDestination != nullptr) + { + ctkXnatFile* file = new ctkXnatFile(uploadDestination); + file->setLocalFilePath(fileName); + QFileInfo fileInfo (fileName); + file->setName(fileInfo.fileName()); + file->save(); + } + } +// dataStorageServiceTracker.close(); +} + +void QmitkUploadToXNATAction::SetDataStorage(mitk::DataStorage* /*dataStorage*/) +{ + //not needed +} + +void QmitkUploadToXNATAction::SetFunctionality(berry::QtViewPart* /*functionality*/) +{ + //not needed +} + +void QmitkUploadToXNATAction::SetSmoothed(bool /*smoothed*/) +{ + //not needed +} + +void QmitkUploadToXNATAction::SetDecimated(bool /*smoothed*/) +{ + //not needed +} diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.h new file mode 100644 index 0000000000..b2a5925b51 --- /dev/null +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkUploadToXNATAction.h @@ -0,0 +1,50 @@ +/*=================================================================== + +The Medical Imaging Interaction Toolkit (MITK) + +Copyright (c) German Cancer Research Center, +Division of Medical and Biological Informatics. +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. + +===================================================================*/ +#ifndef QMITK_UPLOADTOXNATACTION_H +#define QMITK_UPLOADTOXNATACTION_H + +#include "mitkIContextMenuAction.h" + +#include "org_mitk_gui_qt_xnat_Export.h" + +#include "mitkDataNode.h" + +class XNAT_EXPORT QmitkUploadToXNATAction : public QObject, public mitk::IContextMenuAction +{ + Q_OBJECT + Q_INTERFACES(mitk::IContextMenuAction) + +public: + + QmitkUploadToXNATAction(); + virtual ~QmitkUploadToXNATAction(); + + //interface methods + void Run( const QList& selectedNodes ) override; + + // Setters + void SetDataStorage(mitk::DataStorage* dataStorage) override; + void SetSmoothed(bool smoothed) override; + void SetDecimated(bool decimated) override; + void SetFunctionality(berry::QtViewPart* functionality) override; + +private: + + typedef QList NodeList; + +}; + +#endif // QMITK_UPLOADTOXNATACTION_H diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp index af07fd153d..db5c9ec13f 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/org_mitk_gui_qt_xnatinterface_Activator.cpp @@ -1,71 +1,73 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. 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 "org_mitk_gui_qt_xnatinterface_Activator.h" #include +#include "QmitkUploadToXNATAction.h" #include "QmitkXnatTreeBrowserView.h" #include "QmitkXnatConnectionPreferencePage.h" #include #include US_INITIALIZE_MODULE namespace mitk { -ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::m_Context = 0; -us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::m_ModuleContext = 0; +ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::m_Context = nullptr; +us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::m_ModuleContext = nullptr; QmitkXnatSessionManager* org_mitk_gui_qt_xnatinterface_Activator::GetXnatSessionManager() { static QmitkXnatSessionManager manager; return &manager; } ctkPluginContext* org_mitk_gui_qt_xnatinterface_Activator::GetContext() { return m_Context; } us::ModuleContext* org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext() { return m_ModuleContext; } void org_mitk_gui_qt_xnatinterface_Activator::start(ctkPluginContext* context) { this->m_Context = context; this->m_ModuleContext = us::GetModuleContext(); BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatTreeBrowserView, context) BERRY_REGISTER_EXTENSION_CLASS(QmitkXnatConnectionPreferencePage, context) + BERRY_REGISTER_EXTENSION_CLASS(QmitkUploadToXNATAction, context) } void org_mitk_gui_qt_xnatinterface_Activator::stop(ctkPluginContext* context) { Q_UNUSED(context) Q_UNUSED(us::GetModuleContext()) this->m_Context = 0; this->m_ModuleContext = 0; } } #if QT_VERSION < QT_VERSION_CHECK(5, 0, 0) Q_EXPORT_PLUGIN2(org_mitk_gui_qt_xnatinterface, mitk::org_mitk_gui_qt_xnatinterface_Activator) #endif