Ver código fonte

Merge remote-tracking branch 'niftk-ctk/ctk-xnat-support' into xnat-support

Sascha Zelzer 11 anos atrás
pai
commit
714cb2d2f4

+ 1 - 1
CMakeExternals/qRestAPI.cmake

@@ -23,7 +23,7 @@ if(${add_project})
 
     if(NOT DEFINED qRestAPI_DIR)
 
-      set(revision_tag "5830a8146b")
+      set(revision_tag "d81b73b330")
       if(${proj}_REVISION_TAG)
         set(revision_tag ${${proj}_REVISION_TAG})
       endif()

+ 84 - 5
Libs/XNAT/Core/Testing/ctkXnatConnectionTest.cpp

@@ -35,6 +35,7 @@
 #include <ctkXnatConnectionFactory.h>
 #include <ctkXnatProject.h>
 #include <ctkXnatServer.h>
+#include <ctkXnatSubject.h>
 
 class ctkXnatConnectionTestCasePrivate
 {
@@ -104,6 +105,43 @@ void ctkXnatConnectionTestCase::testResourceUri()
   QVERIFY(server->resourceUri().isEmpty());
 }
 
+void ctkXnatConnectionTestCase::testParentChild()
+{
+  Q_D(ctkXnatConnectionTestCase);
+
+  ctkXnatServer* server = d->Connection->server();
+
+  ctkXnatProject* project = new ctkXnatProject(server);
+
+  QVERIFY(project->parent() == server);
+
+  QVERIFY(server->children().contains(project));
+
+  server->add(project);
+
+  int numberOfOccurrences = 0;
+  foreach (ctkXnatObject* serverProject, server->children())
+  {
+    if (serverProject == project || serverProject->id() == project->id())
+    {
+      ++numberOfOccurrences;
+    }
+  }
+  QVERIFY(numberOfOccurrences == 1);
+
+  server->remove(project);
+  numberOfOccurrences = 0;
+  foreach (ctkXnatObject* serverProject, server->children())
+  {
+    if (serverProject == project || serverProject->id() == project->id())
+    {
+      ++numberOfOccurrences;
+    }
+  }
+  QVERIFY(numberOfOccurrences == 0);
+  delete project;
+}
+
 void ctkXnatConnectionTestCase::testCreateProject()
 {
   Q_D(ctkXnatConnectionTestCase);
@@ -113,21 +151,62 @@ void ctkXnatConnectionTestCase::testCreateProject()
   QString projectId = QString("CTK_") + QUuid::createUuid().toString().mid(1, 8);
   d->Project = projectId;
 
-  ctkXnatProject* project = new ctkXnatProject();
+  ctkXnatProject* project = new ctkXnatProject(server);
   project->setId(projectId);
   project->setName(projectId);
-  project->setDescription("CTK test project");
-  server->add(project);
+  project->setDescription("CTK_test_project");
 
   bool exists = d->Connection->exists(project);
   QVERIFY(!exists);
 
-  d->Connection->create(project);
+  d->Connection->save(project);
 
   exists = d->Connection->exists(project);
   QVERIFY(exists);
 
-  d->Connection->create(project);
+  d->Connection->remove(project);
+
+  exists = d->Connection->exists(project);
+  QVERIFY(!exists);
+}
+
+void ctkXnatConnectionTestCase::testCreateSubject()
+{
+  Q_D(ctkXnatConnectionTestCase);
+
+  ctkXnatServer* server = d->Connection->server();
+
+  QString projectId = QString("CTK_") + QUuid::createUuid().toString().mid(1, 8);
+  d->Project = projectId;
+
+  ctkXnatProject* project = new ctkXnatProject(server);
+  project->setId(projectId);
+  project->setName(projectId);
+  project->setDescription("CTK_test_project");
+
+  QVERIFY(!project->exists());
+
+  project->save();
+
+  QVERIFY(project->exists());
+
+  ctkXnatSubject* subject = new ctkXnatSubject(project);
+
+  QString subjectName = QString("CTK_S") + QUuid::createUuid().toString().mid(1, 8);
+  subject->setId(subjectName);
+  subject->setName(subjectName);
+
+  subject->save();
+
+  QVERIFY(!subject->id().isNull());
+
+  subject->erase();
+
+  QVERIFY(!subject->exists());
+
+  project->erase();
+
+  QVERIFY(!project->exists());
 }
 
 // --------------------------------------------------------------------------

+ 4 - 0
Libs/XNAT/Core/Testing/ctkXnatConnectionTest.h

@@ -42,12 +42,16 @@ private slots:
 
   void cleanupTestCase();
 
+  void testParentChild();
+
   void testProjectList();
 
   void testResourceUri();
 
   void testCreateProject();
 
+  void testCreateSubject();
+
 private:
   QScopedPointer<ctkXnatConnectionTestCasePrivate> d_ptr;
 

+ 25 - 5
Libs/XNAT/Core/ctkXnatConnection.cpp

@@ -25,7 +25,6 @@
 #include "ctkXnatExperiment.h"
 #include "ctkXnatFile.h"
 #include "ctkXnatObject.h"
-#include "ctkXnatObjectPrivate.h"
 #include "ctkXnatProject.h"
 #include "ctkXnatReconstruction.h"
 #include "ctkXnatReconstructionFolder.h"
@@ -385,7 +384,7 @@ void ctkXnatConnection::fetch(ctkXnatReconstructionResource* reconstructionResou
   }
 }
 
-bool ctkXnatConnection::exists(ctkXnatObject* object)
+bool ctkXnatConnection::exists(const ctkXnatObject* object)
 {
   Q_D(ctkXnatConnection);
 
@@ -395,18 +394,39 @@ bool ctkXnatConnection::exists(ctkXnatObject* object)
   return success;
 }
 
-void ctkXnatConnection::create(ctkXnatObject* object)
+void ctkXnatConnection::save(ctkXnatObject* object)
 {
   Q_D(ctkXnatConnection);
 
   QString query = object->resourceUri();
+
+  query.append(QString("?%1=%2").arg("xsi:type", object->schemaType()));
+  const QMap<QString, QString>& properties = object->properties();
+  QMapIterator<QString, QString> itProperties(properties);
+  while (itProperties.hasNext())
+  {
+    itProperties.next();
+    query.append(QString("&%1=%2").arg(itProperties.key(), itProperties.value()));
+  }
+
   qDebug() << "ctkXnatConnection::create() query:" << query;
-  bool success = d->xnat->sync(d->xnat->put(query));
+  QUuid queryId = d->xnat->put(query);
+  qRestResult* result = d->xnat->takeResult(queryId);
 
-  if (!success)
+  if (!result || !result->error().isNull())
   {
     throw ctkXnatException("Error occurred while creating the data.");
   }
+
+  const QList<QVariantMap>& maps = result->results();
+  if (maps.size() == 1 && maps[0].size() == 1)
+  {
+    QVariant id = maps[0]["ID"];
+    if (!id.isNull())
+    {
+      object->setId(id.toString());
+    }
+  }
 }
 
 void ctkXnatConnection::remove(ctkXnatObject* object)

+ 2 - 2
Libs/XNAT/Core/ctkXnatConnection.h

@@ -82,9 +82,9 @@ public:
   void fetch(ctkXnatReconstruction* reconstruction);
   void fetch(ctkXnatReconstructionResource* reconstructionResource);
 
-  bool exists(ctkXnatObject* object);
+  bool exists(const ctkXnatObject* object);
 
-  void create(ctkXnatObject* object);
+  void save(ctkXnatObject* object);
   void remove(ctkXnatObject* object);
 
   void download(ctkXnatFile* file, const QString& fileName);

+ 3 - 2
Libs/XNAT/Core/ctkXnatExperiment.cpp

@@ -23,6 +23,7 @@
 
 #include "ctkXnatConnection.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatSubject.h"
 
 class ctkXnatExperimentPrivate : public ctkXnatObjectPrivate
 {
@@ -42,8 +43,8 @@ public:
 };
 
 
-ctkXnatExperiment::ctkXnatExperiment(const QString& schemaType)
-: ctkXnatObject(*new ctkXnatExperimentPrivate(), schemaType)
+ctkXnatExperiment::ctkXnatExperiment(ctkXnatSubject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatExperimentPrivate(), parent, schemaType)
 {
 }
 

+ 2 - 1
Libs/XNAT/Core/ctkXnatExperiment.h

@@ -28,13 +28,14 @@
 
 class ctkXnatConnection;
 class ctkXnatExperimentPrivate;
+class ctkXnatSubject;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatExperiment : public ctkXnatObject
 {
   
 public:
   
-  explicit ctkXnatExperiment(const QString& schemaType = "xnat:experimentData");
+  explicit ctkXnatExperiment(ctkXnatSubject* parent = 0, const QString& schemaType = "xnat:experimentData");
   virtual ~ctkXnatExperiment();
   
   virtual QString resourceUri() const;

+ 2 - 2
Libs/XNAT/Core/ctkXnatFile.cpp

@@ -42,8 +42,8 @@ public:
 //  QString uri;
 };
 
-ctkXnatFile::ctkXnatFile()
-: ctkXnatObject(*new ctkXnatFilePrivate())
+ctkXnatFile::ctkXnatFile(ctkXnatObject* parent)
+: ctkXnatObject(*new ctkXnatFilePrivate(), parent)
 {
 }
 

+ 1 - 1
Libs/XNAT/Core/ctkXnatFile.h

@@ -34,7 +34,7 @@ class CTK_XNAT_CORE_EXPORT ctkXnatFile : public ctkXnatObject
 
 public:
 
-  explicit ctkXnatFile();
+  explicit ctkXnatFile(ctkXnatObject* parent = 0);
   virtual ~ctkXnatFile();
   
   virtual QString resourceUri() const;

+ 23 - 20
Libs/XNAT/Core/ctkXnatObject.cpp

@@ -29,17 +29,19 @@
 #include <QVariant>
 
 
-ctkXnatObject::ctkXnatObject(const QString& schemaType)
+ctkXnatObject::ctkXnatObject(ctkXnatObject* parent, const QString& schemaType)
 : d_ptr(new ctkXnatObjectPrivate())
 {
   Q_D(ctkXnatObject);
+  this->setParent(parent);
   d->schemaType = schemaType;
 }
 
-ctkXnatObject::ctkXnatObject(ctkXnatObjectPrivate& dd, const QString& schemaType)
+ctkXnatObject::ctkXnatObject(ctkXnatObjectPrivate& dd, ctkXnatObject* parent, const QString& schemaType)
 : d_ptr(&dd)
 {
   Q_D(ctkXnatObject);
+  this->setParent(parent);
   d->schemaType = schemaType;
 }
 
@@ -106,21 +108,10 @@ void ctkXnatObject::setProperty(const QString& name, const QVariant& value)
   d->properties.insert(name, value.toString());
 }
 
-
-QList<QString> ctkXnatObject::properties()
+const QMap<QString, QString>& ctkXnatObject::properties() const
 {
-  Q_D(ctkXnatObject);
-  
-  QList<QString> value;
-
-  QMapIterator<QString, QString> it(d->properties);
-  while (it.hasNext())
-  {
-    it.next();
-    value.push_back (it.key());
-  }
-
-  return value;
+  Q_D(const ctkXnatObject);
+  return d->properties;
 }
 
 ctkXnatObject* ctkXnatObject::parent() const
@@ -171,10 +162,6 @@ void ctkXnatObject::add(ctkXnatObject* child)
 void ctkXnatObject::remove(ctkXnatObject* child)
 {
   Q_D(ctkXnatObject);
-  if (child->parent() == this)
-  {
-    child->d_func()->parent = 0;
-  }
   if (!d->children.removeOne(child))
   {
     qWarning() << "ctkXnatObject::remove(): Child does not exist";
@@ -226,3 +213,19 @@ void ctkXnatObject::download(const QString& /*zipFilename*/)
 void ctkXnatObject::upload(const QString& /*zipFilename*/)
 {
 }
+
+bool ctkXnatObject::exists() const
+{
+  return this->connection()->exists(this);
+}
+
+void ctkXnatObject::save()
+{
+  this->connection()->save(this);
+}
+
+void ctkXnatObject::erase()
+{
+  this->connection()->remove(this);
+  this->parent()->remove(this);
+}

+ 15 - 6
Libs/XNAT/Core/ctkXnatObject.h

@@ -75,9 +75,9 @@ public:
   /// Sets the value of the property with the given name.
   void setProperty(const QString& name, const QVariant& value);
 
-  /// Gets the list of the properties of the object.
-  QList<QString> properties();
-  
+  /// Gets the properties of the object.
+  const QMap<QString, QString>& properties() const;
+
   /// Gets the parent of the object in the data hierarchy. The returned pointer
   /// is 0 for the ctkXnatServer objects and different for any other type of
   /// XNAT objects.
@@ -92,7 +92,7 @@ public:
   /// Adds an object to the children of the current one.
   void add(ctkXnatObject* child);
 
-  /// Removes the object from the children of the current object.
+  /// Removes the object from the children of the current object and removes it from the XNAT server.
   void remove(ctkXnatObject* child);
 
   /// Tells if the children and the properties of the objects have been fetched.
@@ -105,16 +105,25 @@ public:
   /// Fetches the children and the properties of the object.
   void fetch();
 
+  /// Checks if the object exists on the XNAT server.
+  bool exists() const;
+
+  /// Creates the object on the XNAT server and sets the new ID.
+  void save();
+
+  /// Deletes the object on the XNAT server and removes it from its parent.
+  void erase();
+
   virtual void download(const QString&);
   virtual void upload(const QString&);
 
 protected:
 
   /// Constructs the ctkXnatObject.
-  ctkXnatObject(const QString& schemaType = QString());
+  ctkXnatObject(ctkXnatObject* parent = 0, const QString& schemaType = QString());
 
   /// Constructs the ctkXnatObject with the given private part.
-  ctkXnatObject(ctkXnatObjectPrivate& dd, const QString& schemaType = QString());
+  ctkXnatObject(ctkXnatObjectPrivate& dd, ctkXnatObject* parent = 0, const QString& schemaType = QString());
 
   /// Gets the object that represents the connection to the XNAT server
   /// that stores the current object.

+ 1 - 1
Libs/XNAT/Core/ctkXnatObjectPrivate.h

@@ -46,7 +46,7 @@ private:
 
   QString schemaType;
 
-  QMap<QString,QString> properties;
+  QMap<QString, QString> properties;
 
   QList<ctkXnatObject*> children;
 

+ 3 - 2
Libs/XNAT/Core/ctkXnatProject.cpp

@@ -23,6 +23,7 @@
 
 #include "ctkXnatConnection.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatServer.h"
 
 class ctkXnatProjectPrivate : public ctkXnatObjectPrivate
 {
@@ -47,8 +48,8 @@ public:
 //  QString uri;
 };
 
-ctkXnatProject::ctkXnatProject(const QString& schemaType)
-: ctkXnatObject(*new ctkXnatProjectPrivate(), schemaType)
+ctkXnatProject::ctkXnatProject(ctkXnatServer* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatProjectPrivate(), parent, schemaType)
 {
 }
 

+ 2 - 1
Libs/XNAT/Core/ctkXnatProject.h

@@ -28,13 +28,14 @@
 
 class ctkXnatConnection;
 class ctkXnatProjectPrivate;
+class ctkXnatServer;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatProject : public ctkXnatObject
 {
 
 public:
 
-  explicit ctkXnatProject(const QString& schemaType = "xnat:projectData");
+  explicit ctkXnatProject(ctkXnatServer* parent = 0, const QString& schemaType = "xnat:projectData");
   virtual ~ctkXnatProject();
 
   virtual QString resourceUri() const;

+ 3 - 2
Libs/XNAT/Core/ctkXnatReconstruction.cpp

@@ -23,6 +23,7 @@
 
 #include "ctkXnatConnection.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatReconstructionFolder.h"
 
 class ctkXnatReconstructionPrivate : public ctkXnatObjectPrivate
 {
@@ -42,8 +43,8 @@ public:
 };
 
 
-ctkXnatReconstruction::ctkXnatReconstruction(const QString& schemaType)
-: ctkXnatObject(*new ctkXnatReconstructionPrivate(), schemaType)
+ctkXnatReconstruction::ctkXnatReconstruction(ctkXnatReconstructionFolder* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatReconstructionPrivate(), parent, schemaType)
 {
 }
 

+ 2 - 1
Libs/XNAT/Core/ctkXnatReconstruction.h

@@ -27,6 +27,7 @@
 #include "ctkXnatObject.h"
 
 class ctkXnatConnection;
+class ctkXnatReconstructionFolder;
 class ctkXnatReconstructionPrivate;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatReconstruction : public ctkXnatObject
@@ -34,7 +35,7 @@ class CTK_XNAT_CORE_EXPORT ctkXnatReconstruction : public ctkXnatObject
 
 public:
 
-  explicit ctkXnatReconstruction(const QString& schemaType = "xnat:reconstructedImageData");
+  explicit ctkXnatReconstruction(ctkXnatReconstructionFolder* parent = 0, const QString& schemaType = "xnat:reconstructedImageData");
   virtual ~ctkXnatReconstruction();
   
   virtual QString resourceUri() const;

+ 3 - 2
Libs/XNAT/Core/ctkXnatReconstructionFolder.cpp

@@ -22,6 +22,7 @@
 #include "ctkXnatReconstructionFolder.h"
 
 #include "ctkXnatConnection.h"
+#include "ctkXnatExperiment.h"
 #include "ctkXnatObjectPrivate.h"
 
 
@@ -43,8 +44,8 @@ public:
 };
 
 
-ctkXnatReconstructionFolder::ctkXnatReconstructionFolder()
-: ctkXnatObject(*new ctkXnatReconstructionFolderPrivate())
+ctkXnatReconstructionFolder::ctkXnatReconstructionFolder(ctkXnatExperiment* parent)
+: ctkXnatObject(*new ctkXnatReconstructionFolderPrivate(), parent)
 {
   this->setProperty("ID", "reconstructions");
 }

+ 2 - 1
Libs/XNAT/Core/ctkXnatReconstructionFolder.h

@@ -27,6 +27,7 @@
 #include "ctkXnatObject.h"
 
 class ctkXnatConnection;
+class ctkXnatExperiment;
 class ctkXnatReconstructionFolderPrivate;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatReconstructionFolder : public ctkXnatObject
@@ -34,7 +35,7 @@ class CTK_XNAT_CORE_EXPORT ctkXnatReconstructionFolder : public ctkXnatObject
 
 public:
   
-  explicit ctkXnatReconstructionFolder();
+  explicit ctkXnatReconstructionFolder(ctkXnatExperiment* parent = 0);
   virtual ~ctkXnatReconstructionFolder();
   
   virtual QString resourceUri() const;

+ 3 - 2
Libs/XNAT/Core/ctkXnatReconstructionResource.cpp

@@ -23,6 +23,7 @@
 
 #include "ctkXnatConnection.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatReconstruction.h"
 
 class ctkXnatReconstructionResourcePrivate : public ctkXnatObjectPrivate
 {
@@ -42,8 +43,8 @@ public:
 };
 
 
-ctkXnatReconstructionResource::ctkXnatReconstructionResource()
-: ctkXnatObject(*new ctkXnatReconstructionResourcePrivate())
+ctkXnatReconstructionResource::ctkXnatReconstructionResource(ctkXnatReconstruction* parent)
+: ctkXnatObject(*new ctkXnatReconstructionResourcePrivate(), parent)
 {
 }
 

+ 2 - 1
Libs/XNAT/Core/ctkXnatReconstructionResource.h

@@ -28,13 +28,14 @@
 
 class ctkXnatConnection;
 class ctkXnatReconstructionResourcePrivate;
+class ctkXnatReconstruction;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatReconstructionResource : public ctkXnatObject
 {
   
 public:
 
-  explicit ctkXnatReconstructionResource();
+  explicit ctkXnatReconstructionResource(ctkXnatReconstruction* parent = 0);
   virtual ~ctkXnatReconstructionResource();
   
   virtual QString resourceUri() const;

+ 3 - 2
Libs/XNAT/Core/ctkXnatScan.cpp

@@ -22,6 +22,7 @@
 #include "ctkXnatScan.h"
 
 #include "ctkXnatConnection.h"
+#include "ctkXnatScanFolder.h"
 #include "ctkXnatObjectPrivate.h"
 
 class ctkXnatScanPrivate : public ctkXnatObjectPrivate
@@ -42,8 +43,8 @@ public:
 };
 
 
-ctkXnatScan::ctkXnatScan(const QString& schemaType)
-: ctkXnatObject(*new ctkXnatScanPrivate(), schemaType)
+ctkXnatScan::ctkXnatScan(ctkXnatScanFolder* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatScanPrivate(), parent, schemaType)
 {
 }
 

+ 2 - 1
Libs/XNAT/Core/ctkXnatScan.h

@@ -27,6 +27,7 @@
 #include "ctkXnatObject.h"
 
 class ctkXnatConnection;
+class ctkXnatScanFolder;
 class ctkXnatScanPrivate;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatScan : public ctkXnatObject
@@ -34,7 +35,7 @@ class CTK_XNAT_CORE_EXPORT ctkXnatScan : public ctkXnatObject
 
 public:
 
-  explicit ctkXnatScan(const QString& schemaType = "xnat:imageScanData");
+  explicit ctkXnatScan(ctkXnatScanFolder* parent = 0, const QString& schemaType = "xnat:imageScanData");
   virtual ~ctkXnatScan();
   
   virtual QString resourceUri() const;

+ 3 - 2
Libs/XNAT/Core/ctkXnatScanFolder.cpp

@@ -22,6 +22,7 @@
 #include "ctkXnatScanFolder.h"
 
 #include "ctkXnatConnection.h"
+#include "ctkXnatExperiment.h"
 #include "ctkXnatObjectPrivate.h"
 
 
@@ -43,8 +44,8 @@ public:
 };
 
 
-ctkXnatScanFolder::ctkXnatScanFolder()
-: ctkXnatObject(*new ctkXnatScanFolderPrivate())
+ctkXnatScanFolder::ctkXnatScanFolder(ctkXnatExperiment* parent)
+: ctkXnatObject(*new ctkXnatScanFolderPrivate(), parent)
 {
   this->setProperty("ID", "scans");
 }

+ 2 - 1
Libs/XNAT/Core/ctkXnatScanFolder.h

@@ -27,6 +27,7 @@
 #include "ctkXnatObject.h"
 
 class ctkXnatConnection;
+class ctkXnatExperiment;
 class ctkXnatScanFolderPrivate;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatScanFolder : public ctkXnatObject
@@ -34,7 +35,7 @@ class CTK_XNAT_CORE_EXPORT ctkXnatScanFolder : public ctkXnatObject
 
 public:
   
-  explicit ctkXnatScanFolder();
+  explicit ctkXnatScanFolder(ctkXnatExperiment* parent = 0);
   virtual ~ctkXnatScanFolder();
   
   virtual QString resourceUri() const;

+ 3 - 2
Libs/XNAT/Core/ctkXnatScanResource.cpp

@@ -23,6 +23,7 @@
 
 #include "ctkXnatConnection.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatScan.h"
 
 class ctkXnatScanResourcePrivate : public ctkXnatObjectPrivate
 {
@@ -42,8 +43,8 @@ public:
 };
 
 
-ctkXnatScanResource::ctkXnatScanResource()
-: ctkXnatObject(*new ctkXnatScanResourcePrivate())
+ctkXnatScanResource::ctkXnatScanResource(ctkXnatScan* parent)
+: ctkXnatObject(*new ctkXnatScanResourcePrivate(), parent)
 {
 }
 

+ 2 - 1
Libs/XNAT/Core/ctkXnatScanResource.h

@@ -27,6 +27,7 @@
 #include "ctkXnatObject.h"
 
 class ctkXnatConnection;
+class ctkXnatScan;
 class ctkXnatScanResourcePrivate;
 
 class CTK_XNAT_CORE_EXPORT ctkXnatScanResource : public ctkXnatObject
@@ -34,7 +35,7 @@ class CTK_XNAT_CORE_EXPORT ctkXnatScanResource : public ctkXnatObject
   
 public:
 
-  explicit ctkXnatScanResource();
+  explicit ctkXnatScanResource(ctkXnatScan* parent = 0);
   virtual ~ctkXnatScanResource();
 
   QString resourceUri() const;

+ 3 - 2
Libs/XNAT/Core/ctkXnatSubject.cpp

@@ -25,6 +25,7 @@
 
 #include "ctkXnatConnection.h"
 #include "ctkXnatObjectPrivate.h"
+#include "ctkXnatProject.h"
 
 class ctkXnatSubjectPrivate : public ctkXnatObjectPrivate
 {
@@ -50,8 +51,8 @@ public:
   QList<ctkXnatProject*> projects;
 };
 
-ctkXnatSubject::ctkXnatSubject(const QString& schemaType)
-: ctkXnatObject(*new ctkXnatSubjectPrivate(), schemaType)
+ctkXnatSubject::ctkXnatSubject(ctkXnatProject* parent, const QString& schemaType)
+: ctkXnatObject(*new ctkXnatSubjectPrivate(), parent, schemaType)
 {
 }
 

+ 1 - 1
Libs/XNAT/Core/ctkXnatSubject.h

@@ -34,7 +34,7 @@ class CTK_XNAT_CORE_EXPORT ctkXnatSubject : public ctkXnatObject
 
 public:
 
-  explicit ctkXnatSubject(const QString& schemaType = "xnat:subjectData");
+  explicit ctkXnatSubject(ctkXnatProject* parent = 0, const QString& schemaType = "xnat:subjectData");
   virtual ~ctkXnatSubject();
 
   ctkXnatProject* getPrimaryProject() const;