瀏覽代碼

Merge branch 'master' of github.com:pieper/CTK

Patrick Cheng 15 年之前
父節點
當前提交
cb409c77c9

+ 3 - 3
CMake/CTKBuildQtLibMacro.cmake

@@ -2,8 +2,8 @@
 #
 #
 #
-MACRO(ctk_build_qtlib)
-  CTK_PARSE_ARGUMENTS(MYQTLIB
+MACRO(CtkMacroBuildQtLib)
+  ctkMacroParseArguments(MYQTLIB
     "NAME;EXPORT_DIRECTIVE;SRCS;MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;RESOURCES;LIBRARY_TYPE"
     ""
     ${ARGN}
@@ -96,6 +96,6 @@ MACRO(ctk_build_qtlib)
     DESTINATION ${CTK_INSTALL_INCLUDE_DIR} COMPONENT Development
     )
 
-ENDMACRO(ctk_build_qtlib)
+ENDMACRO()
 
 

+ 3 - 3
CMake/CTKBuildQtPluginMacro.cmake

@@ -2,8 +2,8 @@
 #
 #
 #
-MACRO(ctk_build_qtplugin)
-  CTK_PARSE_ARGUMENTS(MYQTPLUGIN
+MACRO(CtkMacroBuildQtPlugin)
+  CtkMacroParseArguments(MYQTPLUGIN
     "NAME;EXPORT_DIRECTIVE;SRCS;MOC_SRCS;UI_FORMS;INCLUDE_DIRECTORIES;TARGET_LIBRARIES;UI_RESOURCES;LIBRARY_TYPE"
     ""
     ${ARGN}
@@ -93,6 +93,6 @@ MACRO(ctk_build_qtplugin)
   #  DESTINATION ${CTK_INSTALL_INCLUDE_DIR} COMPONENT Development
   #  )
 
-ENDMACRO(ctk_build_qtplugin)
+ENDMACRO()
 
 

+ 17 - 0
CMake/ctkMacroGetTargetLibraries.cmake

@@ -0,0 +1,17 @@
+
+MACRO(ctkMacroGetTargetLibraries varname)
+
+  SET(target_libraries_path ${CMAKE_CURRENT_SOURCE_DIR}/target_libraries.cmake)
+  
+  # Check if "target_libraries.cmake" file exists
+  IF(NOT EXISTS ${target_libraries_path})
+    MESSAGE(FATAL_ERROR "${target_libraries_path} doesn't exists !")
+  ENDIF()
+
+  # Make sure the variable is cleared 
+  SET(target_libraries )
+
+  INCLUDE(${target_libraries_path})
+
+  SET(${varname} ${target_libraries})
+ENDMACRO()

+ 2 - 2
CMake/CTKParseArgumentsMacro.cmake

@@ -2,7 +2,7 @@
 #
 # See http://www.cmake.org/Wiki/CMakeMacroParseArguments
 #
-MACRO(CTK_PARSE_ARGUMENTS prefix arg_names option_names)
+MACRO(CtkMacroParseArguments prefix arg_names option_names)
   SET(DEFAULT_ARGS)
   FOREACH(arg_name ${arg_names})
     SET(${prefix}_${arg_name})
@@ -31,4 +31,4 @@ MACRO(CTK_PARSE_ARGUMENTS prefix arg_names option_names)
     ENDIF (is_arg_name GREATER -1)
   ENDFOREACH(arg)
   SET(${prefix}_${current_arg_name} ${current_arg_list})
-ENDMACRO(CTK_PARSE_ARGUMENTS)
+ENDMACRO()

+ 6 - 2
CMake/CTKSetupQt.cmake

@@ -5,7 +5,7 @@
 #
 
 
-MACRO(ctk_setup_qt)
+MACRO(ctkMacroSetupQt)
 
   IF(DEFINED CTK_QMAKE_EXECUTABLE)
     SET(QT_QMAKE_EXECUTABLE ${CTK_QMAKE_EXECUTABLE})
@@ -14,6 +14,10 @@ MACRO(ctk_setup_qt)
   SET(minimum_required_qt_version "4.6")
 
   FIND_PACKAGE(Qt4)
+
+  # This option won't show up in the main CMake configure panel
+  MARK_AS_ADVANCED(QT_QMAKE_EXECUTABLE)
+  
   IF(QT4_FOUND)
 
     IF(NOT "${QT_VERSION_MAJOR}.${QT_VERSION_MINOR}" STREQUAL "${minimum_required_qt_version}")
@@ -30,4 +34,4 @@ MACRO(ctk_setup_qt)
     MESSAGE(FATAL_ERROR "error: Qt4 was not found on your system. You probably need to set the QT_QMAKE_EXECUTABLE variable")
   ENDIF(QT4_FOUND)
 
-ENDMACRO(ctk_setup_qt)
+ENDMACRO()

+ 16 - 11
CMakeLists.txt

@@ -20,7 +20,6 @@ IF(NOT EXECUTABLE_OUTPUT_PATH)
 ENDIF(NOT EXECUTABLE_OUTPUT_PATH)
 SET(CTK_LIBRARY_PATH ${LIBRARY_OUTPUT_PATH}/${CMAKE_CFG_INTDIR})
 SET(CTK_EXECUTABLE_PATH ${EXECUTABLE_OUTPUT_PATH}/${CMAKE_CFG_INTDIR})
-SET(CXX_TEST_PATH ${EXECUTABLE_OUTPUT_PATH})
 
 #-----------------------------------------------------------------------------
 # Install directories, used for install rules.
@@ -44,10 +43,11 @@ SET(CTK_BASE_INCLUDE_DIRS CACHE INTERNAL "CTK includes" FORCE)
 #-----------------------------------------------------------------------------
 # CMake Macro(s)
 # 
-INCLUDE(CMake/CTKParseArgumentsMacro.cmake)
-INCLUDE(CMake/CTKBuildQtLibMacro.cmake)
-INCLUDE(CMake/CTKBuildQtPluginMacro.cmake)
-INCLUDE(CMake/CTKSetupQt.cmake)
+INCLUDE(CMake/ctkMacroParseArguments.cmake)
+INCLUDE(CMake/ctkMacroBuildQtLib.cmake)
+INCLUDE(CMake/ctkMacroBuildQtPlugin.cmake)
+INCLUDE(CMake/ctkMacroSetupQt.cmake)
+INCLUDE(CMake/ctkMacroGetTargetLibraries.cmake)
 
 #-----------------------------------------------------------------------------
 # Testing
@@ -56,7 +56,7 @@ OPTION(BUILD_TESTING "Test the project" ON)
 IF(BUILD_TESTING)
   ENABLE_TESTING()
   INCLUDE(CTest)
-  SET(CXX_TEST_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
+  SET(CXX_TEST_PATH ${EXECUTABLE_OUTPUT_PATH})
   MARK_AS_ADVANCED(TCL_TCLSH DART_ROOT)
     
   # Setup file for setting custom ctest vars
@@ -88,7 +88,7 @@ ENDIF()
 #-----------------------------------------------------------------------------
 # QT
 #
-ctk_setup_qt()
+ctkMacroSetupQt()
 
 #-----------------------------------------------------------------------------
 # CTK Libraries
@@ -97,20 +97,25 @@ SET(ctk_libs
   Core
   Widgets
   DICOM/Core
-  DICOM/Widgets)
+  DICOM/Widgets
+  DICOM/Applications)
   
 #-----------------------------------------------------------------------------
 # To make options show up in both CTK-SuperBuild and CTK regular build, let's add them
 # before the SuperBuild script is included
 #
 
+# Let's mark as advanced some default properties
+MARK_AS_ADVANCED(CMAKE_INSTALL_PREFIX)
+MARK_AS_ADVANCED(DART_TESTING_TIMEOUT)
+
 # KWStyle
 OPTION(CTK_USE_KWSTYLE     "Enable sourcecode-based style tests." OFF)
-MARK_AS_ADVANCED(CTK_USE_KWSTYLE)
+#MARK_AS_ADVANCED(CTK_USE_KWSTYLE)
 
 # Build options
 FOREACH(lib ${ctk_libs})
-  OPTION(CTK_USE_${lib} "Enable ${lib} Support." ON)
+  OPTION(CTK_ENABLE_${lib} "Enable ${lib} Support." ON)
 ENDFOREACH()
 
 #-----------------------------------------------------------------------------
@@ -128,7 +133,7 @@ ENDIF()
 # Add subdirectories
 #
 FOREACH(lib ${ctk_libs})
-  IF (CTK_USE_${lib})
+  IF (CTK_ENABLE_${lib})
     ADD_SUBDIRECTORY(Libs/${lib})
   ENDIF()
 ENDFOREACH()

+ 4 - 5
Libs/Core/CMakeLists.txt

@@ -28,12 +28,11 @@ SET(KIT_UI_FORMS
 SET(KIT_resources
 )
 
-# Additional Target libraries
-SET(KIT_target_libraries
-  ${QT_LIBRARIES}
-  )
+# Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
+ctkMacroGetTargetLibraries(KIT_target_libraries)
 
-ctk_build_qtlib(
+# See CMake/ctkMacroBuildQtLib.cmake
+ctkMacroBuildQtLib(
   NAME ${PROJECT_NAME}
   EXPORT_DIRECTIVE ${KIT_export_directive}
   INCLUDE_DIRECTORIES ${KIT_include_directories}

+ 1 - 1
Libs/Core/Testing/CMakeLists.txt

@@ -19,7 +19,7 @@ IF(WIN32)
 ENDIF(WIN32)
 
 MACRO( SIMPLE_TEST  TESTNAME )
-  ADD_TEST( ${TESTNAME} ${LAUNCH_EXE} ${KIT_TESTS} ${TESTNAME} )
+  ADD_TEST( ${TESTNAME} ${KIT_TESTS} ${TESTNAME} )
 ENDMACRO( SIMPLE_TEST  )
 
 #

+ 9 - 0
Libs/Core/target_libraries.cmake

@@ -0,0 +1,9 @@
+#
+# See CMake/ctkMacroGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK libraries
+#
+
+SET(target_libraries
+  ${QT_LIBRARIES}
+  )

+ 2 - 1
Libs/DICOM/Applications/CMakeLists.txt

@@ -1,5 +1,5 @@
 
-
+INCLUDE_DIRECTORIES(${CTK_BASE_INCLUDE_DIRS})
 # Create executable
 ADD_EXECUTABLE(ctkDMCTK
   Main.cxx
@@ -7,6 +7,7 @@ ADD_EXECUTABLE(ctkDMCTK
 
 SET(KIT_LIBRARIES
   ${CTK_BASE_LIBRARIES}
+  # ${QT_LIBRARIES}
   )
 
 TARGET_LINK_LIBRARIES(ctkDMCTK ${KIT_LIBRARIES})

+ 2 - 2
Libs/DICOM/CMakeLists.txt

@@ -1,6 +1,6 @@
 
 
-# ADD_SUBDIRECTORY(Core)
+ADD_SUBDIRECTORY(Core)
 # ADD_SUBDIRECTORY(Widgets)
-# ADD_SUBDIRECTORY(Applications)
+ADD_SUBDIRECTORY(Applications)
 

+ 9 - 6
Libs/DICOM/Core/CMakeLists.txt

@@ -14,11 +14,14 @@ SET(KIT_include_directories
 SET(KIT_SRCS
   qCTKDCMTK.cxx
   qCTKDCMTK.h
+  qCTKDCMTKModel.cxx
+  qCTKDCMTKModel.h
   )
 
 # Headers that should run through moc
 SET(KIT_MOC_SRCS
   qCTKDCMTK.h
+  qCTKDCMTKModel.h
   )
 
 # UI files
@@ -27,14 +30,14 @@ SET(KIT_UI_FORMS
 
 # Resources
 SET(KIT_resources
+  Resources/dicom.qrc
 )
 
-# Additional Target libraries
-SET(KIT_target_libraries
-  CTKCore
-  )
+# Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
+ctkMacroGetTargetLibraries(KIT_target_libraries)
 
-ctk_build_qtlib(
+# See CMake/ctkMacroBuildQtLib.cmake
+ctkMacroBuildQtLib(
   NAME ${PROJECT_NAME}
   EXPORT_DIRECTIVE ${KIT_export_directive}
   INCLUDE_DIRECTORIES ${KIT_include_directories}
@@ -51,5 +54,5 @@ ctk_build_qtlib(
 
 # Testing
 IF(BUILD_TESTING)
-  #ADD_SUBDIRECTORY(Testing)
+  ADD_SUBDIRECTORY(Testing)
 ENDIF(BUILD_TESTING)

+ 5 - 0
Libs/DICOM/Core/Resources/dicom-sample.sql

@@ -3,6 +3,11 @@
 -- For the corresponding DICOM files and more information see
 -- http://www.slicer.org/slicerWiki/index.php/DICOM:Database
 -- 
+-- Note: the semicolon at the end is necessary for the simple parser to separate
+--       the statements since the SQlite driver does not handle multiple
+--       commands per QSqlQuery::exec call!
+-- ;
+ 
 BEGIN TRANSACTION;
 CREATE TABLE 'Images' (   'Filename' VARCHAR(1024) NOT NULL ,   'SeriesInstanceUID' VARCHAR(255) NOT NULL ,   PRIMARY KEY ('Filename') );
 INSERT INTO "Images" VALUES('CTHeadAxialDicom/CTHead24.dcm','1.2.826.0.1.3680043.2.1125.1.65375240934815452318141136507497058');

+ 5 - 2
Libs/DICOM/Core/Resources/dicom-schema.sql

@@ -1,8 +1,11 @@
 -- 
+-- A simple SQLITE3 database schema for modelling locally stored DICOM files 
 -- 
+-- Note: the semicolon at the end is necessary for the simple parser to separate
+--       the statements since the SQlite driver does not handle multiple
+--       commands per QSqlQuery::exec call!
+-- ;
 
-BEGIN TRANSACTION;
 DROP TABLE IF EXISTS 'Images' ;
 DROP TABLE IF EXISTS 'Patients' ;
 DROP TABLE IF EXISTS 'Series' ;
@@ -46,5 +49,4 @@ CREATE TABLE 'Studies' (
   'ReferringPhysician' VARCHAR(255) NULL ,
   'StudyDescription' VARCHAR(255) NULL ,
   PRIMARY KEY ('StudyInstanceUID') );
-COMMIT;
 

+ 2 - 0
Libs/DICOM/Core/Resources/dicom.qrc

@@ -3,3 +3,5 @@
   <file>dicom-schema.sql</file>
 </qresource>
 </RCC>
+
+

+ 22 - 0
Libs/DICOM/Core/Testing/CMakeLists.txt

@@ -0,0 +1,22 @@
+SET(KIT CTKDICOMCore)
+
+CREATE_TEST_SOURCELIST(Tests ${KIT}CxxTests.cxx
+  qCTKDCMTKModelTest1.cxx
+  qCTKDCMTKTest1.cxx
+  )
+
+SET (TestsToRun ${Tests})
+REMOVE (TestsToRun ${KIT}CxxTests.cxx)
+
+SET(LIBRARY_NAME ${PROJECT_NAME})
+
+ADD_EXECUTABLE(${KIT}CxxTests ${Tests})
+TARGET_LINK_LIBRARIES(${KIT}CxxTests ${LIBRARY_NAME})
+
+SET( CTKDICOMCore_TESTS ${CXX_TEST_PATH}/${KIT}CxxTests)
+IF(WIN32)
+  SET(CTKDICOMCore_TESTS ${CXX_TEST_PATH}/${CMAKE_BUILD_TYPE}/${KIT}CxxTests)
+ENDIF(WIN32)
+
+ADD_TEST( qCTKDCMTKModelTest1 ${CTKDICOMCore_TESTS} qCTKDCMTKModelTest1 ../../Resources/dicom-sample.sql)
+ADD_TEST( qCTKDCMTKTest1 ${CTKDICOMCore_TESTS} qCTKDCMTKTest1 ${CMAKE_CURRENT_BINARY_DIR}/dicom.db ${CMAKE_CURRENT_SOURCE_DIR}/../Resources/dicom-sample.sql)

+ 28 - 0
Libs/DICOM/Core/Testing/qCTKDCMTKModelTest1.cxx

@@ -0,0 +1,28 @@
+#include <QApplication>
+#include <QDebug>
+#include <QFileInfo>
+#include "qCTKDCMTKModel.h"
+
+#include <iostream>
+
+int qCTKDCMTKModelTest1( int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  qCTKDCMTKModel model(0);
+  if (argc <= 2)
+    {
+    std::cerr << "Warning, no sql file given. Test stops" << std::endl;
+    return EXIT_SUCCESS;
+    }
+  if (!QFileInfo(argv[1]).exists() || 
+      !QFileInfo(argv[2]).exists())
+    {
+    std::cerr << "Invalid sql file." << std::endl;
+    return EXIT_FAILURE;
+    }
+  model.setDataBase(argv[1]);
+  model.setDataBase(argv[2]);
+  
+  return EXIT_SUCCESS;
+}

+ 30 - 0
Libs/DICOM/Core/Testing/qCTKDCMTKTest1.cxx

@@ -0,0 +1,30 @@
+#include <QTextStream>
+#include <QApplication>
+
+#include "qCTKDCMTK.h"
+
+#include <iostream>
+#include <cstdlib>
+
+int qCTKDCMTKTest1(int argc, char** argv) {
+  
+  QApplication app(argc, argv);
+  QTextStream out(stdout);
+  qCTKDCMTK myCTK;
+  if ( myCTK.openDatabase( argv[1]) )
+    {
+    out << "open db success\n";
+    /// make sure it is empty and properly initialized
+    myCTK.initializeDatabase();
+    /// insert some sample data
+    myCTK.initializeDatabase(argv[2]);
+    myCTK.closeDatabase();
+    }
+  else
+    { 
+    out << "ERROR: " ;
+    out << myCTK.GetLastError();
+    }
+  return EXIT_SUCCESS;
+}
+

+ 52 - 4
Libs/DICOM/Core/qCTKDCMTK.cxx

@@ -3,8 +3,13 @@
 #include "qCTKDCMTK.h"
 
 // Qt includes
+#include <QDebug>
 #include <QSqlDatabase>
 #include <QSqlError>
+#include <QSqlQuery>
+#include <QFile>
+#include <QStringList>
+
 #include <iostream>
 
 //----------------------------------------------------------------------------
@@ -12,6 +17,8 @@ class qCTKDCMTKPrivate: public qCTKPrivate<qCTKDCMTK>
 {
 public:
   qCTKDCMTKPrivate(); 
+  bool executeScript(const QString& script);
+
   QSqlDatabase  Database;
   QString       DatabaseFileName;
   QString       LastError;
@@ -32,15 +39,11 @@ qCTKDCMTK::qCTKDCMTK(QObject* _parent): Superclass(_parent)
 }
 
 //----------------------------------------------------------------------------
-qCTKDCMTK::
 qCTKDCMTK::~qCTKDCMTK()
 {
 }
 
 //----------------------------------------------------------------------------
-QCTK_SET_CXX(qCTKDCMTK, const QString&, setDatabaseFileName, DatabaseFileName);
-
-//----------------------------------------------------------------------------
 bool qCTKDCMTK::openDatabase(const QString& databaseFileName) 
 {
   QCTK_D(qCTKDCMTK);
@@ -51,10 +54,55 @@ bool qCTKDCMTK::openDatabase(const QString& databaseFileName)
     d->LastError = d->Database.lastError().text();
     return false;
     }
+  if ( d->Database.tables().empty() ) 
+    {
+    initializeDatabase();
+    }
   return true;
 }
 const QString& qCTKDCMTK::GetLastError() const {
   QCTK_D(const qCTKDCMTK);
   return d->LastError; 
 }
+const QSqlDatabase& qCTKDCMTK::database() const {
+  QCTK_D(const qCTKDCMTK);
+  return d->Database;
+}
+
+bool qCTKDCMTKPrivate::executeScript(const QString& script) {
+  QFile scriptFile(script);
+  scriptFile.open(QIODevice::ReadOnly);
+  QString sqlCommands( QTextStream(&scriptFile).readAll() );
+  sqlCommands.replace( '\n', ' ' );
+  sqlCommands.replace("; ", ";\n");
+
+  QStringList sqlCommandsLines = sqlCommands.split('\n');
+
+  QSqlQuery query(Database);
+
+  for (QStringList::iterator it = sqlCommandsLines.begin(); it != sqlCommandsLines.end()-1; ++it)
+  {
+    if (! (*it).startsWith("--") )
+      {
+      query.exec(*it);
+      if (query.lastError().type())
+        {
+        qDebug() << "There was an error during execution of the statement: " << (*it);
+        return false;
+        }
+      }
+  }
+  return true;
+}
 
+bool qCTKDCMTK::initializeDatabase(const char* sqlFileName) 
+{
+  QCTK_D(qCTKDCMTK);
+  return d->executeScript(sqlFileName);
+}
+  
+void qCTKDCMTK::closeDatabase()
+{
+  QCTK_D(qCTKDCMTK);
+  d->Database.close();
+}

+ 13 - 2
Libs/DICOM/Core/qCTKDCMTK.h

@@ -3,6 +3,7 @@
 
 // QT includes 
 #include <QObject>
+#include <QSqlDatabase>
 
 // qCTK includes
 #include <qCTKPimpl.h>
@@ -18,11 +19,21 @@ public:
   explicit qCTKDCMTK(QObject* parent = 0);
   virtual ~qCTKDCMTK();
   
-  /// 
   ///
-  void setDatabaseFileName(const QString& file);
+  /// open the SQLite database in @param file. If the file does not
+  /// exist, a new database is created and initialized with the
+  /// default schema
   virtual bool openDatabase(const QString& file);
+
+  const QSqlDatabase& database() const;
   const QString& GetLastError() const; 
+  
+  ///
+  /// close the database. It must not be used afterwards.
+  void closeDatabase();  
+  ///
+  /// delete all data and reinitialize the database.
+  bool initializeDatabase(const char* schemaFile = ":/dicom/dicom-schema.sql");
 private:
   QCTK_DECLARE_PRIVATE(qCTKDCMTK);
 };

+ 523 - 0
Libs/DICOM/Core/qCTKDCMTKModel.cxx

@@ -0,0 +1,523 @@
+#include "qCTKDCMTKModel.h"
+
+#include <QSqlQueryModel>
+#include <QStringList>
+
+struct Node
+{
+  Node* Parent;
+  int   Row;
+  int   Column;
+};
+
+class qCTKDCMTKModelPrivate:public qCTKPrivate<qCTKDCMTKModel>
+{
+public:
+  qCTKDCMTKModelPrivate();
+  ~qCTKDCMTKModelPrivate();
+  void init();
+
+  enum IndexType{
+    RootType,
+    PatientType,
+    StudyType,
+    SeriesType,
+    ImageType
+  };
+  IndexType indexType(const QModelIndex& index)const;
+
+  void updateRootModel(const QModelIndex& index);
+  void updatePatientModel(const QModelIndex& index);
+  void updateStudyModel(const QModelIndex& index);
+  void updateSeriesModel(const QModelIndex& index);
+
+  QModelIndex indexInRootQuery(const QModelIndex& index)const;
+  QModelIndex indexInPatientQuery(const QModelIndex& index)const;
+  QModelIndex indexInStudyQuery(const QModelIndex& index)const;
+  QModelIndex indexInSeriesQuery(const QModelIndex& index)const;
+  
+  QSqlDatabase    DataBase;
+  QSqlQueryModel* RootModel;
+  QSqlQueryModel* PatientModel;
+  QSqlQueryModel* StudyModel;
+  QSqlQueryModel* SeriesModel;
+
+  Node*           RootNode;
+  Node*           PatientNode;
+  Node*           StudyNode;
+  Node*           SeriesNode;
+  mutable QList<Node*>    Nodes;
+};
+
+qCTKDCMTKModelPrivate::qCTKDCMTKModelPrivate()
+  :DataBase(QSqlDatabase::addDatabase("QSQLITE"))
+{
+  this->RootModel    = 0;
+  this->PatientModel = 0;
+  this->StudyModel   = 0;
+  this->SeriesModel  = 0;
+  this->RootNode     = 0;
+  this->PatientNode  = 0;
+  this->StudyNode    = 0;
+  this->SeriesNode   = 0;
+}
+
+qCTKDCMTKModelPrivate::~qCTKDCMTKModelPrivate()
+{
+  foreach(Node* node, this->Nodes)
+    {
+    delete node;
+    }
+  this->Nodes.clear();
+
+}
+
+void qCTKDCMTKModelPrivate::init()
+{
+  QCTK_P(qCTKDCMTKModel);
+  this->RootModel = new QSqlQueryModel(p);
+  this->PatientModel = new QSqlQueryModel(p);
+  this->StudyModel = new QSqlQueryModel(p);
+  this->SeriesModel = new QSqlQueryModel(p);
+
+  QObject::connect(this->RootModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)),
+          p, SLOT(rootRowsAboutToBeInserted(const QModelIndex&, int, int)));
+  QObject::connect(this->PatientModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)),
+          p, SLOT(patientRowsAboutToBeInserted(const QModelIndex&, int, int)));
+  QObject::connect(this->StudyModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)),
+          p, SLOT(studyRowsAboutToBeInserted(const QModelIndex&, int, int)));
+  QObject::connect(this->SeriesModel, SIGNAL(rowsAboutToBeInserted(const QModelIndex&, int, int)),
+          p, SLOT(seriesRowsAboutToBeInserted(const QModelIndex&, int, int)));
+
+  QObject::connect(this->RootModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
+          p, SLOT(rootRowsInserted(const QModelIndex&, int, int)));
+  QObject::connect(this->PatientModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
+          p, SLOT(patientRowsInserted(const QModelIndex&, int, int)));
+  QObject::connect(this->StudyModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
+          p, SLOT(studyRowsInserted(const QModelIndex&, int, int)));
+  QObject::connect(this->SeriesModel, SIGNAL(rowsInserted(const QModelIndex&, int, int)),
+          p, SLOT(seriesRowsInserted(const QModelIndex&, int, int)));
+
+  QObject::connect(this->RootModel, SIGNAL(modelAboutToBeReset()),
+          p, SLOT(onModelAboutToBeReset()));
+  QObject::connect(this->PatientModel, SIGNAL(modelAboutToBeReset()),
+          p, SLOT(onModelAboutToBeReset()));
+  QObject::connect(this->StudyModel, SIGNAL(modelAboutToBeReset()),
+          p, SLOT(onModelAboutToBeReset()));
+  QObject::connect(this->SeriesModel, SIGNAL(modelAboutToBeReset()),
+          p, SLOT(onModelAboutToBeReset()));
+
+  QObject::connect(this->RootModel, SIGNAL(modelReset()),
+          p, SLOT(onModelReset()));
+  QObject::connect(this->PatientModel, SIGNAL(modelReset()),
+          p, SLOT(onModelReset()));
+  QObject::connect(this->StudyModel, SIGNAL(modelReset()),
+          p, SLOT(onModelReset()));
+  QObject::connect(this->SeriesModel, SIGNAL(modelReset()),
+          p, SLOT(onModelReset()));
+
+  QObject::connect(this->RootModel, SIGNAL(layoutAboutToBeChanged()),
+          p, SLOT(onLayoutAboutToBeChanged()));
+  QObject::connect(this->PatientModel, SIGNAL(layoutAboutToBeChanged()),
+          p, SLOT(onLayoutAboutToBeChanged()));
+  QObject::connect(this->StudyModel, SIGNAL(layoutAboutToBeChanged()),
+          p, SLOT(onLayoutAboutToBeChanged()));
+  QObject::connect(this->SeriesModel, SIGNAL(layoutAboutToBeChanged()),
+          p, SLOT(onLayoutAboutToBeChanged()));
+
+  QObject::connect(this->RootModel, SIGNAL(layoutChanged()),
+          p, SLOT(onLayoutChanged()));
+  QObject::connect(this->PatientModel, SIGNAL(layoutChanged()),
+          p, SLOT(onLayoutChanged()));
+  QObject::connect(this->StudyModel, SIGNAL(layoutChanged()),
+          p, SLOT(onLayoutChanged()));
+  QObject::connect(this->SeriesModel, SIGNAL(layoutChanged()),
+          p, SLOT(onLayoutChanged()));
+
+  this->RootNode = new Node;
+  this->RootNode->Parent = 0;
+  this->RootNode->Row = -1;
+  this->RootNode->Column = -1;
+  this->Nodes.append(this->RootNode);
+}
+
+qCTKDCMTKModelPrivate::IndexType qCTKDCMTKModelPrivate::indexType(const QModelIndex& index)const
+{
+  QCTK_P(const qCTKDCMTKModel);
+  if (!index.isValid())
+    {
+    return RootType;
+    }
+  QModelIndex indexParent = p->parent(index);
+  if (!indexParent.isValid())
+    {
+    return PatientType;
+    }
+  indexParent = p->parent(indexParent);
+  if (!indexParent.isValid())
+    {
+    return StudyType;
+    }
+  indexParent = p->parent(indexParent);
+  if (!indexParent.isValid())
+    {
+    return SeriesType;
+    }
+  Q_ASSERT(!p->parent(indexParent).isValid());
+  return ImageType;
+}
+
+QModelIndex qCTKDCMTKModelPrivate::indexInRootQuery(const QModelIndex& index) const
+{
+  return index;
+}
+
+QModelIndex qCTKDCMTKModelPrivate::indexInPatientQuery(const QModelIndex& index) const
+{
+  return index;
+}
+
+QModelIndex qCTKDCMTKModelPrivate::indexInStudyQuery(const QModelIndex& index) const
+{
+  return index;
+}
+
+QModelIndex qCTKDCMTKModelPrivate::indexInSeriesQuery(const QModelIndex& index) const
+{
+  return index;
+}
+
+void qCTKDCMTKModelPrivate::updateRootModel(const QModelIndex& index)
+{
+  this->RootModel->setQuery( "SELECT * FROM Patients", this->DataBase);
+}
+
+void qCTKDCMTKModelPrivate::updatePatientModel(const QModelIndex& index)
+{
+  QCTK_P(qCTKDCMTKModel);
+  this->PatientNode = reinterpret_cast<Node*>(index.internalPointer());
+  QString patientId = p->data(index).toString();
+  this->PatientModel->setQuery( QString("SELECT * FROM Studies WHERE PatientsUID='%1'").arg(patientId), this->DataBase);
+}
+
+void qCTKDCMTKModelPrivate::updateStudyModel(const QModelIndex& index)
+{
+  QCTK_P(qCTKDCMTKModel);
+  this->StudyNode = reinterpret_cast<Node*>(index.internalPointer());
+  QString studyId = p->data(index).toString();
+  this->StudyModel->setQuery( QString("SELECT * FROM Series WHERE StudyInstanceUID='%1'").arg(studyId), this->DataBase);
+}
+
+void qCTKDCMTKModelPrivate::updateSeriesModel(const QModelIndex& index)
+{
+  QCTK_P(qCTKDCMTKModel);
+  this->SeriesNode = reinterpret_cast<Node*>(index.internalPointer());
+  QString seriesId = p->data(index).toString();
+  this->SeriesModel->setQuery( QString("SELECT * FROM Images WHERE SeriesInstanceUID='%1'").arg(seriesId), this->DataBase);
+}
+
+qCTKDCMTKModel::qCTKDCMTKModel(QObject* parent)
+{
+}
+
+qCTKDCMTKModel::~qCTKDCMTKModel()
+{
+}
+
+bool qCTKDCMTKModel::canFetchMore ( const QModelIndex & parent ) const
+{
+  QCTK_D(const qCTKDCMTKModel);
+  switch(d->indexType(parent))
+    {
+    case qCTKDCMTKModelPrivate::RootType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateRootModel(parent);
+      return d->RootModel->canFetchMore();
+      break;
+    case qCTKDCMTKModelPrivate::PatientType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updatePatientModel(parent);
+      return d->PatientModel->canFetchMore();
+      break;
+    case qCTKDCMTKModelPrivate::StudyType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateStudyModel(parent);
+      return d->StudyModel->canFetchMore();
+      break;
+    case qCTKDCMTKModelPrivate::SeriesType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateSeriesModel(parent);
+      return d->SeriesModel->canFetchMore();
+      break;
+    case qCTKDCMTKModelPrivate::ImageType:
+    default:
+      break;
+    }
+  return false;
+}
+
+int qCTKDCMTKModel::columnCount ( const QModelIndex & _parent ) const
+{
+  Q_UNUSED(_parent);
+  return 8;
+}
+
+QVariant qCTKDCMTKModel::data ( const QModelIndex & index, int role ) const
+{
+  QCTK_D(const qCTKDCMTKModel);
+  QVariant res;
+  QModelIndex indexParent = this->parent(index);
+  switch(d->indexType(index))
+    {
+    default:
+    case qCTKDCMTKModelPrivate::RootType:
+      break;
+    case qCTKDCMTKModelPrivate::PatientType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateRootModel(indexParent);
+      res = d->RootModel->data(d->indexInRootQuery(index), role);
+      break;
+    case qCTKDCMTKModelPrivate::StudyType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updatePatientModel(indexParent);
+      res = d->PatientModel->data(d->indexInPatientQuery(index), role);
+      break;
+    case qCTKDCMTKModelPrivate::SeriesType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateStudyModel(indexParent);
+      res = d->StudyModel->data(d->indexInStudyQuery(index), role);
+      break;
+    case qCTKDCMTKModelPrivate::ImageType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateSeriesModel(indexParent);
+      res = d->SeriesModel->data(d->indexInSeriesQuery(index), role);
+      break;
+    }
+  return res;
+}
+
+void qCTKDCMTKModel::fetchMore ( const QModelIndex & parent )
+{
+  QCTK_D(qCTKDCMTKModel);
+  switch(d->indexType(parent))
+    {
+    case qCTKDCMTKModelPrivate::RootType:
+      d->updateRootModel(parent);
+      d->RootModel->fetchMore(d->indexInRootQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::PatientType:
+      d->updatePatientModel(parent);
+      d->PatientModel->fetchMore(d->indexInPatientQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::StudyType:
+      d->updateStudyModel(parent);
+      d->StudyModel->fetchMore(d->indexInStudyQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::SeriesType:
+      d->updateSeriesModel(parent);
+      d->SeriesModel->fetchMore(d->indexInSeriesQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::ImageType:
+    default:
+      break;
+    }
+}
+
+Qt::ItemFlags qCTKDCMTKModel::flags ( const QModelIndex & index ) const
+{
+  return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+}
+
+bool qCTKDCMTKModel::hasChildren ( const QModelIndex & parent ) const
+{
+  QCTK_D(const qCTKDCMTKModel);
+  switch(d->indexType(parent))
+    {
+    case qCTKDCMTKModelPrivate::RootType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateRootModel(parent);
+      return d->RootModel->rowCount(d->indexInRootQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::PatientType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updatePatientModel(parent);
+      return d->PatientModel->rowCount(d->indexInPatientQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::StudyType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateStudyModel(parent);
+      return d->StudyModel->rowCount(d->indexInStudyQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::SeriesType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateSeriesModel(parent);
+      return d->SeriesModel->rowCount(d->indexInSeriesQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::ImageType:
+    default:
+      break;
+    }
+  return false;
+}
+
+QModelIndex qCTKDCMTKModel::index ( int row, int column, const QModelIndex & parent ) const
+{
+  QCTK_D(const qCTKDCMTKModel);
+  QSqlQueryModel* res = 0;
+  switch(d->indexType(parent))
+    {
+    case qCTKDCMTKModelPrivate::RootType:
+      res = d->RootModel;
+      break;
+    case qCTKDCMTKModelPrivate::PatientType:
+      res = d->PatientModel;
+      break;
+    case qCTKDCMTKModelPrivate::StudyType:
+      res = d->StudyModel;
+      break;
+    case qCTKDCMTKModelPrivate::SeriesType:
+      res = d->SeriesModel;
+      break;
+    case qCTKDCMTKModelPrivate::ImageType:
+    default:
+      Q_ASSERT(d->indexType(parent) != qCTKDCMTKModelPrivate::ImageType);
+      break;
+    }
+  Node* parentNode = 
+    reinterpret_cast<Node*>(parent.internalPointer());
+  Node* node = 0;
+  foreach(Node* tmpNode, d->Nodes)
+    {
+    if (tmpNode->Parent == parentNode &&
+        tmpNode->Row == row && 
+        tmpNode->Column == column)
+      {
+      node = tmpNode;
+      break;
+      }
+    }
+  if ( node == 0)
+    {
+    node = new Node;
+    node->Parent = parentNode;
+    node->Row = row;
+    node->Column = column;
+    d->Nodes.append(node);
+    }
+  return this->createIndex(row, column, node);
+}
+
+QModelIndex qCTKDCMTKModel::parent ( const QModelIndex & index ) const
+{
+  Node* node = 
+    reinterpret_cast<Node*>(index.internalPointer());
+  if (node == 0 || node->Parent == 0)
+    {
+    return this->createIndex(-1, -1, 0);
+    }
+  return this->createIndex(node->Parent->Row, node->Parent->Column, node->Parent);
+}
+
+int qCTKDCMTKModel::rowCount ( const QModelIndex & parent ) const
+{
+  QCTK_D(const qCTKDCMTKModel);
+  int res = 0;
+  switch(d->indexType(parent))
+    {
+    default:
+    case qCTKDCMTKModelPrivate::RootType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateRootModel(parent);
+      res = d->RootModel->rowCount(d->indexInRootQuery(parent));
+      break;
+      break;
+    case qCTKDCMTKModelPrivate::PatientType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updatePatientModel(parent);
+      res = d->PatientModel->rowCount(d->indexInPatientQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::StudyType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateStudyModel(parent);
+      res = d->StudyModel->rowCount(d->indexInStudyQuery(parent));
+      break;
+    case qCTKDCMTKModelPrivate::SeriesType:
+      const_cast<qCTKDCMTKModelPrivate*>(d)->updateSeriesModel(parent);
+      res = d->SeriesModel->rowCount(d->indexInSeriesQuery(parent));
+      break;
+    }
+  return res;
+}
+
+void qCTKDCMTKModel::setDataBase(const QString &db)
+{
+  QCTK_D(qCTKDCMTKModel);
+
+  this->beginResetModel();
+  d->DataBase.setDatabaseName(db);
+  this->endResetModel();
+  if (!d->DataBase.open() || d->DataBase.tables().empty())
+    {
+    //Q_ASSERT(d->DataBase.isOpen());
+    return;
+    }
+  //this->m_DbPath = db;
+  //this->LoadStudies();
+}
+
+void qCTKDCMTKModel::rootRowsAboutToBeInserted(const QModelIndex& rootParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  QModelIndex index = this->createIndex(rootParent.row(), rootParent.column(), d->RootNode);
+  this->beginInsertRows(index, start, end);
+}
+
+void qCTKDCMTKModel::rootRowsInserted(const QModelIndex& rootParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  this->endInsertRows();
+}
+
+void qCTKDCMTKModel::patientRowsAboutToBeInserted(const QModelIndex& patientParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  QModelIndex index = this->createIndex(patientParent.row(), patientParent.column(), d->PatientNode);
+  this->beginInsertRows(index, start, end);
+}
+
+void qCTKDCMTKModel::patientRowsInserted(const QModelIndex& patientParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  this->endInsertRows();
+}
+
+void qCTKDCMTKModel::studyRowsAboutToBeInserted(const QModelIndex& studyParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  QModelIndex index = this->createIndex(studyParent.row(), studyParent.column(), d->StudyNode);
+  this->beginInsertRows(index, start, end);
+}
+
+void qCTKDCMTKModel::studyRowsInserted(const QModelIndex& studyParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  this->endInsertRows();
+}
+
+void qCTKDCMTKModel::seriesRowsAboutToBeInserted(const QModelIndex& seriesParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  QModelIndex index = this->createIndex(seriesParent.row(), seriesParent.column(), d->SeriesNode);
+  this->beginInsertRows(index, start, end);
+}
+
+void qCTKDCMTKModel::seriesRowsInserted(const QModelIndex& seriesParent, int start, int end)
+{
+  QCTK_D(qCTKDCMTKModel);
+  this->endInsertRows();
+}
+
+void qCTKDCMTKModel::onModelAboutToBeReset()
+{
+  this->beginResetModel();
+}
+
+void qCTKDCMTKModel::onModelReset()
+{
+  this->endResetModel();
+}
+
+void qCTKDCMTKModel::onLayoutAboutToBeChanged()
+{
+  emit layoutAboutToBeChanged();
+}
+
+void qCTKDCMTKModel::onLayoutChanged()
+{
+  emit layoutChanged();
+}

+ 51 - 0
Libs/DICOM/Core/qCTKDCMTKModel.h

@@ -0,0 +1,51 @@
+#ifndef __qCTKDCMTKModel_h
+#define __qCTKDCMTKModel_h
+
+// QT includes 
+#include <QAbstractItemModel>
+
+// qCTK includes
+#include <qCTKPimpl.h>
+
+#include "CTKDICOMCoreExport.h"
+
+class qCTKDCMTKModelPrivate;
+class Q_CTK_DICOM_CORE_EXPORT qCTKDCMTKModel : public QAbstractItemModel
+{
+  Q_OBJECT
+public:
+  explicit qCTKDCMTKModel(QObject* parent = 0);
+  virtual ~qCTKDCMTKModel();
+
+  void setDataBase(const QString& database);
+
+  virtual bool canFetchMore ( const QModelIndex & parent ) const;
+  virtual int columnCount ( const QModelIndex & parent = QModelIndex() ) const;
+  virtual QVariant data ( const QModelIndex & index, int role = Qt::DisplayRole ) const;
+  virtual void fetchMore ( const QModelIndex & parent );
+  virtual Qt::ItemFlags flags ( const QModelIndex & index ) const;
+  virtual bool hasChildren ( const QModelIndex & parent = QModelIndex() ) const;
+  //virtual QVariant headerData ( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const;
+  virtual QModelIndex index ( int row, int column, const QModelIndex & parent = QModelIndex() ) const;
+  virtual QModelIndex parent ( const QModelIndex & index ) const;
+  virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
+  //virtual bool setHeaderData ( int section, Qt::Orientation orientation, const QVariant & value, int role = Qt::EditRole );
+protected slots:
+  void rootRowsAboutToBeInserted(const QModelIndex& rootParent, int start, int end);
+  void rootRowsInserted(const QModelIndex& rootParent, int start, int end);
+  void patientRowsAboutToBeInserted(const QModelIndex& patientParent, int start, int end);
+  void patientRowsInserted(const QModelIndex& patientParent, int start, int end);
+  void studyRowsAboutToBeInserted(const QModelIndex& studyParent, int start, int end);
+  void studyRowsInserted(const QModelIndex& studyParent, int start, int end);
+  void seriesRowsAboutToBeInserted(const QModelIndex& seriesParent, int start, int end);
+  void seriesRowsInserted(const QModelIndex& seriesParent, int start, int end);
+  void onModelAboutToBeReset();
+  void onModelReset();
+  void onLayoutAboutToBeChanged();
+  void onLayoutChanged();
+
+private:
+  QCTK_DECLARE_PRIVATE(qCTKDCMTKModel);
+};
+
+#endif

+ 9 - 0
Libs/DICOM/Core/target_libraries.cmake

@@ -0,0 +1,9 @@
+#
+# See CMake/ctkMacroGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK libraries
+# 
+
+SET(target_libraries
+  CTKCore
+  )

文件差異過大導致無法顯示
+ 0 - 2257
Libs/DICOM/Resources/dicom-sample.sql


+ 0 - 47
Libs/DICOM/Resources/dicom-schema.sql

@@ -1,50 +0,0 @@
-
-BEGIN TRANSACTION;
-DROP TABLE IF EXISTS 'Images' ;
-DROP TABLE IF EXISTS 'Patients' ;
-DROP TABLE IF EXISTS 'Series' ;
-DROP TABLE IF EXISTS 'Studies' ;
-
-CREATE TABLE 'Images' (
-  'Filename' VARCHAR(1024) NOT NULL ,
-  'SeriesInstanceUID' VARCHAR(255) NOT NULL ,
-  PRIMARY KEY ('Filename') );
-CREATE TABLE 'Patients' (
-  'UID' INTEGER PRIMARY KEY AUTOINCREMENT,
-  'PatientsName' VARCHAR(255) NULL ,
-  'PatientID' VARCHAR(255) NULL ,
-  'PatientsBirthDate' DATE NULL ,
-  'PatientsBirthTime' TIME NULL ,
-  'PatientsSex' varchar(1) NULL ,
-  'PatientsComments' VARCHAR(255) NULL );
-CREATE TABLE 'Series' (
-  'SeriesInstanceUID' VARCHAR(255) NOT NULL ,
-  'StudyInstanceUID' VARCHAR(45) NOT NULL ,
-  'SeriesNumber' INT NULL ,
-  'SeriesDate' DATE NULL ,
-  'SeriesTime' VARCHAR(20) NULL ,
-  'SeriesDescription' VARCHAR(255) NULL ,
-  'BodyPartExamined' VARCHAR(255) NULL ,
-  'FrameOfReferenceUID' VARCHAR(255) NULL ,
-  'AcquisitionNumber' INT NULL ,
-  'ContrastAgent' VARCHAR(255) NULL ,
-  'ScanningSequence' VARCHAR(45) NULL ,
-  'EchoNumber' INT NULL ,
-  'TemporalPosition' INT NULL ,
-  PRIMARY KEY ('SeriesInstanceUID') );
-CREATE TABLE 'Studies' (
-  'StudyInstanceUID' VARCHAR(255) NOT NULL ,
-  'PatientsUID' INT NOT NULL ,
-  'StudyID' VARCHAR(255) NULL ,
-  'StudyDate' DATE NULL ,
-  'StudyTime' VARCHAR(20) NULL ,
-  'AccessionNumber' VARCHAR(255) NULL ,
-  'ModalitiesInStudy' VARCHAR(255) NULL ,
-  'ReferringPhysician' VARCHAR(255) NULL ,
-  'StudyDescription' VARCHAR(255) NULL ,
-  PRIMARY KEY ('StudyInstanceUID') );
-COMMIT;
-

+ 5 - 7
Libs/DICOM/Widgets/CMakeLists.txt

@@ -35,13 +35,11 @@ SET(KIT_UI_FORMS
 SET(KIT_resources
 )
 
-# Additional Target libraries
-SET(KIT_target_libraries
-  CTKCore
-  CTKDICOMCore
-  )
-
-ctk_build_qtlib(
+# Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
+ctkMacroGetTargetLibraries(KIT_target_libraries)
+  
+# See CMake/ctkMacroBuildQtLib.cmake
+ctkMacroBuildQtLib(
   NAME ${PROJECT_NAME}
   EXPORT_DIRECTIVE ${KIT_export_directive}
   INCLUDE_DIRECTORIES ${KIT_include_directories}

+ 10 - 0
Libs/DICOM/Widgets/target_libraries.cmake

@@ -0,0 +1,10 @@
+#
+# See CMake/ctkMacroGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK libraries
+# 
+
+SET(target_libraries
+  CTKCore
+  CTKDICOMCore
+  )

+ 7 - 5
Libs/Widgets/CMakeLists.txt

@@ -29,12 +29,11 @@ SET(KIT_UI_FORMS
 SET(KIT_resources
 )
 
-# Additional Target libraries
-SET(KIT_target_libraries
-  CTKCore
-  )
+# Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
+ctkMacroGetTargetLibraries(KIT_target_libraries)
 
-ctk_build_qtlib(
+# See CMake/ctkMacroBuildQtLib.cmake
+ctkMacroBuildQtLib(
   NAME ${PROJECT_NAME}
   EXPORT_DIRECTIVE ${KIT_export_directive}
   INCLUDE_DIRECTORIES ${KIT_include_directories}
@@ -53,3 +52,6 @@ ctk_build_qtlib(
 IF(BUILD_TESTING)
   #ADD_SUBDIRECTORY(Testing)
 ENDIF(BUILD_TESTING)
+# ADD_EXECUTABLE(MyMain dummyMain.cpp)
+# TARGET_LINK_LIBRARIES(MyMain ${PROJECT_NAME})
+

+ 9 - 0
Libs/Widgets/target_libraries.cmake

@@ -0,0 +1,9 @@
+#
+# See CMake/ctkMacroGetTargetLibraries.cmake
+# 
+# This file should list the libraries required to build the current CTK libraries
+#
+
+SET(target_libraries
+  CTKCore
+  )

+ 0 - 6
SuperBuild.cmake

@@ -1,12 +1,6 @@
 SET(cmake_version_required "2.8")
-SET(cmake_version_required_regex "2.8.*")
 SET(cmake_version_required_dash "2-8")
 
-IF(NOT CMAKE_VERSION MATCHES "${cmake_version_required_regex}")
-  SET(err "error: CTK SuperBuild requires CMake version ${cmake_version_required}")
-  MESSAGE(FATAL_ERROR "${err}")
-ENDIF()
-
 CMAKE_MINIMUM_REQUIRED(VERSION ${cmake_version_required})
 
 #