Browse Source

Moved the XNAT clases from the org.commontk.xnat plug-in.

Sascha Zelzer 12 years ago
parent
commit
c791e8fb6b
39 changed files with 4106 additions and 0 deletions
  1. 3 0
      CMakeLists.txt
  2. 77 0
      Libs/XNAT/CMakeLists.txt
  3. 39 0
      Libs/XNAT/ctkActivator.cpp
  4. 41 0
      Libs/XNAT/ctkActivator_p.h
  5. 751 0
      Libs/XNAT/ctkXnatConnection.cpp
  6. 123 0
      Libs/XNAT/ctkXnatConnection.h
  7. 88 0
      Libs/XNAT/ctkXnatConnectionFactory.cpp
  8. 47 0
      Libs/XNAT/ctkXnatConnectionFactory.h
  9. 32 0
      Libs/XNAT/ctkXnatException.cpp
  10. 41 0
      Libs/XNAT/ctkXnatException.h
  11. 179 0
      Libs/XNAT/ctkXnatExperiment.cpp
  12. 89 0
      Libs/XNAT/ctkXnatExperiment.h
  13. 187 0
      Libs/XNAT/ctkXnatObject.cpp
  14. 80 0
      Libs/XNAT/ctkXnatObject.h
  15. 155 0
      Libs/XNAT/ctkXnatProject.cpp
  16. 83 0
      Libs/XNAT/ctkXnatProject.h
  17. 148 0
      Libs/XNAT/ctkXnatReconstruction.cpp
  18. 79 0
      Libs/XNAT/ctkXnatReconstruction.h
  19. 95 0
      Libs/XNAT/ctkXnatReconstructionFolder.cpp
  20. 54 0
      Libs/XNAT/ctkXnatReconstructionFolder.h
  21. 148 0
      Libs/XNAT/ctkXnatReconstructionResource.cpp
  22. 81 0
      Libs/XNAT/ctkXnatReconstructionResource.h
  23. 162 0
      Libs/XNAT/ctkXnatReconstructionResourceFile.cpp
  24. 86 0
      Libs/XNAT/ctkXnatReconstructionResourceFile.h
  25. 164 0
      Libs/XNAT/ctkXnatScan.cpp
  26. 87 0
      Libs/XNAT/ctkXnatScan.h
  27. 55 0
      Libs/XNAT/ctkXnatScanFolder.cpp
  28. 45 0
      Libs/XNAT/ctkXnatScanFolder.h
  29. 135 0
      Libs/XNAT/ctkXnatScanResource.cpp
  30. 78 0
      Libs/XNAT/ctkXnatScanResource.h
  31. 157 0
      Libs/XNAT/ctkXnatScanResourceFile.cpp
  32. 85 0
      Libs/XNAT/ctkXnatScanResourceFile.h
  33. 43 0
      Libs/XNAT/ctkXnatServer.cpp
  34. 43 0
      Libs/XNAT/ctkXnatServer.h
  35. 61 0
      Libs/XNAT/ctkXnatSettings.cpp
  36. 58 0
      Libs/XNAT/ctkXnatSettings.h
  37. 137 0
      Libs/XNAT/ctkXnatSubject.cpp
  38. 79 0
      Libs/XNAT/ctkXnatSubject.h
  39. 11 0
      Libs/XNAT/target_libraries.cmake

+ 3 - 0
CMakeLists.txt

@@ -487,6 +487,9 @@ ctk_lib_option(CommandLineModules/Backend/LocalProcess
 ctk_lib_option(CommandLineModules/Backend/FunctionPointer
                "Build the Command Line Module back-end for function pointers" OFF)
 
+ctk_lib_option(XNAT
+               "Build the XNAT library" OFF)
+
 #ctk_lib_option(Visualization/XIP
 #               "Build the XIP library" OFF)
 

+ 77 - 0
Libs/XNAT/CMakeLists.txt

@@ -0,0 +1,77 @@
+project(CTKXNAT)
+
+#
+# See CTK/CMake/ctkMacroBuildLib.cmake for details
+#
+
+set(KIT_export_directive "CTK_XNAT_EXPORT")
+
+set(KIT_SRCS
+  ctkXnatConnection.cpp
+  ctkXnatConnectionFactory.cpp
+  ctkXnatException.cpp
+  ctkXnatExperiment.cpp
+  ctkXnatObject.cpp
+  ctkXnatProject.cpp
+  ctkXnatReconstruction.cpp
+  ctkXnatReconstructionFolder.cpp
+  ctkXnatReconstructionResource.cpp
+  ctkXnatReconstructionResourceFile.cpp
+  ctkXnatScan.cpp
+  ctkXnatScanFolder.cpp
+  ctkXnatScanResource.cpp
+  ctkXnatScanResourceFile.cpp
+  ctkXnatServer.cpp
+  ctkXnatSettings.cpp
+  ctkXnatSubject.cpp
+)
+
+# Files which should be processed by Qts moc
+set(KIT_MOC_SRCS
+  ctkXnatConnection.h
+  ctkXnatExperiment.h
+  ctkXnatObject.h
+  ctkXnatProject.h
+  ctkXnatReconstruction.h
+  ctkXnatReconstructionFolder.h
+  ctkXnatReconstructionResource.h
+  ctkXnatReconstructionResourceFile.h
+  ctkXnatScan.h
+  ctkXnatScanFolder.h
+  ctkXnatScanResource.h
+  ctkXnatScanResourceFile.h
+  ctkXnatServer.h
+  ctkXnatSubject.h
+)
+
+
+# Resources
+set(KIT_resources
+)
+
+find_package(Qt4 COMPONENTS QtScript REQUIRED)
+
+# Target libraries - See CMake/ctkFunctionGetTargetLibraries.cmake
+# The following macro will read the target libraries from the file 'target_libraries.cmake'
+set(KIT_target_libraries)
+
+ctkFunctionGetTargetLibraries(KIT_target_libraries)
+
+ctkMacroBuildLib(
+  NAME ${PROJECT_NAME}
+  EXPORT_DIRECTIVE ${KIT_export_directive}
+  SRCS ${KIT_SRCS}
+  MOC_SRCS ${KIT_MOC_SRCS}
+  UI_FORMS ${KIT_UI_FORMS}
+  TARGET_LIBRARIES ${KIT_target_libraries}
+  RESOURCES ${KIT_resources}
+  LIBRARY_TYPE ${CTK_LIBRARY_MODE}
+  )
+
+## Testing
+#if(BUILD_TESTING)
+#  add_subdirectory(Testing)
+#
+#  # Compile source code snippets
+#  add_subdirectory(Documentation/Snippets)
+#endif()

+ 39 - 0
Libs/XNAT/ctkActivator.cpp

@@ -0,0 +1,39 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  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 "ctkActivator_p.h"
+
+#include <QtPlugin>
+
+void ctkActivator::start(ctkPluginContext* context)
+{
+  Q_UNUSED(context)
+}
+
+void ctkActivator::stop(ctkPluginContext* context)
+{
+  Q_UNUSED(context)
+}
+
+Q_EXPORT_PLUGIN2(org_commontk_xnat, ctkActivator)
+
+

+ 41 - 0
Libs/XNAT/ctkActivator_p.h

@@ -0,0 +1,41 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  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 CTKACTIVATOR_P_H
+#define CTKACTIVATOR_P_H
+
+#include <ctkPluginActivator.h>
+
+class ctkActivator :
+  public QObject, public ctkPluginActivator
+{
+  Q_OBJECT
+  Q_INTERFACES(ctkPluginActivator)
+
+public:
+
+  void start(ctkPluginContext* context);
+  void stop(ctkPluginContext* context);
+
+};
+
+#endif // CTKACTIVATOR_P_H

+ 751 - 0
Libs/XNAT/ctkXnatConnection.cpp

@@ -0,0 +1,751 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatConnection.h"
+
+#include "ctkXnatException.h"
+#include "ctkXnatExperiment.h"
+#include "ctkXnatObject.h"
+#include "ctkXnatProject.h"
+#include "ctkXnatReconstruction.h"
+#include "ctkXnatReconstructionFolder.h"
+#include "ctkXnatReconstructionResource.h"
+#include "ctkXnatReconstructionResourceFile.h"
+#include "ctkXnatScan.h"
+#include "ctkXnatScanFolder.h"
+#include "ctkXnatScanResource.h"
+#include "ctkXnatScanResourceFile.h"
+#include "ctkXnatServer.h"
+#include "ctkXnatSubject.h"
+
+#include <QStringBuilder>
+#include <QDebug>
+#include <QScopedPointer>
+
+#include <qXnatAPI.h>
+#include <qRestResult.h>
+
+class ctkXnatConnectionPrivate
+{
+public:
+  QString url;
+  QString userName;
+  QString password;
+
+  qXnatAPI* xnat;
+  qXnatAPI::RawHeaders rawHeaders;
+
+  ctkXnatServer* server;
+};
+
+// ctkXnatConnection class
+
+ctkXnatConnection::ctkXnatConnection()
+: d_ptr(new ctkXnatConnectionPrivate())
+{
+  Q_D(ctkXnatConnection);
+  d->xnat = new qXnatAPI();
+//  d->xnat->setSuppressSslErrors(true);
+  d->rawHeaders["User-Agent"] = "Qt";
+  d->xnat->setDefaultRawHeaders(d->rawHeaders);
+
+  d->server = new ctkXnatServer();
+  createConnections();
+}
+
+ctkXnatConnection::~ctkXnatConnection()
+{
+  Q_D(ctkXnatConnection);
+  delete d->server;
+  delete d->xnat;
+}
+
+void ctkXnatConnection::createConnections()
+{
+  Q_D(ctkXnatConnection);
+//  connect(d->xnat, SIGNAL(resultReceived(QUuid,QList<QVariantMap>)),
+//           this, SLOT(processResult(QUuid,QList<QVariantMap>)));
+//  connect(d->xnat, SIGNAL(progress(QUuid,double)),
+//           this, SLOT(progress(QUuid,double)));
+}
+
+void ctkXnatConnection::progress(QUuid queryId, double progress)
+{
+  qDebug() << "ctkXnatConnection::progress(QUuid queryId, double progress)";
+  qDebug() << "query id:" << queryId;
+  qDebug() << "progress:" << (progress * 100.0) << "%";
+}
+
+QString ctkXnatConnection::url() const
+{
+  Q_D(const ctkXnatConnection);
+  return d->url;
+}
+
+void ctkXnatConnection::setUrl(const QString& url)
+{
+  Q_D(ctkXnatConnection);
+  d->url = url;
+  d->xnat->setServerUrl(d->url);
+}
+
+QString ctkXnatConnection::userName() const
+{
+  Q_D(const ctkXnatConnection);
+  return d->userName;
+}
+
+void ctkXnatConnection::setUserName(const QString& userName)
+{
+  Q_D(ctkXnatConnection);
+  d->userName = userName;
+  d->rawHeaders["Authorization"] = "Basic " +
+      QByteArray(QString("%1:%2").arg(d->userName).arg(d->password).toAscii()).toBase64();
+  d->xnat->setDefaultRawHeaders(d->rawHeaders);
+}
+
+QString ctkXnatConnection::password() const
+{
+  Q_D(const ctkXnatConnection);
+  return d->password;
+}
+
+void ctkXnatConnection::setPassword(const QString& password)
+{
+  Q_D(ctkXnatConnection);
+  d->password = password;
+  d->rawHeaders["Authorization"] = "Basic " +
+      QByteArray(QString("%1:%2").arg(d->userName).arg(d->password).toAscii()).toBase64();
+  d->xnat->setDefaultRawHeaders(d->rawHeaders);
+}
+
+ctkXnatServer* ctkXnatConnection::server()
+{
+  Q_D(ctkXnatConnection);
+  return d->server;
+}
+
+void ctkXnatConnection::fetch(ctkXnatServer* server)
+{
+  Q_D(ctkXnatConnection);
+  qDebug() << "ctkXnatConnection::fetch(ctkXnatServer* server)";
+
+  QString query("/REST/projects");
+
+  QUuid queryId = d->xnat->get(query);
+  qRestResult* restResult = d->xnat->takeResult(queryId);
+  QList<ctkXnatProject*> projects = restResult->results<ctkXnatProject>();
+
+  foreach (ctkXnatProject* project, projects)
+  {
+    server->addChild(project->id(), project);
+  }
+
+  delete restResult;
+}
+
+void ctkXnatConnection::fetch(ctkXnatProject* project)
+{
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects").arg(projectName);
+  QUuid queryId = d->xnat->get(query);
+  qRestResult* restResult = d->xnat->takeResult(queryId);
+  QList<ctkXnatSubject*> subjects = restResult->results<ctkXnatSubject>();
+
+  foreach (ctkXnatSubject* subject, subjects)
+  {
+    project->addChild(subject->id(), subject);
+  }
+
+  delete restResult;
+}
+
+void ctkXnatConnection::fetch(ctkXnatSubject* subject)
+{
+  const QString& subjectName = subject->getName();
+  const QString& projectName = subject->getParent()->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments").arg(projectName, subjectName);
+  QUuid queryId = d->xnat->get(query);
+  qRestResult* restResult = d->xnat->takeResult(queryId);
+  QList<ctkXnatExperiment*> experiments = restResult->results<ctkXnatExperiment>();
+
+  foreach (ctkXnatExperiment* experiment, experiments)
+  {
+    subject->addChild(experiment->id(), experiment);
+  }
+
+  delete restResult;
+}
+
+void ctkXnatConnection::fetch(ctkXnatExperiment* experiment)
+{
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans").arg(projectName, subjectName, experimentName);
+  QList<QVariantMap> result;
+  bool success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving scan list from XNAT.");
+  }
+
+  int scanNumber = result.size();
+
+  query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions").arg(projectName, subjectName, experimentName);
+  success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving reconstruction list from XNAT.");
+  }
+
+  int reconstructionNumber = result.size();
+
+  if (scanNumber > 0)
+  {
+    ctkXnatScanFolder* scanFolder = new ctkXnatScanFolder(experiment);
+    experiment->addChild("Scan", scanFolder);
+  }
+
+  if (reconstructionNumber > 0)
+  {
+    ctkXnatReconstructionFolder* reconstructionFolder = new ctkXnatReconstructionFolder(experiment);
+    experiment->addChild("Reconstruction", reconstructionFolder);
+  }
+}
+
+void ctkXnatConnection::fetch(ctkXnatScanFolder* scanFolder)
+{
+  ctkXnatObject* experiment = scanFolder->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans").arg(projectName, subjectName, experimentName);
+  QList<QVariantMap> result;
+  bool success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving scan list from XNAT.");
+  }
+
+  foreach (QVariantMap map, result)
+  {
+    ctkXnatScan* scan = new ctkXnatScan(scanFolder);
+    QString scanID = map["ID"].toString();
+    scanFolder->addChild(scanID, scan);
+  }
+//  QUuid queryId = d->xnat->get(query);
+//  qRestResult* restResult = d->xnat->takeResult(queryId);
+//  QList<ctkXnatScan*> scans = restResult->results<ctkXnatScan>();
+//
+//  foreach (ctkXnatScan* scan, scans)
+//  {
+//    experiment->addChild(scan->id(), scan);
+//  }
+//  delete restResult;
+}
+
+void ctkXnatConnection::fetch(ctkXnatScan* scan)
+{
+  const QString& scanName = scan->getName();
+  ctkXnatObject* experiment = scan->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans/%4/resources").arg(projectName, subjectName, experimentName, scanName);
+  QList<QVariantMap> result;
+  bool success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving scan resource list from XNAT.");
+  }
+
+  foreach (QVariantMap map, result)
+  {
+    QString scanResourceLabel = map["label"].toString();
+    ctkXnatScanResource* scanResource = new ctkXnatScanResource(scan);
+    scan->addChild(scanResourceLabel, scanResource);
+  }
+}
+
+void ctkXnatConnection::fetch(ctkXnatScanResource* scanResource)
+{
+  const QString& resourceName = scanResource->getName();
+  ctkXnatObject* scan = scanResource->getParent();
+  const QString& scanName = scan->getName();
+  ctkXnatObject* experiment = scan->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans/%4/resources/%5/files").arg(projectName, subjectName, experimentName, scanName, resourceName);
+  QList<QVariantMap> result;
+  bool success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving scan resource file list from XNAT.");
+  }
+
+  foreach (QVariantMap map, result)
+  {
+    QString scanResourceFileName = map["Name"].toString();
+    ctkXnatScanResourceFile* scanResourceFile = new ctkXnatScanResourceFile(scanResource);
+    scanResource->addChild(scanResourceFileName, scanResourceFile);
+  }
+}
+
+void ctkXnatConnection::fetch(ctkXnatReconstructionFolder* reconstructionFolder)
+{
+  ctkXnatObject* experiment = reconstructionFolder->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions").arg(projectName, subjectName, experimentName);
+  QList<QVariantMap> result;
+  bool success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving reconstruction list from XNAT.");
+  }
+
+  foreach (QVariantMap map, result)
+  {
+    QString reconstructionID = map["ID"].toString();
+    ctkXnatReconstruction* reconstruction = new ctkXnatReconstruction(reconstructionFolder);
+    reconstructionFolder->addChild(reconstructionID, reconstruction);
+  }
+}
+
+void ctkXnatConnection::fetch(ctkXnatReconstruction* reconstruction)
+{
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions/%4/ALL/resources").arg(projectName, subjectName, experimentName, reconstructionName);
+  QList<QVariantMap> result;
+  bool success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving reconstruction resource list from XNAT.");
+  }
+
+  foreach (QVariantMap map, result)
+  {
+    QString reconstructionResourceLabel = map["label"].toString();
+    ctkXnatReconstructionResource* reconstructionResource = new ctkXnatReconstructionResource(reconstruction);
+    reconstruction->addChild(reconstructionResourceLabel, reconstructionResource);
+  }
+}
+
+void ctkXnatConnection::fetch(ctkXnatReconstructionResource* reconstructionResource)
+{
+  const QString& resourceName = reconstructionResource->getName();
+  ctkXnatObject* reconstruction = reconstructionResource->getParent();
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions/%4/ALL/resources/%5/files").arg(projectName, subjectName, experimentName, reconstructionName, resourceName);
+  QList<QVariantMap> result;
+  bool success = d->xnat->sync(d->xnat->get(query), result);
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while retrieving reconstruction resource file list from XNAT.");
+  }
+
+  foreach (QVariantMap map, result)
+  {
+    QString reconstructionResourceFileName = map["Name"].toString();
+    ctkXnatReconstructionResourceFile* reconstructionResourceFile = new ctkXnatReconstructionResourceFile(reconstructionResource);
+    reconstructionResource->addChild(reconstructionResourceFileName, reconstructionResourceFile);
+  }
+}
+
+void ctkXnatConnection::create(ctkXnatProject* project)
+{
+  const QString& projectName = project->name();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1").arg(projectName);
+  bool success = d->xnat->sync(d->xnat->put(query));
+
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while creating the project.");
+  }
+}
+
+void ctkXnatConnection::remove(ctkXnatProject* project)
+{
+  const QString& projectName = project->name();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1").arg(projectName);
+  bool success = d->xnat->sync(d->xnat->del(query));
+
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while removing the project.");
+  }
+}
+
+void ctkXnatConnection::create(ctkXnatSubject* subject)
+{
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2").arg(projectName, subjectName);
+  bool success = d->xnat->sync(d->xnat->put(query));
+
+  if (!success)
+  {
+    throw ctkXnatException("Error occurred while creating the subject.");
+  }
+}
+
+void ctkXnatConnection::downloadScanFiles(ctkXnatExperiment* experiment, const QString& fileName)
+{
+  qDebug() << "ctkXnatConnection::downloadScanFiles(ctkXnatExperiment* experiment, const QString& zipFilename)";
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans/ALL/files").arg(projectName, subjectName, experimentName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::downloadReconstructionFiles(ctkXnatExperiment* experiment, const QString& fileName)
+{
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions/ALL/files").arg(projectName, subjectName, experimentName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::addReconstruction(ctkXnatExperiment* experiment, const QString& reconstruction)
+{
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+//  XnatRestStatus status = putXnatRestReconstruction(projectName.toStdString().c_str(), subjectName.toStdString().c_str(), experimentName.toStdString().c_str(), reconstruction.toStdString().c_str());
+//  if ( status != XNATREST_OK )
+//    {
+//    throw XnatException(status);
+//  }
+}
+
+void ctkXnatConnection::downloadReconstruction(ctkXnatReconstruction* reconstruction, const QString& fileName)
+{
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions/%4/ALL/files").arg(projectName, subjectName, experimentName, reconstructionName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::addReconstructionResource(ctkXnatReconstruction* reconstruction, const QString& resourceName)
+{
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+//  XnatRestStatus status = putXnatRestReconResource(projectName.toStdString().c_str(), subjectName.toStdString().c_str(), experimentName.toStdString().c_str(),
+//                                                   reconstructionName.toStdString().c_str(), resourceName.toStdString().c_str());
+//  if ( status != XNATREST_OK )
+//  {
+//    throw XnatException(status);
+//  }
+}
+
+void ctkXnatConnection::removeReconstruction(ctkXnatReconstruction* reconstruction)
+{
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+//  XnatRestStatus status = deleteXnatRestReconstruction(projectName.toStdString().c_str(), subjectName.toStdString().c_str(), experimentName.toStdString().c_str(), reconstructionName.toStdString().c_str());
+//  if ( status != XNATREST_OK )
+//  {
+//    throw XnatException(status);
+//  }
+}
+
+void ctkXnatConnection::downloadReconstructionResourceFiles(ctkXnatReconstructionResource* reconstructionResource, const QString& fileName)
+{
+  const QString& reconstructionResourceName = reconstructionResource->getName();
+  ctkXnatObject* reconstruction = reconstructionResource->getParent();
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions/%4/ALL/resources/%5/files").arg(projectName, subjectName, experimentName, reconstructionName, reconstructionResourceName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::uploadReconstructionResourceFiles(ctkXnatReconstructionResource* reconstructionResource, const QString& zipFilename)
+{
+  const QString& resourceName = reconstructionResource->getName();
+  ctkXnatObject* reconstruction = reconstructionResource->getParent();
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+//  XnatRestStatus status = putXnatRestAsynReconRsrcFiles(projectName.toStdString().c_str(), subjectName.toStdString().c_str(), experimentName.toStdString().c_str(), reconstructionName.toStdString().c_str(),
+//                                                        resourceName.toStdString().c_str(), zipFilename.toStdString().c_str());
+//  if ( status != XNATREST_OK )
+//  {
+//    throw ctkXnatException(status);
+//  }
+}
+
+void ctkXnatConnection::removeReconstructionResource(ctkXnatReconstructionResource* reconstructionResource)
+{
+  const QString& resourceName = reconstructionResource->getName();
+  ctkXnatObject* reconstruction = reconstructionResource->getParent();
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+//  XnatRestStatus status = deleteXnatRestReconResource(projectName.toStdString().c_str(), subjectName.toStdString().c_str(), experimentName.toStdString().c_str(),
+//                                                      reconstructionName.toStdString().c_str(), resourceName.toStdString().c_str());
+//  if ( status != XNATREST_OK )
+//  {
+//    throw ctkXnatException(status);
+//  }
+}
+
+void ctkXnatConnection::download(ctkXnatReconstructionResourceFile* reconstructionResourceFile, const QString& fileName)
+{
+  qDebug() <<  "ctkXnatConnection::download(ctkXnatReconstructionResourceFile* reconstructionResourceFile, const QString& zipFilename)";
+  const QString& reconstructionResourceFileName = reconstructionResourceFile->getName();
+  ctkXnatObject* reconstructionResource = reconstructionResourceFile->getParent();
+  const QString& reconstructionResourceName = reconstructionResource->getName();
+  ctkXnatObject* reconstruction = reconstructionResource->getParent();
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/reconstructions/%4/resources/%5/files/%6").arg(projectName, subjectName, experimentName, reconstructionName, reconstructionResourceName, reconstructionResourceFileName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::remove(ctkXnatReconstructionResourceFile* reconstructionResourceFile)
+{
+  const QString& filename = reconstructionResourceFile->getName();
+  ctkXnatObject* reconstructionResource = reconstructionResourceFile->getParent();
+  const QString& resourceName = reconstructionResource->getName();
+  ctkXnatObject* reconstruction = reconstructionResource->getParent();
+  const QString& reconstructionName = reconstruction->getName();
+  ctkXnatObject* experiment = reconstruction->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+//  XnatRestStatus status = deleteXnatRestReconRsrcFile(projectName.toStdString().c_str(), subjectName.toStdString().c_str(), experimentName.toStdString().c_str(), reconstructionName.toStdString().c_str(),
+//                                                      resourceName.toStdString().c_str(), filename.toStdString().c_str());
+//  if ( status != XNATREST_OK )
+//  {
+//    throw ctkXnatException(status);
+//  }
+}
+
+void ctkXnatConnection::download(ctkXnatScan* scan, const QString& fileName)
+{
+  qDebug() << "ctkXnatConnection::download(ctkXnatScan* scan, const QString& zipFilename)";
+  const QString& scanName = scan->getName();
+  ctkXnatObject* experiment = scan->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans/%4/files").arg(projectName, subjectName, experimentName, scanName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::download(ctkXnatScanResource* scanResource, const QString& fileName)
+{
+  qDebug() << "ctkXnatConnection::download(ctkXnatScanResource* scanResource, const QString& zipFilename)";
+  const QString& scanResourceName = scanResource->getName();
+  ctkXnatObject* scan = scanResource->getParent();
+  const QString& scanName = scan->getName();
+  ctkXnatObject* experiment = scan->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans/%4/resources/%5/files").arg(projectName, subjectName, experimentName, scanName, scanResourceName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::download(ctkXnatScanResourceFile* scanResourceFile, const QString& fileName)
+{
+  qDebug() << "ctkXnatConnection::download(ctkXnatScanResourceFile* scanResourceFile)";
+  const QString& scanResourceFileName = scanResourceFile->getName();
+  ctkXnatObject* scanResource = scanResourceFile->getParent();
+  const QString& scanResourceName = scanResource->getName();
+  ctkXnatObject* scan = scanResource->getParent();
+  const QString& scanName = scan->getName();
+  ctkXnatObject* experiment = scan->getParent()->getParent();
+  const QString& experimentName = experiment->getName();
+  ctkXnatObject* subject = experiment->getParent();
+  const QString& subjectName = subject->getName();
+  ctkXnatObject* project = subject->getParent();
+  const QString& projectName = project->getName();
+
+  Q_D(ctkXnatConnection);
+
+  QString query = QString("/REST/projects/%1/subjects/%2/experiments/%3/scans/%4/resources/%5/files/%6").arg(projectName, subjectName, experimentName, scanName, scanResourceName, scanResourceFileName);
+  qRestAPI::Parameters parameters;
+  parameters["format"] = "zip";
+  QUuid queryId = d->xnat->download(fileName, query, parameters);
+  d->xnat->sync(queryId);
+}
+
+void ctkXnatConnection::processResult(QUuid queryId, QList<QVariantMap> parameters)
+{
+}

+ 123 - 0
Libs/XNAT/ctkXnatConnection.h

@@ -0,0 +1,123 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatConnection_h
+#define ctkXnatConnection_h
+
+#include "ctkXNATExport.h"
+
+#include <QScopedPointer>
+#include <QString>
+#include <QScriptValue>
+
+#include <qXnatAPI.h>
+
+class ctkXnatConnectionPrivate;
+
+class QAuthenticator;
+class QNetworkReply;
+
+class ctkXnatExperiment;
+class ctkXnatObject;
+class ctkXnatProject;
+class ctkXnatReconstruction;
+class ctkXnatReconstructionFolder;
+class ctkXnatReconstructionResource;
+class ctkXnatReconstructionResourceFile;
+class ctkXnatRoot;
+class ctkXnatScan;
+class ctkXnatScanFolder;
+class ctkXnatScanResource;
+class ctkXnatScanResourceFile;
+class ctkXnatServer;
+class ctkXnatSubject;
+
+class CTK_XNAT_EXPORT ctkXnatConnection : public QObject
+{
+
+  Q_OBJECT
+
+public:
+
+  ctkXnatConnection();
+  ~ctkXnatConnection();
+
+  void createConnections();
+
+  QString url() const;
+  void setUrl(const QString& url);
+
+  QString userName() const;
+  void setUserName(const QString& userName);
+
+  QString password() const;
+  void setPassword(const QString& password);
+
+  ctkXnatServer* server();
+
+  void fetch(ctkXnatServer* server);
+  void fetch(ctkXnatProject* project);
+  void fetch(ctkXnatSubject* subject);
+  void fetch(ctkXnatExperiment* experiment);
+  void fetch(ctkXnatScanFolder* scanFolder);
+  void fetch(ctkXnatScan* scan);
+  void fetch(ctkXnatScanResource* scanResource);
+  void fetch(ctkXnatReconstructionFolder* reconstructionFolder);
+  void fetch(ctkXnatReconstruction* reconstruction);
+  void fetch(ctkXnatReconstructionResource* reconstructionResource);
+
+  void create(ctkXnatProject* project);
+  void create(ctkXnatSubject* subject);
+
+  void remove(ctkXnatProject* project);
+
+  void downloadScanFiles(ctkXnatExperiment* experiment, const QString& zipFileName);
+  void downloadReconstructionFiles(ctkXnatExperiment* experiment, const QString& zipFileName);
+  void addReconstruction(ctkXnatExperiment* experiment, const QString& categoryEntry);
+
+  void download(ctkXnatScan* scan, const QString& zipFileName);
+  void download(ctkXnatScanResource* scanResource, const QString& zipFileName);
+  void download(ctkXnatScanResourceFile* scanResourceFile, const QString& fileName);
+
+  void downloadReconstruction(ctkXnatReconstruction* reconstruction, const QString& zipFilename);
+  void addReconstructionResource(ctkXnatReconstruction* reconstruction, const QString& resource);
+  void removeReconstruction(ctkXnatReconstruction* reconstruction);
+
+  void downloadReconstructionResourceFiles(ctkXnatReconstructionResource* reconstructionResource, const QString& zipFilename);
+  void uploadReconstructionResourceFiles(ctkXnatReconstructionResource* reconstructionResource, const QString& zipFilename);
+  void removeReconstructionResource(ctkXnatReconstructionResource* reconstructionResource);
+
+  void download(ctkXnatReconstructionResourceFile* reconstructionResourceFile, const QString& zipFileName);
+  void remove(ctkXnatReconstructionResourceFile* reconstructionResourceFile);
+
+public slots:
+  void processResult(QUuid queryId, QList<QVariantMap> parameters);
+  void progress(QUuid queryId, double progress);
+
+protected:
+  QScopedPointer<ctkXnatConnectionPrivate> d_ptr;
+
+private:
+  Q_DECLARE_PRIVATE(ctkXnatConnection);
+  Q_DISABLE_COPY(ctkXnatConnection);
+};
+
+#endif

+ 88 - 0
Libs/XNAT/ctkXnatConnectionFactory.cpp

@@ -0,0 +1,88 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatConnectionFactory.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatException.h"
+#include "ctkXnatObject.h"
+#include "ctkXnatServer.h"
+
+// ctkXnatConnectionFactory class
+
+ctkXnatConnectionFactory::ctkXnatConnectionFactory()
+{
+}
+
+ctkXnatConnectionFactory::~ctkXnatConnectionFactory()
+{
+}
+
+ctkXnatConnectionFactory& ctkXnatConnectionFactory::instance()
+{
+  static ctkXnatConnectionFactory connectionFactory;
+  return connectionFactory;
+}
+
+ctkXnatConnection* ctkXnatConnectionFactory::makeConnection(const QString& url, const QString& user, const QString& password)
+{
+  // create XNAT connection
+  ctkXnatConnection* connection = new ctkXnatConnection;
+
+  // test XNAT connection
+  try
+  {
+    testConnection(connection);
+  }
+  catch (ctkXnatException& e)
+  {
+    delete connection;
+    throw;
+  }
+
+  connection->setUrl(url);
+  connection->setUserName(user);
+  connection->setPassword(password);
+
+  // return XNAT connection
+  return connection;
+}
+
+void ctkXnatConnectionFactory::testConnection(ctkXnatConnection* connection)
+{
+  // test connection by retrieving project names from XNAT
+  ctkXnatServer* server = NULL;
+  try
+  {
+    // create XNAT root
+    server = connection->server();
+
+    // TODO E.g. get version
+  }
+  catch (ctkXnatException& e)
+  {
+    if (server != NULL)
+    {
+      delete server;
+    }
+    throw;
+  }
+}

+ 47 - 0
Libs/XNAT/ctkXnatConnectionFactory.h

@@ -0,0 +1,47 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatConnectionFactory_h
+#define ctkXnatConnectionFactory_h
+
+#include "ctkXNATExport.h"
+
+#include <QString>
+
+class ctkXnatConnection;
+
+class CTK_XNAT_EXPORT ctkXnatConnectionFactory
+{
+public:
+  static ctkXnatConnectionFactory& instance();
+  ~ctkXnatConnectionFactory();
+
+  ctkXnatConnection* makeConnection(const QString& url, const QString& user, const QString& password);
+
+private:
+  ctkXnatConnectionFactory();
+  ctkXnatConnectionFactory& operator=(ctkXnatConnectionFactory& f);
+  ctkXnatConnectionFactory(const ctkXnatConnectionFactory& f);
+
+  void testConnection(ctkXnatConnection* conn);
+};
+
+#endif

+ 32 - 0
Libs/XNAT/ctkXnatException.cpp

@@ -0,0 +1,32 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatException.h"
+
+ctkXnatException::ctkXnatException(const std::string& message)
+: message(message.c_str())
+{
+}
+
+const char* ctkXnatException::what() const throw()
+{
+  return message;
+}

+ 41 - 0
Libs/XNAT/ctkXnatException.h

@@ -0,0 +1,41 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatException_h
+#define ctkXnatException_h
+
+#include "ctkXNATExport.h"
+
+#include <exception>
+#include <string>
+
+class CTK_XNAT_EXPORT ctkXnatException : public std::exception
+{
+public:
+  ctkXnatException(const std::string& message);
+
+  virtual const char* what() const throw();
+
+private:
+  const char* message;
+};
+
+#endif

+ 179 - 0
Libs/XNAT/ctkXnatExperiment.cpp

@@ -0,0 +1,179 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatExperiment.h"
+
+#include "ctkXnatConnection.h"
+
+class ctkXnatExperimentPrivate
+{
+public:
+  QString id;
+  QString project;
+  QString date;
+  QString xsiType;
+  QString label;
+  QString insertDate;
+  QString uri;
+};
+
+ctkXnatExperiment::ctkXnatExperiment(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+, d_ptr(new ctkXnatExperimentPrivate())
+{
+}
+
+ctkXnatExperiment::~ctkXnatExperiment()
+{
+}
+
+const QString& ctkXnatExperiment::id() const
+{
+  Q_D(const ctkXnatExperiment);
+  return d->id;
+}
+
+void ctkXnatExperiment::setId(const QString& id)
+{
+  Q_D(ctkXnatExperiment);
+  d->id = id;
+}
+
+const QString& ctkXnatExperiment::project() const
+{
+  Q_D(const ctkXnatExperiment);
+  return d->project;
+}
+
+void ctkXnatExperiment::setProject(const QString& project)
+{
+  Q_D(ctkXnatExperiment);
+  d->project = project;
+}
+
+const QString& ctkXnatExperiment::date() const
+{
+  Q_D(const ctkXnatExperiment);
+  return d->date;
+}
+
+void ctkXnatExperiment::setDate(const QString& date)
+{
+  Q_D(ctkXnatExperiment);
+  d->date = date;
+}
+
+const QString& ctkXnatExperiment::xsiType() const
+{
+  Q_D(const ctkXnatExperiment);
+  return d->xsiType;
+}
+
+void ctkXnatExperiment::setXsiType(const QString& xsiType)
+{
+  Q_D(ctkXnatExperiment);
+  d->xsiType = xsiType;
+}
+
+const QString& ctkXnatExperiment::label() const
+{
+  Q_D(const ctkXnatExperiment);
+  return d->label;
+}
+
+void ctkXnatExperiment::setLabel(const QString& label)
+{
+  Q_D(ctkXnatExperiment);
+  d->label = label;
+}
+
+const QString& ctkXnatExperiment::insertDate() const
+{
+  Q_D(const ctkXnatExperiment);
+  return d->insertDate;
+}
+
+void ctkXnatExperiment::setInsertDate(const QString& insertDate)
+{
+  Q_D(ctkXnatExperiment);
+  d->insertDate = insertDate;
+}
+
+const QString& ctkXnatExperiment::uri() const
+{
+  Q_D(const ctkXnatExperiment);
+  return d->uri;
+}
+
+void ctkXnatExperiment::setUri(const QString& uri)
+{
+  Q_D(ctkXnatExperiment);
+  d->uri = uri;
+}
+
+bool ctkXnatExperiment::holdsFiles() const
+{
+  return true;
+}
+
+void ctkXnatExperiment::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+bool ctkXnatExperiment::isModifiable(int parentIndex) const
+{
+  ctkXnatObject* child = getChildren()[parentIndex];
+  if (child == 0)
+  {
+    return false;
+  }
+  return child->isModifiable();
+}
+
+void ctkXnatExperiment::add(ctkXnatConnection* connection, const QString& reconstruction)
+{
+  connection->addReconstruction(this, reconstruction);
+}
+
+QString ctkXnatExperiment::getModifiableChildKind() const
+{
+  return "reconstruction";
+}
+
+QString ctkXnatExperiment::getModifiableParentName() const
+{
+  return getName();
+}
+
+bool ctkXnatExperiment::isModifiable() const
+{
+  int childNumber = getChildren().size();
+  for (int i = 0; i < childNumber; i++)
+  {
+    if (childName(i) == QString("Reconstruction"))
+    {
+      return false;
+    }
+  }
+
+  return true;
+}

+ 89 - 0
Libs/XNAT/ctkXnatExperiment.h

@@ -0,0 +1,89 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatExperiment_h
+#define ctkXnatExperiment_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+
+class ctkXnatExperimentPrivate;
+
+class CTK_XNAT_EXPORT ctkXnatExperiment : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString ID READ id WRITE setId)
+  // FIXME encode colons and slashes to valid characters for C++ identifiers
+//  Q_PROPERTY(QString xnat:subjectassessordata/id READ id WRITE setId)
+  Q_PROPERTY(QString project READ project WRITE setProject)
+  Q_PROPERTY(QString date READ date WRITE setDate)
+  Q_PROPERTY(QString xsiType READ xsiType WRITE setXsiType)
+  Q_PROPERTY(QString label READ label WRITE setLabel)
+  Q_PROPERTY(QString insert_date READ insertDate WRITE setInsertDate)
+  Q_PROPERTY(QString URI READ uri WRITE setUri)
+
+public:
+  explicit ctkXnatExperiment(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatExperiment();
+
+  const QString& id() const;
+  void setId(const QString& id);
+
+  const QString& project() const;
+  void setProject(const QString& project);
+
+  const QString& date() const;
+  void setDate(const QString& date);
+
+  const QString& xsiType() const;
+  void setXsiType(const QString& xsiType);
+
+  const QString& label() const;
+  void setLabel(const QString& label);
+
+  const QString& insertDate() const;
+  void setInsertDate(const QString& insertDate);
+
+  const QString& uri() const;
+  void setUri(const QString& uri);
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  void add(ctkXnatConnection* connection, const QString& reconstruction);
+  QString getModifiableChildKind() const;
+  QString getModifiableParentName() const;
+  bool isModifiable() const;
+
+  virtual bool holdsFiles() const;
+  virtual bool isModifiable(int parentIndex) const;
+
+private:
+  QScopedPointer<ctkXnatExperimentPrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatExperiment);
+  Q_DISABLE_COPY(ctkXnatExperiment);
+};
+
+#endif

+ 187 - 0
Libs/XNAT/ctkXnatObject.cpp

@@ -0,0 +1,187 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatObject.h"
+
+#include <QDebug>
+
+class ctkXnatObjectPrivate
+{
+public:
+  ctkXnatObject* parent;
+  int parentIndex;
+  QList<QString> childrenNames;
+  QList<ctkXnatObject*> children;
+};
+
+ctkXnatObject::ctkXnatObject(ctkXnatObject* parent)
+: QObject(parent)
+, d_ptr(new ctkXnatObjectPrivate())
+{
+  Q_D(ctkXnatObject);
+  d->parent = parent;
+  d->parentIndex = -1;
+}
+
+ctkXnatObject::~ctkXnatObject()
+{
+}
+
+void ctkXnatObject::setParent(ctkXnatObject* parent)
+{
+  Q_D(ctkXnatObject);
+  QObject::setParent(parent);
+  d->parent = parent;
+}
+
+int ctkXnatObject::parentIndex()
+{
+  Q_D(ctkXnatObject);
+  return d->parentIndex;
+}
+
+void ctkXnatObject::setParentIndex(int parentIndex)
+{
+  Q_D(ctkXnatObject);
+  d->parentIndex = parentIndex;
+}
+
+void ctkXnatObject::fetch(ctkXnatConnection* connection)
+{
+//  connection->fetch(this);
+}
+
+QString ctkXnatObject::getName() const
+{
+  Q_D(const ctkXnatObject);
+  return d->parent ? d->parent->childName(d->parentIndex) : 0;
+}
+
+ctkXnatObject* ctkXnatObject::getParent() const
+{
+  Q_D(const ctkXnatObject);
+  return d->parent;
+}
+
+const QList<ctkXnatObject*>& ctkXnatObject::getChildren() const
+{
+  Q_D(const ctkXnatObject);
+  return d->children;
+}
+
+QString ctkXnatObject::childName(int childIndex) const
+{
+  Q_D(const ctkXnatObject);
+  return d->childrenNames[childIndex];
+}
+
+void ctkXnatObject::addChild(const QString& name, ctkXnatObject* child)
+{
+  Q_D(ctkXnatObject);
+  int index = d->childrenNames.indexOf(name);
+  if (index == -1)
+  {
+    index = d->childrenNames.size();
+    d->childrenNames.push_back(name);
+    d->children.push_back(child);
+  }
+  else
+  {
+    d->children[index] = child;
+  }
+  child->setParent(this);
+  child->setParentIndex(index);
+}
+
+void ctkXnatObject::removeChild(int childIndex)
+{
+  Q_D(ctkXnatObject);
+  if (d->children[childIndex])
+  {
+    delete d->children[childIndex];
+    d->children[childIndex] = NULL;
+  }
+}
+
+void ctkXnatObject::download(ctkXnatConnection* connection, const QString& zipFilename)
+{
+  // do nothing
+}
+
+void ctkXnatObject::upload(ctkXnatConnection* connection, const QString& zipFilename)
+{
+  // do nothing
+}
+
+void ctkXnatObject::add(ctkXnatConnection* connection, const QString& name)
+{
+  // do nothing
+}
+
+void ctkXnatObject::remove(ctkXnatConnection* connection)
+{
+  // do nothing
+}
+
+QString ctkXnatObject::getKind() const
+{
+  return NULL;
+}
+
+QString ctkXnatObject::getModifiableChildKind() const
+{
+  return NULL;
+}
+
+QString ctkXnatObject::getModifiableParentName() const
+{
+  return NULL;
+}
+
+bool ctkXnatObject::isFile() const
+{
+  return false;
+}
+
+bool ctkXnatObject::holdsFiles() const
+{
+  return false;
+}
+
+bool ctkXnatObject::receivesFiles() const
+{
+  return false;
+}
+
+bool ctkXnatObject::isModifiable(int childIndex) const
+{
+  return false;
+}
+
+bool ctkXnatObject::isModifiable() const
+{
+  return false;
+}
+
+bool ctkXnatObject::isDeletable() const
+{
+  return false;
+}

+ 80 - 0
Libs/XNAT/ctkXnatObject.h

@@ -0,0 +1,80 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatObject_h
+#define ctkXnatObject_h
+
+#include "ctkXNATExport.h"
+
+#include <QList>
+#include <QObject>
+#include <QString>
+
+class ctkXnatConnection;
+class ctkXnatObjectPrivate;
+
+class CTK_XNAT_EXPORT ctkXnatObject : public QObject
+{
+  Q_OBJECT
+
+public:
+  explicit ctkXnatObject(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatObject();
+
+  QString getName() const;
+  ctkXnatObject* getParent() const;
+  int parentIndex();
+  const QList<ctkXnatObject*>& getChildren() const;
+  QString childName(int childIndex) const;
+
+  void addChild(const QString& name, ctkXnatObject* child);
+
+  virtual void fetch(ctkXnatConnection* connection);
+  void removeChild(int parentIndex);
+
+  virtual void download(ctkXnatConnection* connection, const QString& zipFilename);
+  virtual void upload(ctkXnatConnection* connection, const QString& zipFilename);
+  virtual void add(ctkXnatConnection* connection, const QString& name);
+  virtual void remove(ctkXnatConnection* connection);
+
+  virtual QString getKind() const;
+  virtual QString getModifiableChildKind() const;
+  virtual QString getModifiableParentName() const;
+
+  virtual bool isFile() const;
+  virtual bool holdsFiles() const;
+  virtual bool receivesFiles() const;
+  virtual bool isModifiable(int childIndex) const;
+  virtual bool isDeletable() const;
+
+  virtual bool isModifiable() const;
+
+private:
+  void setParent(ctkXnatObject* parent);
+  void setParentIndex(int index);
+
+  QScopedPointer<ctkXnatObjectPrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatObject);
+  Q_DISABLE_COPY(ctkXnatObject);
+};
+
+#endif

+ 155 - 0
Libs/XNAT/ctkXnatProject.cpp

@@ -0,0 +1,155 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatProject.h"
+
+#include "ctkXnatConnection.h"
+
+class ctkXnatProjectPrivate
+{
+public:
+  QString id;
+  QString secondaryId;
+  QString name;
+  QString description;
+  QString piFirstName;
+  QString piLastName;
+  QString uri;
+};
+
+ctkXnatProject::ctkXnatProject(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+, d_ptr(new ctkXnatProjectPrivate())
+{
+}
+
+ctkXnatProject::~ctkXnatProject()
+{
+}
+
+const QString& ctkXnatProject::id() const
+{
+  Q_D(const ctkXnatProject);
+  return d->id;
+}
+
+void ctkXnatProject::setId(const QString& id)
+{
+  Q_D(ctkXnatProject);
+  d->id = id;
+}
+
+const QString& ctkXnatProject::secondaryId() const
+{
+  Q_D(const ctkXnatProject);
+  return d->secondaryId;
+}
+
+void ctkXnatProject::setSecondaryId(const QString& secondaryId)
+{
+  Q_D(ctkXnatProject);
+  d->secondaryId = secondaryId;
+}
+
+const QString& ctkXnatProject::name() const
+{
+  Q_D(const ctkXnatProject);
+  return d->name;
+}
+
+void ctkXnatProject::setName(const QString& name)
+{
+  Q_D(ctkXnatProject);
+  d->name = name;
+}
+
+const QString& ctkXnatProject::description() const
+{
+  Q_D(const ctkXnatProject);
+  return d->description;
+}
+
+void ctkXnatProject::setDescription(const QString& description)
+{
+  Q_D(ctkXnatProject);
+  d->description = description;
+}
+
+const QString& ctkXnatProject::piFirstName() const
+{
+  Q_D(const ctkXnatProject);
+  return d->piFirstName;
+}
+
+void ctkXnatProject::setPiFirstName(const QString& piFirstName)
+{
+  Q_D(ctkXnatProject);
+  d->piFirstName = piFirstName;
+}
+
+const QString& ctkXnatProject::piLastName() const
+{
+  Q_D(const ctkXnatProject);
+  return d->piLastName;
+}
+
+void ctkXnatProject::setPiLastName(const QString& piLastName)
+{
+  Q_D(ctkXnatProject);
+  d->piLastName = piLastName;
+}
+
+const QString& ctkXnatProject::uri() const
+{
+  Q_D(const ctkXnatProject);
+  return d->uri;
+}
+
+void ctkXnatProject::setUri(const QString& uri)
+{
+  Q_D(ctkXnatProject);
+  d->uri = uri;
+}
+
+void ctkXnatProject::fetch(ctkXnatConnection* connection)
+{
+  return connection->fetch(this);
+}
+
+void ctkXnatProject::remove(ctkXnatConnection* connection)
+{
+  connection->remove(this);
+}
+
+QString ctkXnatProject::getKind() const
+{
+  return "subject";
+}
+
+bool ctkXnatProject::isModifiable(int parentIndex) const
+{
+  return true;
+}
+
+QString ctkXnatProject::getModifiableChildKind(int parentIndex) const
+{
+  return "project";
+}

+ 83 - 0
Libs/XNAT/ctkXnatProject.h

@@ -0,0 +1,83 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkctkXnatProject_h
+#define ctkctkXnatProject_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+class ctkXnatProjectPrivate;
+
+class CTK_XNAT_EXPORT ctkXnatProject : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString ID READ id WRITE setId)
+  Q_PROPERTY(QString secondary_ID READ secondaryId WRITE setSecondaryId)
+  Q_PROPERTY(QString name READ name WRITE setName)
+  Q_PROPERTY(QString description READ description WRITE setDescription)
+  Q_PROPERTY(QString pi_firstname READ piFirstName WRITE setPiFirstName)
+  Q_PROPERTY(QString pi_lastname READ piLastName WRITE setPiLastName)
+  Q_PROPERTY(QString URI READ uri WRITE setUri)
+
+public:
+  explicit ctkXnatProject(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatProject();
+
+  const QString& id() const;
+  void setId(const QString& id);
+
+  const QString& secondaryId() const;
+  void setSecondaryId(const QString& secondaryId);
+
+  const QString& name() const;
+  void setName(const QString& name);
+
+  const QString& description() const;
+  void setDescription(const QString& description);
+
+  const QString& piFirstName() const;
+  void setPiFirstName(const QString& piFirstName);
+
+  const QString& piLastName() const;
+  void setPiLastName(const QString& piLastName);
+
+  const QString& uri() const;
+  void setUri(const QString& uri);
+
+  virtual void fetch(ctkXnatConnection* connection);
+  virtual void remove(ctkXnatConnection* connection);
+
+  virtual QString getKind() const;
+  virtual bool isModifiable(int parentIndex) const;
+  virtual QString getModifiableChildKind(int parentIndex) const;
+
+private:
+  QScopedPointer<ctkXnatProjectPrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatProject);
+  Q_DISABLE_COPY(ctkXnatProject);
+};
+
+#endif

+ 148 - 0
Libs/XNAT/ctkXnatReconstruction.cpp

@@ -0,0 +1,148 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatReconstruction.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatReconstructionResource.h"
+
+class ctkXnatReconstructionPrivate
+{
+public:
+  QString reconstructedImageId;
+  QString id;
+  QString type;
+  QString quality;
+  QString baseScanType;
+  QString note;
+  QString seriesDescription;
+  QString uri;
+};
+
+ctkXnatReconstruction::ctkXnatReconstruction(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+, d_ptr(new ctkXnatReconstructionPrivate())
+{
+}
+
+ctkXnatReconstruction::~ctkXnatReconstruction()
+{
+}
+
+const QString& ctkXnatReconstruction::reconstructedImageId() const
+{
+  Q_D(const ctkXnatReconstruction);
+  return d->reconstructedImageId;
+}
+
+void ctkXnatReconstruction::setReconstructedImageId(const QString& reconstructeImageId)
+{
+  Q_D(ctkXnatReconstruction);
+  d->reconstructedImageId = reconstructeImageId;
+}
+
+const QString& ctkXnatReconstruction::id() const
+{
+  Q_D(const ctkXnatReconstruction);
+  return d->id;
+}
+
+void ctkXnatReconstruction::setId(const QString& id)
+{
+  Q_D(ctkXnatReconstruction);
+  d->id = id;
+}
+
+const QString& ctkXnatReconstruction::type() const
+{
+  Q_D(const ctkXnatReconstruction);
+  return d->type;
+}
+
+void ctkXnatReconstruction::setType(const QString& type)
+{
+  Q_D(ctkXnatReconstruction);
+  d->type = type;
+}
+
+const QString& ctkXnatReconstruction::baseScanType() const
+{
+  Q_D(const ctkXnatReconstruction);
+  return d->baseScanType;
+}
+
+void ctkXnatReconstruction::setBaseScanType(const QString& baseScanType)
+{
+  Q_D(ctkXnatReconstruction);
+  d->baseScanType = baseScanType;
+}
+
+const QString& ctkXnatReconstruction::uri() const
+{
+  Q_D(const ctkXnatReconstruction);
+  return d->uri;
+}
+
+void ctkXnatReconstruction::setUri(const QString& uri)
+{
+  Q_D(ctkXnatReconstruction);
+  d->uri = uri;
+}
+
+void ctkXnatReconstruction::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+void ctkXnatReconstruction::download(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->downloadReconstruction(this, zipFileName);
+}
+
+void ctkXnatReconstruction::add(ctkXnatConnection* connection, const QString& resource)
+{
+  connection->addReconstructionResource(this, resource);
+}
+
+void ctkXnatReconstruction::remove(ctkXnatConnection* connection)
+{
+  connection->removeReconstruction(this);
+}
+
+QString ctkXnatReconstruction::getKind() const
+{
+  return "resource";
+}
+
+bool ctkXnatReconstruction::holdsFiles() const
+{
+  return true;
+}
+
+bool ctkXnatReconstruction::receivesFiles() const
+{
+  return true;
+}
+
+bool ctkXnatReconstruction::isDeletable() const
+{
+  return true;
+}

+ 79 - 0
Libs/XNAT/ctkXnatReconstruction.h

@@ -0,0 +1,79 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatReconstruction_h
+#define ctkXnatReconstruction_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+class ctkXnatReconstructionPrivate;
+
+class CTK_XNAT_EXPORT ctkXnatReconstruction : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString xnat_reconstructedimagedata_id READ reconstructedImageId WRITE setReconstructedImageId)
+  Q_PROPERTY(QString ID READ id WRITE setId)
+  Q_PROPERTY(QString type READ type WRITE setType)
+  Q_PROPERTY(QString baseScanType READ baseScanType WRITE setBaseScanType)
+  Q_PROPERTY(QString URI READ uri WRITE setUri)
+
+public:
+  explicit ctkXnatReconstruction(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatReconstruction();
+
+  const QString& reconstructedImageId() const;
+  void setReconstructedImageId(const QString& reconstructedImageId);
+
+  const QString& id() const;
+  void setId(const QString& id);
+
+  const QString& type() const;
+  void setType(const QString& type);
+
+  const QString& baseScanType() const;
+  void setBaseScanType(const QString& baseScanType);
+
+  const QString& uri() const;
+  void setUri(const QString& uri);
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  virtual void download(ctkXnatConnection* connection, const QString& zipFilename);
+  virtual void add(ctkXnatConnection* connection, const QString& name);
+  virtual void remove(ctkXnatConnection* connection);
+
+  virtual QString getKind() const;
+  virtual bool holdsFiles() const;
+  virtual bool receivesFiles() const;
+  virtual bool isDeletable() const;
+
+private:
+  QScopedPointer<ctkXnatReconstructionPrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatReconstruction);
+  Q_DISABLE_COPY(ctkXnatReconstruction);
+};
+
+#endif

+ 95 - 0
Libs/XNAT/ctkXnatReconstructionFolder.cpp

@@ -0,0 +1,95 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatReconstructionFolder.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatExperiment.h"
+#include "ctkXnatReconstruction.h"
+
+ctkXnatReconstructionFolder::ctkXnatReconstructionFolder(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+{
+}
+
+ctkXnatReconstructionFolder::~ctkXnatReconstructionFolder()
+{
+}
+
+void ctkXnatReconstructionFolder::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+void ctkXnatReconstructionFolder::download(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->downloadReconstructionFiles(dynamic_cast<ctkXnatExperiment*>(getParent()), zipFileName);
+}
+
+void ctkXnatReconstructionFolder::add(ctkXnatConnection* connection, const QString& categoryEntry)
+{
+  connection->addReconstruction(dynamic_cast<ctkXnatExperiment*>(getParent()), categoryEntry);
+}
+
+QString ctkXnatReconstructionFolder::getModifiableChildKind() const
+{
+  return "reconstruction";
+}
+
+QString ctkXnatReconstructionFolder::getModifiableParentName() const
+{
+  return getParent()->getName();
+}
+
+bool ctkXnatReconstructionFolder::isModifiable() const
+{
+  return true;
+}
+
+QString ctkXnatReconstructionFolder::getKind() const
+{
+  return "reconstruction";
+}
+
+QString ctkXnatReconstructionFolder::getModifiableChildKind(int parentIndex) const
+{
+  return "resource";
+}
+
+QString ctkXnatReconstructionFolder::getModifiableParentName(int parentIndex) const
+{
+  return this->childName(parentIndex);
+}
+
+bool ctkXnatReconstructionFolder::holdsFiles() const
+{
+  return true;
+}
+
+bool ctkXnatReconstructionFolder::isModifiable(int parentIndex) const
+{
+  return true;
+}
+
+bool ctkXnatReconstructionFolder::isDeletable() const
+{
+  return true;
+}

+ 54 - 0
Libs/XNAT/ctkXnatReconstructionFolder.h

@@ -0,0 +1,54 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatReconstructionFolder_h
+#define ctkXnatReconstructionFolder_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+
+class CTK_XNAT_EXPORT ctkXnatReconstructionFolder : public ctkXnatObject
+{
+public:
+  explicit ctkXnatReconstructionFolder(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatReconstructionFolder();
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  void download(ctkXnatConnection* connection, const QString& zipFilename);
+  void add(ctkXnatConnection* connection, const QString& categoryEntry);
+  QString getModifiableChildKind() const;
+  QString getModifiableParentName() const;
+  bool isModifiable() const;
+
+  virtual QString getKind() const;
+  virtual QString getModifiableChildKind(int parentIndex) const;
+  virtual QString getModifiableParentName(int parentIndex) const;
+
+  virtual bool holdsFiles() const;
+  virtual bool isModifiable(int parentIndex) const;
+  virtual bool isDeletable() const;
+};
+
+#endif

+ 148 - 0
Libs/XNAT/ctkXnatReconstructionResource.cpp

@@ -0,0 +1,148 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatReconstructionResource.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatReconstructionResourceFile.h"
+
+class ctkXnatReconstructionResourcePrivate
+{
+public:
+  QString resourceId;
+  QString label;
+  QString elementName;
+  QString category;
+  QString categoryId;
+  QString categoryDescription;
+};
+
+ctkXnatReconstructionResource::ctkXnatReconstructionResource(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+, d_ptr(new ctkXnatReconstructionResourcePrivate())
+{
+}
+
+ctkXnatReconstructionResource::~ctkXnatReconstructionResource()
+{
+}
+
+const QString& ctkXnatReconstructionResource::resourceId() const
+{
+  Q_D(const ctkXnatReconstructionResource);
+  return d->resourceId;
+}
+
+void ctkXnatReconstructionResource::setResourceId(const QString& resourceId)
+{
+  Q_D(ctkXnatReconstructionResource);
+  d->resourceId = resourceId;
+}
+
+const QString& ctkXnatReconstructionResource::label() const
+{
+  Q_D(const ctkXnatReconstructionResource);
+  return d->label;
+}
+
+void ctkXnatReconstructionResource::setLabel(const QString& label)
+{
+  Q_D(ctkXnatReconstructionResource);
+  d->label = label;
+}
+
+const QString& ctkXnatReconstructionResource::elementName() const
+{
+  Q_D(const ctkXnatReconstructionResource);
+  return d->elementName;
+}
+
+void ctkXnatReconstructionResource::setElementName(const QString& elementName)
+{
+  Q_D(ctkXnatReconstructionResource);
+  d->elementName = elementName;
+}
+
+const QString& ctkXnatReconstructionResource::category() const
+{
+  Q_D(const ctkXnatReconstructionResource);
+  return d->category;
+}
+
+void ctkXnatReconstructionResource::setCategory(const QString& category)
+{
+  Q_D(ctkXnatReconstructionResource);
+  d->category = category;
+}
+
+const QString& ctkXnatReconstructionResource::categoryId() const
+{
+  Q_D(const ctkXnatReconstructionResource);
+  return d->categoryId;
+}
+
+void ctkXnatReconstructionResource::setCategoryId(const QString& categoryId)
+{
+  Q_D(ctkXnatReconstructionResource);
+  d->categoryId = categoryId;
+}
+
+const QString& ctkXnatReconstructionResource::categoryDescription() const
+{
+  Q_D(const ctkXnatReconstructionResource);
+  return d->categoryDescription;
+}
+
+void ctkXnatReconstructionResource::setCategoryDescription(const QString& categoryDescription)
+{
+  Q_D(ctkXnatReconstructionResource);
+  d->categoryDescription = categoryDescription;
+}
+
+void ctkXnatReconstructionResource::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+void ctkXnatReconstructionResource::download(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->downloadReconstructionResourceFiles(this, zipFileName);
+}
+
+void ctkXnatReconstructionResource::upload(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->uploadReconstructionResourceFiles(this, zipFileName);
+}
+
+void ctkXnatReconstructionResource::remove(ctkXnatConnection* connection)
+{
+  connection->removeReconstructionResource(this);
+}
+
+bool ctkXnatReconstructionResource::isFile() const
+{
+  return true;
+}
+
+bool ctkXnatReconstructionResource::isDeletable() const
+{
+  return true;
+}

+ 81 - 0
Libs/XNAT/ctkXnatReconstructionResource.h

@@ -0,0 +1,81 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatReconstructionResource_h
+#define ctkXnatReconstructionResource_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+class ctkXnatReconstructionResourcePrivate;
+
+class CTK_XNAT_EXPORT ctkXnatReconstructionResource : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString xnat_abstractresource_id READ resourceId WRITE setResourceId)
+  Q_PROPERTY(QString label READ label WRITE setLabel)
+  Q_PROPERTY(QString elementName READ elementName WRITE setElementName)
+  Q_PROPERTY(QString category READ category WRITE setCategory)
+  Q_PROPERTY(QString cat_id READ categoryId WRITE setCategoryId)
+  Q_PROPERTY(QString cat_desc READ categoryDescription WRITE setCategoryDescription)
+
+public:
+  explicit ctkXnatReconstructionResource(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatReconstructionResource();
+
+  const QString& resourceId() const;
+  void setResourceId(const QString& resourceId);
+
+  const QString& label() const;
+  void setLabel(const QString& label);
+
+  const QString& elementName() const;
+  void setElementName(const QString& elementName);
+
+  const QString& category() const;
+  void setCategory(const QString& category);
+
+  const QString& categoryId() const;
+  void setCategoryId(const QString& categoryId);
+
+  const QString& categoryDescription() const;
+  void setCategoryDescription(const QString& categoryDescription);
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  virtual void download(ctkXnatConnection* connection, const QString& zipFilename);
+  virtual void upload(ctkXnatConnection* connection, const QString& zipFilename);
+  virtual void remove(ctkXnatConnection* connection);
+
+  virtual bool isFile() const;
+  virtual bool isDeletable() const;
+
+private:
+  QScopedPointer<ctkXnatReconstructionResourcePrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatReconstructionResource);
+  Q_DISABLE_COPY(ctkXnatReconstructionResource);
+};
+
+#endif

+ 162 - 0
Libs/XNAT/ctkXnatReconstructionResourceFile.cpp

@@ -0,0 +1,162 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatReconstructionResourceFile.h"
+
+#include "ctkXnatConnection.h"
+
+class ctkXnatReconstructionResourceFilePrivate
+{
+public:
+  QString name;
+  QString size;
+  QString uri;
+  QString collection;
+  QString fileTags;
+  QString fileFormat;
+  QString fileContent;
+  QString categoryId;
+};
+
+ctkXnatReconstructionResourceFile::ctkXnatReconstructionResourceFile(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+{
+}
+
+ctkXnatReconstructionResourceFile::~ctkXnatReconstructionResourceFile()
+{
+}
+
+const QString& ctkXnatReconstructionResourceFile::name() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->name;
+}
+
+void ctkXnatReconstructionResourceFile::setName(const QString& name)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->name = name;
+}
+
+const QString& ctkXnatReconstructionResourceFile::size() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->size;
+}
+
+void ctkXnatReconstructionResourceFile::setSize(const QString& size)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->size = size;
+}
+
+const QString& ctkXnatReconstructionResourceFile::uri() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->uri;
+}
+
+void ctkXnatReconstructionResourceFile::setUri(const QString& uri)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->uri = uri;
+}
+
+const QString& ctkXnatReconstructionResourceFile::collection() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->collection;
+}
+
+void ctkXnatReconstructionResourceFile::setCollection(const QString& collection)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->collection = collection;
+}
+
+const QString& ctkXnatReconstructionResourceFile::fileTags() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->fileTags;
+}
+
+void ctkXnatReconstructionResourceFile::setFileTags(const QString& fileTags)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->fileTags = fileTags;
+}
+
+const QString& ctkXnatReconstructionResourceFile::fileFormat() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->fileFormat;
+}
+
+void ctkXnatReconstructionResourceFile::setFileFormat(const QString& fileFormat)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->fileFormat = fileFormat;
+}
+
+const QString& ctkXnatReconstructionResourceFile::fileContent() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->fileContent;
+}
+
+void ctkXnatReconstructionResourceFile::setFileContent(const QString& fileContent)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->fileContent = fileContent;
+}
+
+const QString& ctkXnatReconstructionResourceFile::categoryId() const
+{
+  Q_D(const ctkXnatReconstructionResourceFile);
+  return d->categoryId;
+}
+
+void ctkXnatReconstructionResourceFile::setCategoryId(const QString& categoryId)
+{
+  Q_D(ctkXnatReconstructionResourceFile);
+  d->categoryId = categoryId;
+}
+
+void ctkXnatReconstructionResourceFile::download(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->download(this, zipFileName);
+}
+
+void ctkXnatReconstructionResourceFile::remove(ctkXnatConnection* connection)
+{
+  connection->remove(this);
+}
+
+bool ctkXnatReconstructionResourceFile::isFile() const
+{
+  return true;
+}
+
+bool ctkXnatReconstructionResourceFile::isDeletable() const
+{
+  return true;
+}

+ 86 - 0
Libs/XNAT/ctkXnatReconstructionResourceFile.h

@@ -0,0 +1,86 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatReconstructionResourceFile_h
+#define ctkXnatReconstructionResourceFile_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+class ctkXnatReconstructionResourceFilePrivate;
+
+class CTK_XNAT_EXPORT ctkXnatReconstructionResourceFile : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString Name READ name WRITE setName)
+  Q_PROPERTY(QString Size READ size WRITE setSize)
+  Q_PROPERTY(QString URI READ uri WRITE setUri)
+  Q_PROPERTY(QString collection READ collection WRITE setCollection)
+  Q_PROPERTY(QString file_tags READ fileTags WRITE setFileTags)
+  Q_PROPERTY(QString file_format READ fileFormat WRITE setFileFormat)
+  Q_PROPERTY(QString file_content READ fileContent WRITE setFileContent)
+  Q_PROPERTY(QString cat_ID READ categoryId WRITE setCategoryId)
+
+public:
+  explicit ctkXnatReconstructionResourceFile(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatReconstructionResourceFile();
+
+  const QString& name() const;
+  void setName(const QString& name);
+
+  const QString& size() const;
+  void setSize(const QString& size);
+
+  const QString& uri() const;
+  void setUri(const QString& uri);
+
+  const QString& collection() const;
+  void setCollection(const QString& collection);
+
+  const QString& fileTags() const;
+  void setFileTags(const QString& fileTags);
+
+  const QString& fileFormat() const;
+  void setFileFormat(const QString& fileFormat);
+
+  const QString& fileContent() const;
+  void setFileContent(const QString& fileContent);
+
+  const QString& categoryId() const;
+  void setCategoryId(const QString& categoryId);
+
+  virtual void download(ctkXnatConnection* connection, const QString& zipFilename);
+  virtual void remove(ctkXnatConnection* connection);
+
+  virtual bool isFile() const;
+  virtual bool isDeletable() const;
+
+private:
+  QScopedPointer<ctkXnatReconstructionResourceFilePrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatReconstructionResourceFile);
+  Q_DISABLE_COPY(ctkXnatReconstructionResourceFile);
+};
+
+#endif

+ 164 - 0
Libs/XNAT/ctkXnatScan.cpp

@@ -0,0 +1,164 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatScan.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatScanResource.h"
+
+class ctkXnatScanPrivate
+{
+public:
+  QString imageScanId;
+  QString id;
+  QString type;
+  QString quality;
+  QString xsiType;
+  QString note;
+  QString seriesDescription;
+  QString uri;
+};
+
+ctkXnatScan::ctkXnatScan(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+, d_ptr(new ctkXnatScanPrivate())
+{
+}
+
+ctkXnatScan::~ctkXnatScan()
+{
+}
+
+const QString& ctkXnatScan::imageScanId() const
+{
+  Q_D(const ctkXnatScan);
+  return d->imageScanId;
+}
+
+void ctkXnatScan::setImageScanId(const QString& imageScanId)
+{
+  Q_D(ctkXnatScan);
+  d->imageScanId = imageScanId;
+}
+
+const QString& ctkXnatScan::id() const
+{
+  Q_D(const ctkXnatScan);
+  return d->id;
+}
+
+void ctkXnatScan::setId(const QString& id)
+{
+  Q_D(ctkXnatScan);
+  d->id = id;
+}
+
+const QString& ctkXnatScan::type() const
+{
+  Q_D(const ctkXnatScan);
+  return d->type;
+}
+
+void ctkXnatScan::setType(const QString& type)
+{
+  Q_D(ctkXnatScan);
+  d->type = type;
+}
+
+const QString& ctkXnatScan::quality() const
+{
+  Q_D(const ctkXnatScan);
+  return d->quality;
+}
+
+void ctkXnatScan::setQuality(const QString& quality)
+{
+  Q_D(ctkXnatScan);
+  d->quality = quality;
+}
+
+const QString& ctkXnatScan::xsiType() const
+{
+  Q_D(const ctkXnatScan);
+  return d->xsiType;
+}
+
+void ctkXnatScan::setXsiType(const QString& xsiType)
+{
+  Q_D(ctkXnatScan);
+  d->xsiType = xsiType;
+}
+
+const QString& ctkXnatScan::note() const
+{
+  Q_D(const ctkXnatScan);
+  return d->note;
+}
+
+void ctkXnatScan::setNote(const QString& note)
+{
+  Q_D(ctkXnatScan);
+  d->note = note;
+}
+
+const QString& ctkXnatScan::seriesDescription() const
+{
+  Q_D(const ctkXnatScan);
+  return d->seriesDescription;
+}
+
+void ctkXnatScan::setSeriesDescription(const QString& seriesDescription)
+{
+  Q_D(ctkXnatScan);
+  d->seriesDescription = seriesDescription;
+}
+
+const QString& ctkXnatScan::uri() const
+{
+  Q_D(const ctkXnatScan);
+  return d->uri;
+}
+
+void ctkXnatScan::setUri(const QString& uri)
+{
+  Q_D(ctkXnatScan);
+  d->uri = uri;
+}
+
+void ctkXnatScan::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+void ctkXnatScan::download(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->download(this, zipFileName);
+}
+
+QString ctkXnatScan::getKind() const
+{
+  return "resource";
+}
+
+bool ctkXnatScan::holdsFiles() const
+{
+  return true;
+}

+ 87 - 0
Libs/XNAT/ctkXnatScan.h

@@ -0,0 +1,87 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatScan_h
+#define ctkXnatScan_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+class ctkXnatScanPrivate;
+
+class CTK_XNAT_EXPORT ctkXnatScan : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString xnat_imagescandata_id READ imageScanId WRITE setImageScanId)
+  Q_PROPERTY(QString ID READ id WRITE setId)
+  Q_PROPERTY(QString type READ type WRITE setType)
+  Q_PROPERTY(QString quality READ quality WRITE setQuality)
+  Q_PROPERTY(QString xsiType READ xsiType WRITE setXsiType)
+  Q_PROPERTY(QString note READ note WRITE setNote)
+  Q_PROPERTY(QString series_description READ seriesDescription WRITE setSeriesDescription)
+  Q_PROPERTY(QString URI READ uri WRITE setUri)
+
+public:
+  explicit ctkXnatScan(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatScan();
+
+  const QString& imageScanId() const;
+  void setImageScanId(const QString& imageScanId);
+
+  const QString& id() const;
+  void setId(const QString& id);
+
+  const QString& type() const;
+  void setType(const QString& type);
+
+  const QString& quality() const;
+  void setQuality(const QString& quality);
+
+  const QString& xsiType() const;
+  void setXsiType(const QString& xsiType);
+
+  const QString& note() const;
+  void setNote(const QString& note);
+
+  const QString& seriesDescription() const;
+  void setSeriesDescription(const QString& seriesDescription);
+
+  const QString& uri() const;
+  void setUri(const QString& uri);
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  virtual void download(ctkXnatConnection* connection, const QString& zipFilename);
+
+  virtual QString getKind() const;
+  virtual bool holdsFiles() const;
+
+private:
+  QScopedPointer<ctkXnatScanPrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatScan);
+  Q_DISABLE_COPY(ctkXnatScan);
+};
+
+#endif

+ 55 - 0
Libs/XNAT/ctkXnatScanFolder.cpp

@@ -0,0 +1,55 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatScanFolder.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatExperiment.h"
+#include "ctkXnatScan.h"
+
+ctkXnatScanFolder::ctkXnatScanFolder(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+{
+}
+
+ctkXnatScanFolder::~ctkXnatScanFolder()
+{
+}
+
+void ctkXnatScanFolder::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+void ctkXnatScanFolder::download(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->downloadScanFiles(dynamic_cast<ctkXnatExperiment*>(getParent()), zipFileName);
+}
+
+QString ctkXnatScanFolder::getKind() const
+{
+  return "scan";
+}
+
+bool ctkXnatScanFolder::holdsFiles() const
+{
+  return true;
+}

+ 45 - 0
Libs/XNAT/ctkXnatScanFolder.h

@@ -0,0 +1,45 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatScanFolder_h
+#define ctkXnatScanFolder_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+
+class CTK_XNAT_EXPORT ctkXnatScanFolder : public ctkXnatObject
+{
+public:
+  explicit ctkXnatScanFolder(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatScanFolder();
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  void download(ctkXnatConnection* connection, const QString& zipFilename);
+
+  virtual QString getKind() const;
+  virtual bool holdsFiles() const;
+};
+
+#endif

+ 135 - 0
Libs/XNAT/ctkXnatScanResource.cpp

@@ -0,0 +1,135 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatScanResource.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatScanResourceFile.h"
+
+#include <QDebug>
+
+class ctkXnatScanResourcePrivate
+{
+public:
+  QString resourceId;
+  QString label;
+  QString elementName;
+  QString category;
+  QString categoryId;
+  QString categoryDescription;
+};
+
+ctkXnatScanResource::ctkXnatScanResource(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+, d_ptr(new ctkXnatScanResourcePrivate())
+{
+}
+
+ctkXnatScanResource::~ctkXnatScanResource()
+{
+}
+
+const QString& ctkXnatScanResource::resourceId() const
+{
+  Q_D(const ctkXnatScanResource);
+  return d->resourceId;
+}
+
+void ctkXnatScanResource::setResourceId(const QString& resourceId)
+{
+  Q_D(ctkXnatScanResource);
+  d->resourceId = resourceId;
+}
+
+const QString& ctkXnatScanResource::label() const
+{
+  Q_D(const ctkXnatScanResource);
+  return d->label;
+}
+
+void ctkXnatScanResource::setLabel(const QString& label)
+{
+  Q_D(ctkXnatScanResource);
+  d->label = label;
+}
+
+const QString& ctkXnatScanResource::elementName() const
+{
+  Q_D(const ctkXnatScanResource);
+  return d->elementName;
+}
+
+void ctkXnatScanResource::setElementName(const QString& elementName)
+{
+  Q_D(ctkXnatScanResource);
+  d->elementName = elementName;
+}
+
+const QString& ctkXnatScanResource::category() const
+{
+  Q_D(const ctkXnatScanResource);
+  return d->category;
+}
+
+void ctkXnatScanResource::setCategory(const QString& category)
+{
+  Q_D(ctkXnatScanResource);
+  d->category = category;
+}
+
+const QString& ctkXnatScanResource::categoryId() const
+{
+  Q_D(const ctkXnatScanResource);
+  return d->categoryId;
+}
+
+void ctkXnatScanResource::setCategoryId(const QString& categoryId)
+{
+  Q_D(ctkXnatScanResource);
+  d->categoryId = categoryId;
+}
+
+const QString& ctkXnatScanResource::categoryDescription() const
+{
+  Q_D(const ctkXnatScanResource);
+  return d->categoryDescription;
+}
+
+void ctkXnatScanResource::setCategoryDescription(const QString& categoryDescription)
+{
+  Q_D(ctkXnatScanResource);
+  d->categoryDescription = categoryDescription;
+}
+
+void ctkXnatScanResource::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+void ctkXnatScanResource::download(ctkXnatConnection* connection, const QString& zipFileName)
+{
+  connection->download(this, zipFileName);
+}
+
+bool ctkXnatScanResource::isFile() const
+{
+  return true;
+}

+ 78 - 0
Libs/XNAT/ctkXnatScanResource.h

@@ -0,0 +1,78 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatScanResource_h
+#define ctkXnatScanResource_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+class ctkXnatScanResourcePrivate;
+
+class CTK_XNAT_EXPORT ctkXnatScanResource : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString xnat_abstractresource_id READ resourceId WRITE setResourceId)
+  Q_PROPERTY(QString label READ label WRITE setLabel)
+  Q_PROPERTY(QString elementName READ elementName WRITE setElementName)
+  Q_PROPERTY(QString category READ category WRITE setCategory)
+  Q_PROPERTY(QString cat_id READ categoryId WRITE setCategoryId)
+  Q_PROPERTY(QString cat_desc READ categoryDescription WRITE setCategoryDescription)
+
+public:
+  explicit ctkXnatScanResource(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatScanResource();
+
+  const QString& resourceId() const;
+  void setResourceId(const QString& resourceId);
+
+  const QString& label() const;
+  void setLabel(const QString& label);
+
+  const QString& elementName() const;
+  void setElementName(const QString& elementName);
+
+  const QString& category() const;
+  void setCategory(const QString& category);
+
+  const QString& categoryId() const;
+  void setCategoryId(const QString& categoryId);
+
+  const QString& categoryDescription() const;
+  void setCategoryDescription(const QString& categoryDescription);
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  virtual void download(ctkXnatConnection* connection, const QString& zipFilename);
+
+  virtual bool isFile() const;
+
+private:
+  QScopedPointer<ctkXnatScanResourcePrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatScanResource);
+  Q_DISABLE_COPY(ctkXnatScanResource);
+};
+
+#endif

+ 157 - 0
Libs/XNAT/ctkXnatScanResourceFile.cpp

@@ -0,0 +1,157 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatScanResourceFile.h"
+
+#include "ctkXnatConnection.h"
+
+class ctkXnatScanResourceFilePrivate
+{
+public:
+  QString name;
+  QString size;
+  QString uri;
+  QString collection;
+  QString fileTags;
+  QString fileFormat;
+  QString fileContent;
+  QString categoryId;
+};
+
+ctkXnatScanResourceFile::ctkXnatScanResourceFile(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+{
+}
+
+ctkXnatScanResourceFile::~ctkXnatScanResourceFile()
+{
+}
+
+const QString& ctkXnatScanResourceFile::name() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->name;
+}
+
+void ctkXnatScanResourceFile::setName(const QString& name)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->name = name;
+}
+
+const QString& ctkXnatScanResourceFile::size() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->size;
+}
+
+void ctkXnatScanResourceFile::setSize(const QString& size)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->size = size;
+}
+
+const QString& ctkXnatScanResourceFile::uri() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->uri;
+}
+
+void ctkXnatScanResourceFile::setUri(const QString& uri)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->uri = uri;
+}
+
+const QString& ctkXnatScanResourceFile::collection() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->collection;
+}
+
+void ctkXnatScanResourceFile::setCollection(const QString& collection)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->collection = collection;
+}
+
+const QString& ctkXnatScanResourceFile::fileTags() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->fileTags;
+}
+
+void ctkXnatScanResourceFile::setFileTags(const QString& fileTags)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->fileTags = fileTags;
+}
+
+const QString& ctkXnatScanResourceFile::fileFormat() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->fileFormat;
+}
+
+void ctkXnatScanResourceFile::setFileFormat(const QString& fileFormat)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->fileFormat = fileFormat;
+}
+
+const QString& ctkXnatScanResourceFile::fileContent() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->fileContent;
+}
+
+void ctkXnatScanResourceFile::setFileContent(const QString& fileContent)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->fileContent = fileContent;
+}
+
+const QString& ctkXnatScanResourceFile::categoryId() const
+{
+  Q_D(const ctkXnatScanResourceFile);
+  return d->categoryId;
+}
+
+void ctkXnatScanResourceFile::setCategoryId(const QString& categoryId)
+{
+  Q_D(ctkXnatScanResourceFile);
+  d->categoryId = categoryId;
+}
+
+void ctkXnatScanResourceFile::download(ctkXnatConnection* connection, const QString& fileName)
+{
+  connection->download(this, fileName);
+}
+
+bool ctkXnatScanResourceFile::isFile() const
+{
+  return true;
+}
+
+bool ctkXnatScanResourceFile::isDeletable() const
+{
+  return true;
+}

+ 85 - 0
Libs/XNAT/ctkXnatScanResourceFile.h

@@ -0,0 +1,85 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatScanResourceFile_h
+#define ctkXnatScanResourceFile_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+class ctkXnatScanResourceFilePrivate;
+
+class CTK_XNAT_EXPORT ctkXnatScanResourceFile : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString Name READ name WRITE setName)
+  Q_PROPERTY(QString Size READ size WRITE setSize)
+  Q_PROPERTY(QString URI READ uri WRITE setUri)
+  Q_PROPERTY(QString collection READ collection WRITE setCollection)
+  Q_PROPERTY(QString file_tags READ fileTags WRITE setFileTags)
+  Q_PROPERTY(QString file_format READ fileFormat WRITE setFileFormat)
+  Q_PROPERTY(QString file_content READ fileContent WRITE setFileContent)
+  Q_PROPERTY(QString cat_ID READ categoryId WRITE setCategoryId)
+
+public:
+  explicit ctkXnatScanResourceFile(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatScanResourceFile();
+
+  const QString& name() const;
+  void setName(const QString& name);
+
+  const QString& size() const;
+  void setSize(const QString& size);
+
+  const QString& uri() const;
+  void setUri(const QString& uri);
+
+  const QString& collection() const;
+  void setCollection(const QString& collection);
+
+  const QString& fileTags() const;
+  void setFileTags(const QString& fileTags);
+
+  const QString& fileFormat() const;
+  void setFileFormat(const QString& fileFormat);
+
+  const QString& fileContent() const;
+  void setFileContent(const QString& fileContent);
+
+  const QString& categoryId() const;
+  void setCategoryId(const QString& categoryId);
+
+  virtual void download(ctkXnatConnection* connection, const QString& zipFilename);
+
+  virtual bool isFile() const;
+  virtual bool isDeletable() const;
+
+private:
+  QScopedPointer<ctkXnatScanResourceFilePrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatScanResourceFile);
+  Q_DISABLE_COPY(ctkXnatScanResourceFile);
+};
+
+#endif

+ 43 - 0
Libs/XNAT/ctkXnatServer.cpp

@@ -0,0 +1,43 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatServer.h"
+
+#include "ctkXnatConnection.h"
+
+ctkXnatServer::ctkXnatServer(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+{
+}
+
+ctkXnatServer::~ctkXnatServer()
+{
+}
+
+void ctkXnatServer::fetch(ctkXnatConnection* connection)
+{
+  return connection->fetch(this);
+}
+
+QString ctkXnatServer::getKind() const
+{
+  return "project";
+}

+ 43 - 0
Libs/XNAT/ctkXnatServer.h

@@ -0,0 +1,43 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatServer_h
+#define ctkXnatServer_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+
+class CTK_XNAT_EXPORT ctkXnatServer : public ctkXnatObject
+{
+public:
+  explicit ctkXnatServer(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatServer();
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  virtual QString getKind() const;
+
+};
+
+#endif

+ 61 - 0
Libs/XNAT/ctkXnatSettings.cpp

@@ -0,0 +1,61 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatSettings.h"
+
+#include <QDir>
+#include <QFileInfo>
+#include <QUuid>
+
+ctkXnatSettings::ctkXnatSettings()
+{
+}
+
+ctkXnatSettings::~ctkXnatSettings()
+{
+}
+
+QString ctkXnatSettings::getWorkSubdirectory() const
+{
+  // set work directory name
+  QDir workDir;
+  QString workDirName = getDefaultWorkDirectory();
+  if ( !workDirName.isEmpty() )
+  {
+    workDir = QDir(workDirName);
+  }
+
+  // generate random name for subdirectory
+  QString subdir = QUuid::createUuid().toString();
+
+  // create subdirectory in work directory
+  bool subdirCreated = workDir.mkdir(subdir);
+
+  // check whether subdirectory was created
+  if ( !subdirCreated )
+  {
+    // display error message
+    return QString();
+  }
+
+  // return full path of subdirectory
+  return QFileInfo(workDir, subdir).absoluteFilePath();
+}

+ 58 - 0
Libs/XNAT/ctkXnatSettings.h

@@ -0,0 +1,58 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatSettings_h
+#define ctkXnatSettings_h
+
+#include "ctkXNATExport.h"
+
+#include <QMap>
+#include <QString>
+
+class ctkXnatLoginProfile;
+
+class CTK_XNAT_EXPORT ctkXnatSettings
+{
+public:
+  virtual QString getDefaultDirectory() const = 0;
+  virtual void setDefaultDirectory(const QString& dir) = 0;
+
+  virtual QString getDefaultWorkDirectory() const = 0;
+  virtual void setDefaultWorkDirectory(const QString& workDir) = 0;
+
+  virtual QString getWorkSubdirectory() const;
+
+  virtual QMap<QString, ctkXnatLoginProfile*> getLoginProfiles() const = 0;
+  virtual void setLoginProfiles(QMap<QString, ctkXnatLoginProfile*> loginProfiles) = 0;
+
+  virtual ctkXnatLoginProfile* getLoginProfile(QString profileName) const = 0;
+  virtual void setLoginProfile(QString profileName, ctkXnatLoginProfile*) = 0;
+
+  virtual void removeLoginProfile(QString profileName) = 0;
+
+  virtual ctkXnatLoginProfile* getDefaultLoginProfile() const = 0;
+
+protected:
+  explicit ctkXnatSettings();
+  virtual ~ctkXnatSettings();
+};
+
+#endif

+ 137 - 0
Libs/XNAT/ctkXnatSubject.cpp

@@ -0,0 +1,137 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 "ctkXnatSubject.h"
+
+#include "ctkXnatConnection.h"
+#include "ctkXnatSubject.h"
+
+class ctkXnatSubjectPrivate
+{
+public:
+  QString id;
+  QString project;
+  QString label;
+  QString insertDate;
+  QString insertUser;
+  QString uri;
+};
+
+ctkXnatSubject::ctkXnatSubject(ctkXnatObject* parent)
+: ctkXnatObject(parent)
+, d_ptr(new ctkXnatSubjectPrivate())
+{
+}
+
+ctkXnatSubject::~ctkXnatSubject()
+{
+}
+
+const QString& ctkXnatSubject::id() const
+{
+  Q_D(const ctkXnatSubject);
+  return d->id;
+}
+
+void ctkXnatSubject::setId(const QString& id)
+{
+  Q_D(ctkXnatSubject);
+  d->id = id;
+}
+
+const QString& ctkXnatSubject::project() const
+{
+  Q_D(const ctkXnatSubject);
+  return d->project;
+}
+
+void ctkXnatSubject::setProject(const QString& project)
+{
+  Q_D(ctkXnatSubject);
+  d->project = project;
+}
+
+const QString& ctkXnatSubject::label() const
+{
+  Q_D(const ctkXnatSubject);
+  return d->label;
+}
+
+void ctkXnatSubject::setLabel(const QString& label)
+{
+  Q_D(ctkXnatSubject);
+  d->label = label;
+}
+
+const QString& ctkXnatSubject::insertDate() const
+{
+  Q_D(const ctkXnatSubject);
+  return d->insertDate;
+}
+
+void ctkXnatSubject::setInsertDate(const QString& insertDate)
+{
+  Q_D(ctkXnatSubject);
+  d->insertDate = insertDate;
+}
+
+const QString& ctkXnatSubject::insertUser() const
+{
+  Q_D(const ctkXnatSubject);
+  return d->insertUser;
+}
+
+void ctkXnatSubject::setInsertUser(const QString& insertUser)
+{
+  Q_D(ctkXnatSubject);
+  d->insertUser = insertUser;
+}
+
+const QString& ctkXnatSubject::uri() const
+{
+  Q_D(const ctkXnatSubject);
+  return d->uri;
+}
+
+void ctkXnatSubject::setUri(const QString& uri)
+{
+  Q_D(ctkXnatSubject);
+  d->uri = uri;
+}
+
+void ctkXnatSubject::fetch(ctkXnatConnection* connection)
+{
+  connection->fetch(this);
+}
+
+QString ctkXnatSubject::getKind() const
+{
+  return "experiment";
+}
+
+bool ctkXnatSubject::isModifiable(int childIndex) const
+{
+  if (getChildren()[childIndex] == 0)
+  {
+    return false;
+  }
+  return getChildren()[childIndex]->isModifiable();
+}

+ 79 - 0
Libs/XNAT/ctkXnatSubject.h

@@ -0,0 +1,79 @@
+/*=============================================================================
+
+  Plugin: org.commontk.xnat
+
+  Copyright (c) University College London,
+    Centre for Medical Image Computing
+
+  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 ctkXnatSubject_h
+#define ctkXnatSubject_h
+
+#include "ctkXNATExport.h"
+
+#include "ctkXnatObject.h"
+
+class ctkXnatConnection;
+
+class ctkXnatSubjectPrivate;
+
+class CTK_XNAT_EXPORT ctkXnatSubject : public ctkXnatObject
+{
+  Q_OBJECT
+
+  Q_PROPERTY(QString ID READ id WRITE setId)
+  Q_PROPERTY(QString project READ project WRITE setProject)
+  Q_PROPERTY(QString label READ label WRITE setLabel)
+  Q_PROPERTY(QString insert_date READ insertDate WRITE setInsertDate)
+  Q_PROPERTY(QString insert_user READ insertUser WRITE setInsertUser)
+  Q_PROPERTY(QString URI READ uri WRITE setUri)
+
+public:
+  explicit ctkXnatSubject(ctkXnatObject* parent = 0);
+  virtual ~ctkXnatSubject();
+
+  const QString& id() const;
+  void setId(const QString& id);
+
+  const QString& project() const;
+  void setProject(const QString& project);
+
+  const QString& label() const;
+  void setLabel(const QString& label);
+
+  const QString& insertDate() const;
+  void setInsertDate(const QString& insertDate);
+
+  const QString& insertUser() const;
+  void setInsertUser(const QString& insertUser);
+
+  const QString& uri() const;
+  void setUri(const QString& uri);
+
+  virtual void fetch(ctkXnatConnection* connection);
+
+  virtual QString getKind() const;
+
+  virtual bool isModifiable(int parentIndex) const;
+
+private:
+  QScopedPointer<ctkXnatSubjectPrivate> d_ptr;
+
+  Q_DECLARE_PRIVATE(ctkXnatSubject);
+  Q_DISABLE_COPY(ctkXnatSubject);
+};
+
+#endif

+ 11 - 0
Libs/XNAT/target_libraries.cmake

@@ -0,0 +1,11 @@
+#
+# See CMake/ctkFunctionGetTargetLibraries.cmake
+#
+# This file should list the libraries required to build the current CTK libraries
+#
+
+set(target_libraries
+  qRestAPI_LIBRARIES
+  QT_LIBRARIES
+  QtScript
+  )