diff --git a/Modules/XNAT/files.cmake b/Modules/XNAT/files.cmake index dec4c2727b..46c800680e 100644 --- a/Modules/XNAT/files.cmake +++ b/Modules/XNAT/files.cmake @@ -1,31 +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 + 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/QmitkXnatUploadFromDataStorageDialog.h +) +set(UI_FILES + src/QmitkXnatUploadFromDataStorageDialog.ui ) set(QRC_FILES resources/xnat.qrc ) set(UI_FILES src/QmitkXnatProjectWidgetControls.ui src/QmitkXnatSubjectWidgetControls.ui src/QmitkXnatExperimentWidgetControls.ui ) diff --git a/Modules/XNAT/include/QmitkXnatTreeModel.h b/Modules/XNAT/include/QmitkXnatTreeModel.h index ad4ab5fd47..fc680f6e71 100644 --- a/Modules/XNAT/include/QmitkXnatTreeModel.h +++ b/Modules/XNAT/include/QmitkXnatTreeModel.h @@ -1,51 +1,51 @@ /*=================================================================== 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 QMITKXNATTREEMODEL_H #define QMITKXNATTREEMODEL_H // CTK includes #include // MITK includes #include "MitkXNATExports.h" namespace mitk { class DataNode; } class MITKXNAT_EXPORT QmitkXnatTreeModel : public ctkXnatTreeModel { Q_OBJECT public: QmitkXnatTreeModel(); virtual QVariant data(const QModelIndex& index, int role) const; virtual bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent); using QAbstractItemModel::supportedDropActions; virtual Qt::DropActions supportedDropActions(); virtual Qt::ItemFlags flags(const QModelIndex &index) const; signals: - void ResourceDropped(const QList&, ctkXnatObject*); + void ResourceDropped(const QList&, ctkXnatObject*, const QModelIndex&); }; #endif // QMITKXNATTREEMODEL_H diff --git a/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h b/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h new file mode 100644 index 0000000000..819621543a --- /dev/null +++ b/Modules/XNAT/include/QmitkXnatUploadFromDataStorageDialog.h @@ -0,0 +1,46 @@ +#ifndef QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H +#define QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H + +#include + +#include + +namespace Ui { +class QmitkXnatUploadFromDataStorageDialog; +} + +namespace mitk { +class DataStorage; +} + +class QmitkXnatUploadFromDataStorageDialog : public QDialog +{ + Q_OBJECT + +public: + explicit QmitkXnatUploadFromDataStorageDialog(QWidget *parent = 0); + ~QmitkXnatUploadFromDataStorageDialog(); + + void SetDataStorage(mitk::DataStorage* ds); + mitk::DataNode::Pointer GetSelectedNode(); + + enum + { + UPLOAD, CANCEL + }; + +protected slots: + + void OnUpload(); + void OnUploadSceneChecked(); + void OnCancel(); + + void OnMITKProjectFileNameEntered(const QString &text); + void OnDataSelected(const mitk::DataNode*); +private: + Ui::QmitkXnatUploadFromDataStorageDialog *ui; + + mitk::DataNode::Pointer m_SelectedNode; +}; + +#endif // QMITKXNATUPLOADFROMDATASTORAGEDIALOG_H diff --git a/Modules/XNAT/src/QmitkXnatTreeModel.cpp b/Modules/XNAT/src/QmitkXnatTreeModel.cpp index 64703ceed4..1c22560a11 100644 --- a/Modules/XNAT/src/QmitkXnatTreeModel.cpp +++ b/Modules/XNAT/src/QmitkXnatTreeModel.cpp @@ -1,111 +1,116 @@ /*=================================================================== 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 "QmitkXnatTreeModel.h" #include #include #include +#include #include +#include +#include #include -#include QmitkXnatTreeModel::QmitkXnatTreeModel () : ctkXnatTreeModel() { } QVariant QmitkXnatTreeModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } if (role == Qt::DecorationRole) { ctkXnatObject* xnatObject = this->xnatObject(index); QString path; if(dynamic_cast(xnatObject)) { path = ":/xnat/server.ico"; } else if(dynamic_cast(xnatObject)) { path = ":/xnat/project.ico"; } else if(dynamic_cast(xnatObject)) { path = ":/xnat/subject.ico"; } else if(dynamic_cast(xnatObject)) { path = ":/xnat/experiment.ico"; } return QIcon(path); } return ctkXnatTreeModel::data(index, role); } bool QmitkXnatTreeModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int /*row*/, int /*column*/, const QModelIndex &parent) { if (action == Qt::IgnoreAction) return true; // Return true if data can be handled bool returnVal (false); if (data->hasFormat(QmitkMimeTypes::DataNodePtrs)) { returnVal = true; QList droppedNodes = QmitkMimeTypes::ToDataNodePtrList(data); - ctkXnatObject* parentObj = this->xnatObject(parent); - emit ResourceDropped(droppedNodes, parentObj); + ctkXnatObject* parentXnatObj = this->xnatObject(parent); + emit ResourceDropped(droppedNodes, parentXnatObj, parent); } return returnVal; } Qt::DropActions QmitkXnatTreeModel::supportedDropActions() { return Qt::CopyAction; } Qt::ItemFlags QmitkXnatTreeModel::flags(const QModelIndex &index) const { Qt::ItemFlags defaultFlags = ctkXnatTreeModel::flags(index); if (index.isValid()) { - ctkXnatProject* xnatProj = dynamic_cast(this->xnatObject(index)); + bool droppingAllowed = dynamic_cast(this->xnatObject(index)) != nullptr; + droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; + droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; + droppingAllowed |= dynamic_cast(this->xnatObject(index)) != nullptr; - // No dropping at project level allowed - if (xnatProj == NULL) + // No dropping at project, session or data model level allowed + if (droppingAllowed) { return Qt::ItemIsDropEnabled | defaultFlags; } else { return defaultFlags; } } else return defaultFlags; } diff --git a/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp new file mode 100644 index 0000000000..989dbfcb47 --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.cpp @@ -0,0 +1,71 @@ +#include "QmitkXnatUploadFromDataStorageDialog.h" +#include "ui_QmitkXnatUploadFromDataStorageDialog.h" + +#include +#include +#include +#include + +QmitkXnatUploadFromDataStorageDialog::QmitkXnatUploadFromDataStorageDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::QmitkXnatUploadFromDataStorageDialog), + m_SelectedNode(0) +{ + ui->setupUi(this); + + // Not yet implemented + ui->cbUploadMITKProject->hide(); + ui->leMITKProjectFileName->hide(); + // + + connect(ui->btnCancel, SIGNAL(clicked()), this, SLOT(OnCancel())); + connect(ui->btnUpload, SIGNAL(clicked()), this, SLOT(OnUpload())); + connect(ui->cbUploadMITKProject, SIGNAL(checked()), this, SLOT(OnUploadSceneChecked())); + connect(ui->leMITKProjectFileName, SIGNAL(textEdited(const QString&)), this, SLOT(OnMITKProjectFileNameEntered(const QString&))); + connect(ui->cBDataSelection, SIGNAL(OnSelectionChanged(const mitk::DataNode*)), this, SLOT(OnDataSelected(const mitk::DataNode*))); + + mitk::NodePredicateNot::Pointer noHelper = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("helper object")); + mitk::NodePredicateNot::Pointer noHidden = mitk::NodePredicateNot::New(mitk::NodePredicateProperty::New("hidden object")); + mitk::NodePredicateAnd::Pointer pred = mitk::NodePredicateAnd::New(noHelper, noHidden); + ui->cBDataSelection->SetPredicate(pred); +} + +QmitkXnatUploadFromDataStorageDialog::~QmitkXnatUploadFromDataStorageDialog() +{ + delete ui; +} + +void QmitkXnatUploadFromDataStorageDialog::SetDataStorage(mitk::DataStorage *ds) +{ + ui->cBDataSelection->SetDataStorage(ds); +} + +void QmitkXnatUploadFromDataStorageDialog::OnUpload() +{ + this->done(UPLOAD); +} + +void QmitkXnatUploadFromDataStorageDialog::OnUploadSceneChecked() +{ +} + +void QmitkXnatUploadFromDataStorageDialog::OnCancel() +{ + this->done(CANCEL); +} + +void QmitkXnatUploadFromDataStorageDialog::OnMITKProjectFileNameEntered(const QString& /*text*/) +{ +} + +void QmitkXnatUploadFromDataStorageDialog::OnDataSelected(const mitk::DataNode* node) +{ + m_SelectedNode = const_cast(node); + if (m_SelectedNode.IsNotNull()) + ui->btnUpload->setEnabled(true); +} + +mitk::DataNode::Pointer QmitkXnatUploadFromDataStorageDialog::GetSelectedNode() +{ + return m_SelectedNode; +} diff --git a/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.ui b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.ui new file mode 100644 index 0000000000..d28dc01caa --- /dev/null +++ b/Modules/XNAT/src/QmitkXnatUploadFromDataStorageDialog.ui @@ -0,0 +1,89 @@ + + + QmitkXnatUploadFromDataStorageDialog + + + + 0 + 0 + 400 + 164 + + + + Dialog + + + + + + Select the data for upload: + + + + + + + + + + Uploads all data as MITK project file + + + Upload scene as MITK project file + + + + + + + Enter project file name + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Cancel + + + + + + + false + + + Upload + + + + + + + + + + QmitkDataStorageComboBox + QComboBox +
QmitkDataStorageComboBox.h
+
+
+ + +
diff --git a/Plugins/org.mitk.gui.qt.xnat/files.cmake b/Plugins/org.mitk.gui.qt.xnat/files.cmake index 0a26dcea91..f0a27c0ce6 100644 --- a/Plugins/org.mitk.gui.qt.xnat/files.cmake +++ b/Plugins/org.mitk.gui.qt.xnat/files.cmake @@ -1,46 +1,47 @@ set(SRC_CPP_FILES ) set(INTERNAL_CPP_FILES org_mitk_gui_qt_xnatinterface_Activator.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/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 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/resources/xnat-download.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-download.png new file mode 100644 index 0000000000..cdc6b22a4d Binary files /dev/null and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-download.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.png new file mode 100644 index 0000000000..2adc69f865 Binary files /dev/null and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-folder.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png new file mode 100644 index 0000000000..54c8236f9e Binary files /dev/null and b/Plugins/org.mitk.gui.qt.xnat/resources/xnat-upload.png differ diff --git a/Plugins/org.mitk.gui.qt.xnat/resources/xnat.qrc b/Plugins/org.mitk.gui.qt.xnat/resources/xnat.qrc new file mode 100644 index 0000000000..c0e23b477a --- /dev/null +++ b/Plugins/org.mitk.gui.qt.xnat/resources/xnat.qrc @@ -0,0 +1,7 @@ + + + xnat-download.png + xnat-upload.png + xnat-folder.png + + diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp index 6a152a7c9a..28b5fd98bc 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.cpp @@ -1,726 +1,830 @@ /*=================================================================== 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 "QmitkXnatTreeBrowserView.h" // Qmitk #include "org_mitk_gui_qt_xnatinterface_Activator.h" // Blueberry #include #include // CTK XNAT Core #include #include +#include #include #include #include "ctkXnatFile.h" #include #include #include #include #include #include #include #include // MITK XNAT #include #include #include #include // Qt #include #include #include #include #include #include #include #include #include #include // MITK #include -#include #include +#include // Poco #include const std::string QmitkXnatTreeBrowserView::VIEW_ID = "org.mitk.views.xnat.treebrowser"; QmitkXnatTreeBrowserView::QmitkXnatTreeBrowserView() : m_DataStorageServiceTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()), m_TreeModel(new QmitkXnatTreeModel()), m_Tracker(0), m_DownloadPath(berry::Platform::GetPreferencesService()->GetSystemPreferences()->Node("/XnatConnection")->Get("Download Path", "")) { m_DataStorageServiceTracker.open(); // Set DownloadPath if (m_DownloadPath.isEmpty()) { QString xnatFolder = "XNAT_DOWNLOADS"; QDir dir(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetContext()->getDataFile("").absoluteFilePath()); dir.mkdir(xnatFolder); dir.setPath(dir.path() + "/" + xnatFolder); m_DownloadPath = dir.path() + "/"; } } QmitkXnatTreeBrowserView::~QmitkXnatTreeBrowserView() { m_DataStorageServiceTracker.close(); delete m_TreeModel; delete m_Tracker; } void QmitkXnatTreeBrowserView::SetFocus() { } void QmitkXnatTreeBrowserView::CreateQtPartControl(QWidget *parent) { // Create GUI widgets from the Qt Designer's .ui file m_Controls.setupUi(parent); m_Controls.treeView->setModel(m_TreeModel); m_Controls.treeView->header()->hide(); m_Controls.treeView->setSelectionMode(QAbstractItemView::ExtendedSelection); m_Controls.treeView->setAcceptDrops(true); m_Controls.treeView->setDropIndicatorShown(true); m_Controls.labelError->setText("Please use the 'Connect' button in the Preferences."); m_Controls.labelError->setStyleSheet("QLabel { color: red; }"); m_SelectionProvider = new berry::QtSelectionProvider(); this->SetSelectionProvider(); m_Controls.treeView->setSelectionMode(QAbstractItemView::SingleSelection); m_Controls.treeView->setContextMenuPolicy(Qt::CustomContextMenu); + m_Controls.groupBox->hide(); + m_Tracker = new mitk::XnatSessionTracker(mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()); m_ContextMenu = new QMenu(m_Controls.treeView); connect(m_Controls.treeView, SIGNAL(clicked(const QModelIndex&)), SLOT(itemSelected(const QModelIndex&))); connect(m_Controls.treeView, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OnContextMenuRequested(const QPoint&))); connect(m_Tracker, SIGNAL(AboutToBeClosed(ctkXnatSession*)), this, SLOT(CleanTreeModel(ctkXnatSession*))); connect(m_Tracker, SIGNAL(Opened(ctkXnatSession*)), this, SLOT(UpdateSession(ctkXnatSession*))); m_Tracker->Open(); ctkXnatSession* session; try { session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); } catch (std::invalid_argument) { session = 0; } if (session != 0) { m_Controls.labelError->setVisible(false); } else { m_Controls.labelError->setVisible(true); } - connect(m_Controls.treeView, SIGNAL(activated(const QModelIndex&)), this, SLOT(OnActivatedNode(const QModelIndex&))); - connect(m_TreeModel, SIGNAL(ResourceDropped(const QList&, ctkXnatObject*)), this, SLOT(OnUploadResource(const QList&, ctkXnatObject*))); + connect(m_Controls.treeView, SIGNAL(doubleClicked(const QModelIndex&)), this, SLOT(OnActivatedNode(const QModelIndex&))); + connect(m_Controls.treeView, SIGNAL(clicked(const QModelIndex&)), this, SLOT(OnXnatNodeSelected(const QModelIndex&))); + connect(m_TreeModel, SIGNAL(ResourceDropped(const QList&, ctkXnatObject*, const QModelIndex&)), this, SLOT(OnUploadResource(const QList&, ctkXnatObject*, const QModelIndex&))); + + connect(m_Controls.btnXnatUpload, SIGNAL(clicked()), this, SLOT(OnUploadFromDataStorage())); + connect(m_Controls.btnXnatDownload, SIGNAL(clicked()), this, SLOT(OnDownloadSelectedXnatFile())); + connect(m_Controls.btnCreateXnatFolder, SIGNAL(clicked()), this, SLOT(OnCreateResourceFolder())); +} + +void QmitkXnatTreeBrowserView::OnCreateResourceFolder() +{ + QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); + + if(!index.isValid()) return; + + ctkXnatObject* parent = index.data(Qt::UserRole).value(); + + this->InternalAddResourceFolder(parent); + m_TreeModel->refresh(index); +} + +void QmitkXnatTreeBrowserView::OnDownloadSelectedXnatFile() +{ + QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); + + if(!index.isValid()) return; + + ctkXnatObject* selectedXnatObject = index.data(Qt::UserRole).value(); + + ctkXnatFile* selectedXnatFile = dynamic_cast(selectedXnatObject); + + if (selectedXnatFile != nullptr) + { + this->InternalFileDownload(index, true); + } +} + +void QmitkXnatTreeBrowserView::OnUploadFromDataStorage() +{ + QmitkXnatUploadFromDataStorageDialog dialog; + dialog.SetDataStorage(this->GetDataStorage()); + int result = dialog.exec(); + + if (result == QmitkXnatUploadFromDataStorageDialog::UPLOAD) + { + QList nodes; + nodes << dialog.GetSelectedNode().GetPointer(); + QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); + + if (!index.isValid()) return; + ctkXnatObject* parent = m_TreeModel->xnatObject(index); + this->OnUploadResource(nodes, parent, index); + } +} + +void QmitkXnatTreeBrowserView::OnXnatNodeSelected(const QModelIndex& index) +{ + // Enable download button + if (!index.isValid()) return; + + ctkXnatObject* selectedXnatObject = index.data(Qt::UserRole).value(); + + bool enableDownload = dynamic_cast(selectedXnatObject); + m_Controls.btnXnatDownload->setEnabled(enableDownload); + + bool enableCreateFolder = dynamic_cast(selectedXnatObject) != nullptr; + enableCreateFolder |= dynamic_cast(selectedXnatObject) != nullptr; + enableCreateFolder |= dynamic_cast(selectedXnatObject) != nullptr; + m_Controls.btnCreateXnatFolder->setEnabled(enableCreateFolder); + + bool enableUpload = dynamic_cast(selectedXnatObject) != nullptr; + m_Controls.btnXnatUpload->setEnabled(enableUpload); } void QmitkXnatTreeBrowserView::OnActivatedNode(const QModelIndex& index) { if (!index.isValid()) return; ctkXnatFile* file = dynamic_cast(index.data(Qt::UserRole).value()); if (file != NULL) { // If the selected node is a file, so show it in MITK InternalFileDownload(index, true); } } void QmitkXnatTreeBrowserView::SetSelectionProvider() { GetSite()->SetSelectionProvider(m_SelectionProvider); } void QmitkXnatTreeBrowserView::UpdateSession(ctkXnatSession* session) { if (session != 0 && session->isOpen()) { m_Controls.labelError->setVisible(false); // Fill model and show in the GUI m_TreeModel->addDataModel(session->dataModel()); m_Controls.treeView->reset(); m_SelectionProvider->SetItemSelectionModel(m_Controls.treeView->selectionModel()); connect(session, SIGNAL(progress(QUuid,double)), this, SLOT(OnProgress(QUuid,double))); - connect(session, SIGNAL(uploadFinished()), this, SLOT(OnProgress(QUuid,double))); } } void QmitkXnatTreeBrowserView::CleanTreeModel(ctkXnatSession* session) { if (session != 0) { m_TreeModel->removeDataModel(session->dataModel()); m_Controls.treeView->reset(); } } void QmitkXnatTreeBrowserView::OnProgress(QUuid /*queryID*/, double progress) { unsigned int currentProgress = progress*100; - if (currentProgress < 1) - mitk::ProgressBar::GetInstance()->AddStepsToDo(100); - else - mitk::ProgressBar::GetInstance()->Progress(); + if (m_Controls.groupBox->isHidden()) + { + m_Controls.groupBox->show(); + m_Controls.progressBar->setValue(0); + } + m_Controls.progressBar->setValue(currentProgress); } void QmitkXnatTreeBrowserView::InternalFileDownload(const QModelIndex& index, bool loadData) { QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatFile* file = dynamic_cast(variant.value()); if (file != NULL) { QDir downDir(m_DownloadPath); QString filePath = m_DownloadPath + file->name(); - // Testing if the file exists already + // Checking if the file exists already if (downDir.exists(file->name())) { MITK_INFO << "File '" << file->name().toStdString() << "' already exists!"; } else { if (file->property("collection") == QString("DICOM")) { ctkXnatObject* parent = file->parent(); filePath = m_DownloadPath + parent->property("label") + ".zip"; + + m_Controls.groupBox->setTitle("Downloading DICOM series..."); + m_Controls.groupBox->show(); + m_Controls.progressBar->setValue(0); + parent->download(filePath); std::ifstream in(filePath.toStdString().c_str(), std::ios::binary); poco_assert(in); // decompress to XNAT_DOWNLOAD dir Poco::Zip::Decompress dec(in, Poco::Path(m_DownloadPath.toStdString())); dec.decompressAllFiles(); in.close(); QFile::remove(filePath); } else { MITK_INFO << "Download started ..."; - MITK_INFO << "..."; + + m_Controls.groupBox->setTitle("Downloading file..."); + m_Controls.groupBox->show(); + m_Controls.progressBar->setValue(0); + file->download(filePath); - // Testing if the file exists now + // Checking if the file exists now if (downDir.exists(file->name())) { - MITK_INFO << "Download of " << file->name().toStdString() << " was completed!"; + MITK_INFO << "Download of " << file->name().toStdString() << " completed!"; + QMessageBox msgBox; + msgBox.setText("Download of " + file->name() + " completed!"); + msgBox.setIcon(QMessageBox::Information); + msgBox.exec(); + m_Controls.groupBox->hide(); } else { MITK_INFO << "Download of " << file->name().toStdString() << " failed!"; + QMessageBox msgBox; + msgBox.setText("Download of " + file->name() + " failed!"); + msgBox.setIcon(QMessageBox::Critical); + msgBox.exec(); + m_Controls.groupBox->hide(); + return; } } } if (downDir.exists(file->name()) || file->property("collection") == "DICOM") { if (loadData) { if (file->property("collection") == "DICOM") { // Search for the downloaded file an its file path QDirIterator it(m_DownloadPath, QStringList() << file->name(), QDir::Files, QDirIterator::Subdirectories); while (it.hasNext()) { it.next(); filePath = it.filePath(); } } if (filePath.isEmpty()) { MITK_INFO << "Decompressing failed!"; return; } else if (!QFile(filePath).exists()) { MITK_INFO << "Decompressing failed!"; return; } mitk::IDataStorageService* dsService = m_DataStorageServiceTracker.getService(); mitk::DataStorage::Pointer dataStorage = dsService->GetDataStorage()->GetDataStorage(); QStringList list; list << filePath; try { QmitkIOUtil::Load(list, *dataStorage); } catch (const mitk::Exception& e) { MITK_INFO << e; return; } mitk::RenderingManager::GetInstance()->InitializeViewsByBoundingObjects( dsService->GetDataStorage()->GetDataStorage()); } } } else { MITK_INFO << "Selection was not a file!"; } } } void QmitkXnatTreeBrowserView::OnContextMenuDownloadFile() { QModelIndex index = m_Controls.treeView->currentIndex(); InternalFileDownload(index, false); } void QmitkXnatTreeBrowserView::OnContextMenuDownloadAndOpenFile() { QModelIndex index = m_Controls.treeView->currentIndex(); InternalFileDownload(index, true); } void QmitkXnatTreeBrowserView::OnContextMenuCreateResourceFolder() { const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); ctkXnatObject* parentObject = m_TreeModel->xnatObject(index); if (parentObject != nullptr) { this->InternalAddResourceFolder(parentObject); } } ctkXnatResource* QmitkXnatTreeBrowserView::InternalAddResourceFolder(ctkXnatObject *parent) { bool ok; QString folderName = QInputDialog::getText(m_Controls.treeView, tr("Create XNAT resource folder"), tr("Folder name:"), QLineEdit::Normal, tr("data"), &ok); if (ok) { if (folderName.isEmpty()) folderName = "NO LABEL"; return parent->addResourceFolder(folderName); } else { return nullptr; } } void QmitkXnatTreeBrowserView::InternalFileUpload(ctkXnatFile* file) { + m_Controls.groupBox->setTitle("Uploading file..."); + m_Controls.groupBox->show(); + try { file->save(); + MITK_INFO << "Upload of " << file->name().toStdString() << " completed!"; + QMessageBox msgBox; + msgBox.setText("Upload of " + file->name() + " completed!"); + msgBox.setIcon(QMessageBox::Information); + msgBox.show(); + msgBox.exec(); } catch (ctkXnatException &e) { QMessageBox msgbox; msgbox.setText(e.what()); msgbox.setIcon(QMessageBox::Critical); msgbox.exec(); + m_Controls.progressBar->setValue(0); } + m_Controls.groupBox->hide(); } void QmitkXnatTreeBrowserView::OnContextMenuUploadFile() { QString filename = QFileDialog::getOpenFileName(m_Controls.treeView, tr("Open File"), QDir::homePath()); const QModelIndex index = m_Controls.treeView->selectionModel()->currentIndex(); ctkXnatResource* resource = dynamic_cast(m_TreeModel->xnatObject(index)); if (resource) { ctkXnatFile* file = new ctkXnatFile(resource); file->setLocalFilePath(filename); QFileInfo fileInfo (filename); file->setName(fileInfo.fileName()); - file->setFileFormat("some format"); - file->setFileContent("some content"); - file->setFileTags("some, tags"); - file->save(); + this->InternalFileUpload(file); m_TreeModel->addChildNode(index, file); } } -#include -void QmitkXnatTreeBrowserView::OnUploadResource(const QList& droppedNodes, ctkXnatObject* parentObject) +void QmitkXnatTreeBrowserView::OnUploadResource(const QList& droppedNodes, ctkXnatObject* parentObject, const QModelIndex& parentIndex) { if (parentObject == nullptr) return; - if (dynamic_cast(parentObject)) - MITK_INFO<<"SESSION"; - else if (dynamic_cast(parentObject)) - MITK_INFO<<"DATAMODEL"; - else if (dynamic_cast(parentObject)) - MITK_INFO<<"PROJECT"; - else if (dynamic_cast(parentObject)) - MITK_INFO<<"SUBJECT"; //1. If not dropped on a resource, create a new folder - //2. Save file locally - //3. Upload file ctkXnatResource* resource = dynamic_cast(parentObject); if (resource == nullptr) { resource = this->InternalAddResourceFolder(parentObject); } if (resource == nullptr) { MITK_WARN << "Could not upload file! No resource available!"; + QMessageBox msgbox; + msgbox.setText("Could not upload file! No resource available!"); + msgbox.setIcon(QMessageBox::Critical); + msgbox.exec(); + return; } + //2. Save files locally + //3. Upload file mitk::DataNode* node = NULL; foreach (node, droppedNodes) { mitk::BaseData* data = node->GetData(); if (!data) return; QString fileName (QString::fromStdString(node->GetName())); ctkXnatFile* xnatFile = new ctkXnatFile(resource); if (dynamic_cast(data)) { fileName.append(".nrrd"); } else if (dynamic_cast(data)) { fileName.append(".vtk"); } else if (dynamic_cast(data)) { 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(); + } xnatFile->setName(fileName); 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 (data, fileName.toStdString()); // TODO Check if file exists // AbstractFileReader::SetDefaultDataNodeProperties // und in die andere SetDefaultDataNodeProperties // PropertyName klein: mtime.initial + Kommentar mitk::StringProperty::Pointer orignalFilePath = mitk::StringProperty::New(); node->GetProperty(orignalFilePath, "path"); xnatFile->setLocalFilePath(fileName); - // - xnatFile->setFileFormat("some format"); - xnatFile->setFileContent("some content"); - xnatFile->setFileTags("some, tags"); - // - xnatFile->save(); - m_TreeModel->addChildNode(m_Controls.treeView->currentIndex(), xnatFile); - parentObject->fetch(); + + this->InternalFileUpload(xnatFile); + MITK_INFO << "XNAT-OBJECT: "<xnatObject(parentIndex)->name(); + +// m_TreeModel->addChildNode(parentIndex, xnatFile); + m_TreeModel->refresh(parentIndex); // The filename for uploading // QFileInfo fileInfo; // if (surface) // { // // Save surface // fileName.append(".stl"); // xnatFile->setName(fileName); // dir.setPath(dir.path().append("/" + fileName)); // QString origFile = QString::fromStdString(orignalFilePath->GetValueAsString()); // origFile.append("/" + fileName); // origFile.append(".stl"); // fileInfo.setFile(origFile); // if (!fileInfo.exists()) // mitk::IOUtil::SaveSurface(surface, dir.path().toStdString()); // } // this->uploadFileToXnat(xnatFile, dir.path()); // TODO delete file!!! } } void QmitkXnatTreeBrowserView::OnContextMenuRequested(const QPoint & pos) { m_ContextMenu->clear(); QModelIndex index = m_Controls.treeView->indexAt(pos); 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; bool canHaveResourceFolder = false; canHaveResourceFolder |= dynamic_cast(xnatObject) != NULL; canHaveResourceFolder |= dynamic_cast(xnatObject) != NULL; canHaveResourceFolder |= dynamic_cast(xnatObject) != NULL; bool uploadFilePossible = false; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; uploadFilePossible |= dynamic_cast(xnatObject) != NULL; if (downloadable) { QAction* actDownload = new QAction("Download", m_ContextMenu); connect(actDownload, SIGNAL(triggered()), this, SLOT(OnContextMenuDownloadFile())); m_ContextMenu->addAction(actDownload); ctkXnatFile* file = dynamic_cast(xnatObject); if (file) { QAction* actView = new QAction("Download and Open", m_ContextMenu); connect(actView, SIGNAL(triggered()), this, SLOT(OnContextMenuDownloadAndOpenFile())); m_ContextMenu->addAction(actView); } } if (canHaveResourceFolder) { QAction* actCreateResource = new QAction("Add resource folder", m_ContextMenu); connect(actCreateResource, SIGNAL(triggered()), this, SLOT(OnContextMenuCreateResourceFolder())); m_ContextMenu->addAction(actCreateResource); } if (uploadFilePossible) { QAction* actUploadFile = new QAction("Upload File", m_ContextMenu); connect(actUploadFile, SIGNAL(triggered()), this, SLOT(OnContextMenuUploadFile())); m_ContextMenu->addAction(actUploadFile); } ctkXnatProject* project = dynamic_cast(xnatObject); if (project != NULL) { QAction* actCreateSubject = new QAction("Create new subject", m_ContextMenu); m_ContextMenu->addAction(actCreateSubject); connect(actCreateSubject, SIGNAL(triggered()), this, SLOT(OnContextMenuCreateNewSubject())); m_ContextMenu->popup(QCursor::pos()); } ctkXnatSubject* subject = dynamic_cast(xnatObject); if (subject != NULL) { QAction* actCreateExperiment = new QAction("Create new experiment", m_ContextMenu); m_ContextMenu->addAction(actCreateExperiment); connect(actCreateExperiment, SIGNAL(triggered()), this, SLOT(OnContextMenuCreateNewExperiment())); m_ContextMenu->popup(QCursor::pos()); } m_ContextMenu->popup(QCursor::pos()); } void QmitkXnatTreeBrowserView::itemSelected(const QModelIndex& index) { QLayout* layout = m_Controls.infoVerticalLayout; QLayoutItem *child; while ((child = layout->takeAt(0)) != 0) { delete child->widget(); } QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { ctkXnatSession *session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); ctkXnatObject* object = variant.value(); ctkXnatProject* project = dynamic_cast(object); ctkXnatSubject* subject = dynamic_cast(object); ctkXnatExperiment* experiment = dynamic_cast(object); if (project != NULL) { QmitkXnatProjectWidget* widget = new QmitkXnatProjectWidget(QmitkXnatProjectWidget::Mode::INFO); widget->SetProject(project); layout->addWidget(widget); } else if (subject != NULL) { QMap paramMap; paramMap.insert("columns", "dob,gender,handedness,weight,height"); QUuid requestID = session->httpGet(QString("%1/subjects").arg(subject->parent()->resourceUri()), paramMap); QList results = session->httpSync(requestID); foreach(const QVariantMap& propertyMap, results) { QMapIterator it(propertyMap); bool isConcretSubject = false; if (it.hasNext()) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); // After CTK Change (subjectID = name) to (subjectID = ID) // CHANGE TO: if (var == subject->property("ID")) if (var == subject->property("URI").right(11)) { isConcretSubject = true; } else { isConcretSubject = false; } it.toFront(); } while (it.hasNext() && isConcretSubject) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); subject->setProperty(str, var); } } QmitkXnatSubjectWidget* widget = new QmitkXnatSubjectWidget(QmitkXnatSubjectWidget::Mode::INFO); widget->SetSubject(subject); layout->addWidget(widget); } else if (experiment != NULL) { QMap paramMap; paramMap.insert("columns", "date,time,scanner,modality"); QUuid requestID = session->httpGet(QString("%1/experiments").arg(experiment->parent()->resourceUri()), paramMap); QList results = session->httpSync(requestID); foreach(const QVariantMap& propertyMap, results) { QMapIterator it(propertyMap); bool isConcretExperiment = false; if (it.hasNext()) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); if (var == experiment->property("URI")) { isConcretExperiment = true; } else { isConcretExperiment = false; } it.toFront(); } while (it.hasNext() && isConcretExperiment) { it.next(); QString str = it.key().toLatin1().data(); QVariant var = it.value(); experiment->setProperty(str, var); } } QmitkXnatExperimentWidget* widget = new QmitkXnatExperimentWidget(QmitkXnatExperimentWidget::Mode::INFO); widget->SetExperiment(experiment); layout->addWidget(widget); } } } void QmitkXnatTreeBrowserView::OnContextMenuCreateNewSubject() { QModelIndex index = m_Controls.treeView->currentIndex(); QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { QmitkXnatCreateObjectDialog* dialog = new QmitkXnatCreateObjectDialog(QmitkXnatCreateObjectDialog::SpecificType::SUBJECT); if (dialog->exec() == QDialog::Accepted) { ctkXnatProject* project = dynamic_cast(variant.value()); ctkXnatSubject* subject = dynamic_cast(dialog->GetXnatObject()); subject->setParent(project); subject->save(); // Get xnat session from micro service ctkXnatSession* session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); // Update View m_TreeModel->removeDataModel(session->dataModel()); UpdateSession(session); } } } void QmitkXnatTreeBrowserView::OnContextMenuCreateNewExperiment() { QModelIndex index = m_Controls.treeView->currentIndex(); QVariant variant = m_TreeModel->data(index, Qt::UserRole); if (variant.isValid()) { QmitkXnatCreateObjectDialog* dialog = new QmitkXnatCreateObjectDialog(QmitkXnatCreateObjectDialog::SpecificType::EXPERIMENT); if (dialog->exec() == QDialog::Accepted) { ctkXnatSubject* subject = dynamic_cast(variant.value()); ctkXnatExperiment* experiment = dynamic_cast(dialog->GetXnatObject()); experiment->setParent(subject); experiment->setProperty("xsiType", experiment->imageModality()); experiment->save(); // Get xnat session from micro service ctkXnatSession* session = mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetService( mitk::org_mitk_gui_qt_xnatinterface_Activator::GetXnatModuleContext()->GetServiceReference()); // Update View m_TreeModel->removeDataModel(session->dataModel()); UpdateSession(session); } } } diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h index 15ccec9101..9b90eb488f 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserView.h @@ -1,112 +1,118 @@ /*=================================================================== 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 QMITKXNATTREEBROWSERVIEW_H #define QMITKXNATTREEBROWSERVIEW_H #include #include #include "ui_QmitkXnatTreeBrowserViewControls.h" // ctkXnatCore #include "ctkXnatSession.h" // ctkXnatWidget #include "QmitkXnatTreeModel.h" // MitkXNAT Module #include "mitkXnatSessionTracker.h" #include #include class QMenu; /*! \brief QmitkXnatTreeBrowserView \warning This class is not yet documented. Use "git blame" and ask the author to provide basic documentation. \sa QmitkFunctionality \ingroup ${plugin_target}_internal */ class QmitkXnatTreeBrowserView : public QmitkAbstractView { // this is needed for all Qt objects that should have a Qt meta-object // (everything that derives from QObject and wants to have signal/slots) Q_OBJECT public: QmitkXnatTreeBrowserView(); ~QmitkXnatTreeBrowserView(); static const std::string VIEW_ID; virtual void CreateQtPartControl(QWidget *parent) override; - protected slots: +protected slots: /// \brief Opens or reuses the xnat editor with the activated node as root item. void OnActivatedNode(const QModelIndex& index); /// \brief Updates the ctkXnatSession and the user interface void UpdateSession(ctkXnatSession* session); /// \brief Cleans the tree model void CleanTreeModel(ctkXnatSession* session); void OnContextMenuRequested(const QPoint & pos); void OnContextMenuDownloadAndOpenFile(); void OnContextMenuDownloadFile(); void OnContextMenuCreateResourceFolder(); void OnContextMenuUploadFile(); void OnContextMenuCreateNewSubject(); void OnContextMenuCreateNewExperiment(); - void OnUploadResource(const QList& , ctkXnatObject *); + void OnUploadResource(const QList& , ctkXnatObject *, const QModelIndex &parentIndex); void OnProgress(QUuid, double); void itemSelected(const QModelIndex& index); + void OnUploadFromDataStorage(); + protected: virtual void SetFocus() override; Ui::QmitkXnatTreeBrowserViewControls m_Controls; -private: +private slots: + void OnXnatNodeSelected(const QModelIndex &index); + void OnDownloadSelectedXnatFile(); + void OnCreateResourceFolder(); +private: void InternalFileDownload(const QModelIndex& index, bool loadData); void InternalFileUpload(ctkXnatFile *file); ctkXnatResource* InternalAddResourceFolder(ctkXnatObject* parent); berry::QtSelectionProvider::Pointer m_SelectionProvider; void SetSelectionProvider() override; ctkServiceTracker m_DataStorageServiceTracker; QmitkXnatTreeModel* m_TreeModel; mitk::XnatSessionTracker* m_Tracker; QString m_DownloadPath; QMenu* m_ContextMenu; }; #endif // QMITKXNATTREEBROWSERVIEW_H diff --git a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui index a8e0c93d34..f16916886c 100644 --- a/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui +++ b/Plugins/org.mitk.gui.qt.xnat/src/internal/QmitkXnatTreeBrowserViewControls.ui @@ -1,66 +1,158 @@ QmitkXnatTreeBrowserViewControls 0 0 455 - 975 + 284 0 0 QmitkTemplate - - 0 - - - 0 - - - 0 - - - 0 - Qt::AlignCenter 5 0 - + + + + + false + + + Upload to XNAT + + + + + + + + + + :/xnat/xnat-upload.png:/xnat/xnat-upload.png + + + + 32 + 32 + + + + + + + + false + + + Download File + + + + + + + :/xnat/xnat-download.png:/xnat/xnat-download.png + + + + 32 + 32 + + + + + + + + false + + + Create Folder + + + + + + + :/xnat/xnat-folder.png:/xnat/xnat-folder.png + + + + 32 + 32 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + - - - 6 + + + Dowloading file ... + + + + + 0 + + + + + + + + + + + - + + +