Bläddra i källkod

ENH: DAH: Added QtSOAP as external project.

Experimental code for the hosting part.
Sascha Zelzer 14 år sedan
förälder
incheckning
3d45c635e4
25 ändrade filer med 908 tillägg och 14 borttagningar
  1. 6 6
      Applications/ctkCLIPluginExplorer/ctkCLIPluginExplorerMain.cpp
  2. 3 2
      CMake/ctkMacroSetupQt.cmake
  3. 13 5
      CMakeExternals/QtSOAP.cmake
  4. 8 0
      Plugins/org.commontk.dicom.wg23.app/CMakeLists.txt
  5. 129 0
      Plugins/org.commontk.dicom.wg23.app/ctkDicomHostInterfaceImpl.cpp
  6. 54 0
      Plugins/org.commontk.dicom.wg23.app/ctkDicomHostInterfaceImpl_p.h
  7. 9 0
      Plugins/org.commontk.dicom.wg23.app/ctkDicomWG23AppPlugin.cpp
  8. 3 0
      Plugins/org.commontk.dicom.wg23.app/ctkDicomWG23AppPlugin_p.h
  9. 20 0
      Plugins/org.commontk.dicom.wg23.core/CMakeLists.txt
  10. 49 0
      Plugins/org.commontk.dicom.wg23.core/ctkDicomAppInterface.h
  11. 51 0
      Plugins/org.commontk.dicom.wg23.core/ctkDicomHostInterface.h
  12. 52 0
      Plugins/org.commontk.dicom.wg23.core/ctkDicomWG23Types.h
  13. 43 0
      Plugins/org.commontk.dicom.wg23.core/ctkSimpleSoapServer.cpp
  14. 52 0
      Plugins/org.commontk.dicom.wg23.core/ctkSimpleSoapServer.h
  15. 109 0
      Plugins/org.commontk.dicom.wg23.core/ctkSoapConnectionRunnable.cpp
  16. 54 0
      Plugins/org.commontk.dicom.wg23.core/ctkSoapConnectionRunnable_p.h
  17. 2 1
      Plugins/org.commontk.dicom.wg23.core/target_libraries.cmake
  18. 3 0
      Plugins/org.commontk.dicom.wg23.host/CMakeLists.txt
  19. 31 0
      Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServer.cpp
  20. 41 0
      Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServer.h
  21. 87 0
      Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServerPrivate.cpp
  22. 56 0
      Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServerPrivate.h
  23. 1 0
      SuperBuild.cmake
  24. 13 0
      Utilities/QtSOAP/BuildScript.cmake.in
  25. 19 0
      Utilities/QtSOAP/InstallScript.cmake.in

+ 6 - 6
Applications/ctkCLIPluginExplorer/ctkCLIPluginExplorerMain.cpp

@@ -24,19 +24,19 @@
 #include <QDebug>
 
 // CTK includes
-#include <ctkPluginManager.h>
+//#include <ctkPluginManager.h>
 
 int main(int argc, char** argv)
 {
   QCoreApplication app(argc, argv);
 
-  ctkPluginManager pluginManager;
-  pluginManager.addSearchPath("/home/sascha/git/CTK-bin/CTK-build/bin/Plugins");
-  pluginManager.startAllPlugins();
+//  ctkPluginManager pluginManager;
+//  pluginManager.addSearchPath("/home/sascha/git/CTK-bin/CTK-build/bin/Plugins");
+//  pluginManager.startAllPlugins();
 
-  qDebug() << "List of services: " <<  pluginManager.serviceManager()->findServices();
+//  qDebug() << "List of services: " <<  pluginManager.serviceManager()->findServices();
 
-  QObject* service = pluginManager.serviceManager()->loadInterface("org.commontk.cli.ICLIManager");
+//  QObject* service = pluginManager.serviceManager()->loadInterface("org.commontk.cli.ICLIManager");
 
   return 0;
 }

+ 3 - 2
CMake/ctkMacroSetupQt.cmake

@@ -39,14 +39,15 @@ MACRO(ctkMacroSetupQt)
 
     SET(QT_USE_QTNETWORK ON)
     SET(QT_USE_QTSQL ON)
-	SET(QT_USE_QTOPENGL ON)
+    SET(QT_USE_QTOPENGL ON)
+    SET(QT_USE_QTXML ON)
     SET(QT_USE_QTTEST ${BUILD_TESTING})
     INCLUDE(${QT_USE_FILE})
 
     # Set variable QT_INSTALLED_LIBRARY_DIR that will contains
     # Qt shared library
     SET(QT_INSTALLED_LIBRARY_DIR ${QT_LIBRARY_DIR})
-    IF (WIN32)
+    IF(WIN32)
       GET_FILENAME_COMPONENT(QT_INSTALLED_LIBRARY_DIR ${QT_QMAKE_EXECUTABLE} PATH)
     ENDIF()
 

+ 13 - 5
CMakeExternals/QtSOAP.cmake

@@ -3,11 +3,11 @@
 #
 
 SET(QtSOAP_DEPENDS)
-ctkMacroShouldAddExternalProject(QTSOAP_LIBRARIES add_project)
+ctkMacroShouldAddExternalProject(QTSOAP_LIBRARY add_project)
 IF(${add_project})
   
   SET(proj QtSOAP)
-#  MESSAGE(STATUS "Adding project:${proj}")
+  MESSAGE(STATUS "Adding project:${proj}")
   SET(QtSOAP_DEPENDS ${proj})
 
   IF(WIN32)
@@ -22,17 +22,25 @@ IF(${add_project})
   ENDIF()
 
   SET(_qtsoap_patch_script "${CTK_BINARY_DIR}/Utilities/QtSOAP/AcceptLicense.cmake")
-  CONFIGURE_FILE("${CTK_SOURCE_DIR}/Utilities/QtSOAP/AcceptLicense.cmake.in" ${_qtsoap_patch_script})
+  CONFIGURE_FILE("${CTK_SOURCE_DIR}/Utilities/QtSOAP/AcceptLicense.cmake.in" ${_qtsoap_patch_script} @ONLY)
+
+  SET(_qtsoap_build_script "${CTK_BINARY_DIR}/Utilities/QtSOAP/BuildScript.cmake")
+  CONFIGURE_FILE("${CTK_SOURCE_DIR}/Utilities/QtSOAP/BuildScript.cmake.in" ${_qtsoap_build_script} @ONLY)
+
+  SET(_qtsoap_install_script "${CTK_BINARY_DIR}/Utilities/QtSOAP/InstallScript.cmake")
+  CONFIGURE_FILE("${CTK_SOURCE_DIR}/Utilities/QtSOAP/InstallScript.cmake.in" ${_qtsoap_install_script} @ONLY)
 
   ExternalProject_Add(${proj}
     URL ${_qtsoap_url}
     PATCH_COMMAND ${CMAKE_COMMAND} -P ${_qtsoap_patch_script}
     CONFIGURE_COMMAND <SOURCE_DIR>/configure -library
     BUILD_IN_SOURCE 1
-    BUILD_COMMAND ${QT_QMAKE_EXECUTABLE}
-    INSTALL_COMMAND ${_make_cmd} # misuse the install step for second build command
+    BUILD_COMMAND ${CMAKE_COMMAND} -P ${_qtsoap_build_script}
+    INSTALL_COMMAND ${CMAKE_COMMAND} -D INTERMEDIATE_DIRECTORY:STRING=$(IntDir) -P ${_qtsoap_install_script}
   )
 
+  SET(QtSOAP_DIR "${CTK_BINARY_DIR}/Utilities/QtSOAP/")
+
   # Since the full path of PythonQt library is used, there is not need to add 
   # its corresponding library output directory to CTK_EXTERNAL_LIBRARY_DIRS
     

+ 8 - 0
Plugins/org.commontk.dicom.wg23.app/CMakeLists.txt

@@ -1,13 +1,20 @@
 PROJECT(org_commontk_dicom_wg23_app)
 
+FIND_PACKAGE(QtSOAP)
+IF(NOT QtSOAP_FOUND)
+  MESSAGE(FATAL_ERROR "error: QtSOAP package is required to build ${PROJECT_NAME}" )
+ENDIF()
+
 SET(PLUGIN_export_directive "org_commontk_dicom_wg23_app_EXPORT")
 
 SET(PLUGIN_SRCS
+  ctkDicomHostInterfaceImpl.cpp
   ctkDicomWG23AppPlugin.cpp
 )
 
 # Files which should be processed by Qts moc
 SET(PLUGIN_MOC_SRCS
+  ctkDicomHostInterfaceImpl_p.h
   ctkDicomWG23AppPlugin_p.h
 )
 
@@ -24,6 +31,7 @@ ctkMacroGetTargetLibraries(PLUGIN_target_libraries)
 
 ctkMacroBuildPlugin(
   NAME ${PROJECT_NAME}
+  INCLUDE_DIRECTORIES ${QTSOAP_INCLUDE_DIR}
   EXPORT_DIRECTIVE ${PLUGIN_export_directive}
   SRCS ${PLUGIN_SRCS}
   MOC_SRCS ${PLUGIN_MOC_SRCS}

+ 129 - 0
Plugins/org.commontk.dicom.wg23.app/ctkDicomHostInterfaceImpl.cpp

@@ -0,0 +1,129 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 "ctkDicomHostInterfaceImpl_p.h"
+
+#include <QApplication>
+#include <QCursor>
+#include <QNetworkReply>
+
+#include <stdexcept>
+
+ctkDicomHostInterfaceImpl::ctkDicomHostInterfaceImpl()
+{
+  connect(&http, SIGNAL(responseReady()), this, SLOT(responseReady()));
+
+  http.setHost("127.0.0.1", false, 8080);
+}
+
+void ctkDicomHostInterfaceImpl::responseReady()
+{
+  blockingLoop.exit();
+}
+
+QString ctkDicomHostInterfaceImpl::generateUID()
+{
+  return QString();
+}
+
+QRect ctkDicomHostInterfaceImpl::getAvailableScreen(const QRect& preferredScreen)
+{
+  http.setAction("GetAvailableScreen");
+
+  QtSoapMessage request;
+  request.setMethod("GetAvailableScreen");
+
+  QtSoapStruct* preferredScreenType = new QtSoapStruct(QtSoapQName("preferredScreen"));
+  preferredScreenType->insert(new QtSoapSimpleType(QtSoapQName("Height"), preferredScreen.height()));
+  preferredScreenType->insert(new QtSoapSimpleType(QtSoapQName("Width"), preferredScreen.width()));
+  preferredScreenType->insert(new QtSoapSimpleType(QtSoapQName("RefPointX"), preferredScreen.x()));
+  preferredScreenType->insert(new QtSoapSimpleType(QtSoapQName("RefPointY"), preferredScreen.y()));
+
+  request.addMethodArgument(preferredScreenType);
+
+  http.submitRequest(request, "/IHostService");
+
+  qDebug() << "Submitted request GetAvailableScreen";
+
+  QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
+
+  blockingLoop.exec(QEventLoop::ExcludeUserInputEvents | QEventLoop::WaitForMoreEvents);
+
+  QApplication::restoreOverrideCursor();
+
+  //qDebug() << "Reply error: " << reply->errorString();
+  //qDebug() << reply->readAll();
+  const QtSoapMessage& response = http.getResponse();
+
+  if (response.isFault())
+  {
+    throw std::runtime_error("server error");
+  }
+
+  qDebug() << "Response: " << response.toXmlString();
+
+  const QtSoapType &meth = response.method();
+
+  if (!meth.isValid() || meth.type() != QtSoapType::Struct)
+    qDebug() << "SOAP returning NIL: invalid or type != Struct";
+
+  const QtSoapStruct &m = dynamic_cast<const QtSoapStruct &>(meth);
+  if (m.count() == 0)
+    qDebug() << "SOAP returning NIL: count == 0";
+
+
+  const QtSoapType& screenResult = response.returnValue();
+  if (!screenResult.isValid())
+  {
+    //throw std::runtime_error("invalid return value");
+    qDebug() << response.errorString() << response.faultString().toString();
+    qDebug() << response.toXmlString();
+    return QRect();
+  }
+
+  qDebug() << screenResult.count() << screenResult["Height"].typeName();
+  QRect resultRect;
+  resultRect.setHeight(screenResult["Height"].toInt());
+  resultRect.setWidth(screenResult["Width"].toInt());
+  resultRect.setX(screenResult["RefPointX"].toInt());
+  resultRect.setY(screenResult["RefPointY"].toInt());
+
+  qDebug() << "x:" << resultRect.x() << " y:" << resultRect.y();
+
+  return resultRect;
+}
+
+QString ctkDicomHostInterfaceImpl::getOutputLocation(const QStringList& preferredProtocols)
+{
+  Q_UNUSED(preferredProtocols)
+  return QString();
+}
+
+void ctkDicomHostInterfaceImpl::notifyStateChanged(State state)
+{
+  Q_UNUSED(state)
+}
+
+void ctkDicomHostInterfaceImpl::notifyStatus(const Status& status)
+{
+  Q_UNUSED(status)
+}

+ 54 - 0
Plugins/org.commontk.dicom.wg23.app/ctkDicomHostInterfaceImpl_p.h

@@ -0,0 +1,54 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 DICOMHOSTINTERFACEIMPL_P_H
+#define DICOMHOSTINTERFACEIMPL_P_H
+
+#include <ctkDicomHostInterface.h>
+
+#include <QEventLoop>
+#include <QtSoapHttpTransport>
+
+class ctkDicomHostInterfaceImpl : public ctkDicomHostInterface
+{
+  Q_OBJECT
+
+public:
+    ctkDicomHostInterfaceImpl();
+
+    virtual QString generateUID();
+    virtual QRect getAvailableScreen(const QRect& preferredScreen);
+    virtual QString getOutputLocation(const QStringList& preferredProtocols);
+    virtual void notifyStateChanged(State state);
+    virtual void notifyStatus(const Status& status);
+
+private slots:
+
+    void responseReady();
+
+private:
+
+    QEventLoop blockingLoop;
+    QtSoapHttpTransport http;
+};
+
+#endif // DICOMHOSTINTERFACEIMPL_P_H

+ 9 - 0
Plugins/org.commontk.dicom.wg23.app/ctkDicomWG23AppPlugin.cpp

@@ -21,6 +21,9 @@
 
 
 #include "ctkDicomWG23AppPlugin_p.h"
+
+#include <ctkDicomHostInterfaceImpl_p.h>
+
 #include <QtPlugin>
 
 ctkDicomWG23AppPlugin* ctkDicomWG23AppPlugin::instance = 0;
@@ -28,6 +31,7 @@ ctkDicomWG23AppPlugin* ctkDicomWG23AppPlugin::instance = 0;
 ctkDicomWG23AppPlugin::ctkDicomWG23AppPlugin()
   : context(0)
 {
+
 }
 
 ctkDicomWG23AppPlugin::~ctkDicomWG23AppPlugin()
@@ -39,11 +43,16 @@ void ctkDicomWG23AppPlugin::start(ctkPluginContext* context)
 {
   instance = this;
   this->context = context;
+
+  hostInterface = new ctkDicomHostInterfaceImpl();
+  context->registerService(QStringList("ctkDicomHostInterface"), hostInterface);
 }
 
 void ctkDicomWG23AppPlugin::stop(ctkPluginContext* context)
 {
   Q_UNUSED(context)
+
+  delete hostInterface;
 }
 
 ctkDicomWG23AppPlugin* ctkDicomWG23AppPlugin::getInstance()

+ 3 - 0
Plugins/org.commontk.dicom.wg23.app/ctkDicomWG23AppPlugin_p.h

@@ -25,6 +25,8 @@
 
 #include <ctkPluginActivator.h>
 
+class ctkDicomHostInterface;
+
 class ctkDicomWG23AppPlugin :
   public QObject, public ctkPluginActivator
 {
@@ -49,6 +51,7 @@ private:
   static ctkDicomWG23AppPlugin* instance;
   ctkPluginContext* context;
 
+  ctkDicomHostInterface* hostInterface;
 
 }; // ctkDicomWG23AppPlugin
 

+ 20 - 0
Plugins/org.commontk.dicom.wg23.core/CMakeLists.txt

@@ -1,14 +1,33 @@
 PROJECT(org_commontk_dicom_wg23_core)
 
+FIND_PACKAGE(QtSOAP)
+IF(NOT QtSOAP_FOUND)
+  MESSAGE(FATAL_ERROR "error: QtSOAP package is required to build ${PROJECT_NAME}" )
+ENDIF()
+
+# TODO: Fix this after discussing include dependencies with Jc
+SET(CTK_BASE_INCLUDE_DIRS ${CTK_BASE_INCLUDE_DIRS} ${QTSOAP_INCLUDE_DIR} CACHE INTERNAL "CTK includes" FORCE)
+
 SET(PLUGIN_export_directive "org_commontk_dicom_wg23_core_EXPORT")
 
+# Additional directories to include
+SET(PLUGIN_include_directories
+
+)
+
 SET(PLUGIN_SRCS
   ctkDicomWG23CorePlugin.cpp
+  ctkSimpleSoapServer.cpp
+  ctkSoapConnectionRunnable.cpp
 )
 
 # Files which should be processed by Qts moc
 SET(PLUGIN_MOC_SRCS
+  ctkDicomAppInterface.h
+  ctkDicomHostInterface.h
   ctkDicomWG23CorePlugin_p.h
+  ctkSimpleSoapServer.h
+  ctkSoapConnectionRunnable_p.h
 )
 
 # Qt Designer files which should be processed by Qts uic
@@ -25,6 +44,7 @@ ctkMacroGetTargetLibraries(PLUGIN_target_libraries)
 ctkMacroBuildPlugin(
   NAME ${PROJECT_NAME}
   EXPORT_DIRECTIVE ${PLUGIN_export_directive}
+  INCLUDE_DIRECTORIES ${PLUGIN_include_directories}
   SRCS ${PLUGIN_SRCS}
   MOC_SRCS ${PLUGIN_MOC_SRCS}
   UI_FORMS ${PLUGIN_UI_FORMS}

+ 49 - 0
Plugins/org.commontk.dicom.wg23.core/ctkDicomAppInterface.h

@@ -0,0 +1,49 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 CTKDICOMAPPINTERFACE_H
+#define CTKDICOMAPPINTERFACE_H
+
+#include <QObject>
+#include <QRect>
+
+#include "ctkDicomWG23Types.h"
+
+#include <org_commontk_dicom_wg23_core_Export.h>
+
+class org_commontk_dicom_wg23_core_EXPORT ctkDicomAppInterface : public QObject
+{
+  Q_OBJECT
+
+public:
+
+  // Application interface methods
+  virtual State getState() = 0;
+  virtual bool setState(State newState) = 0;
+  virtual bool bringToFront(const QRect& requestedScreenArea) = 0;
+
+  // Data exchange interface methods
+  // ...
+
+};
+
+#endif // CTKDICOMAPPINTERFACE_H

+ 51 - 0
Plugins/org.commontk.dicom.wg23.core/ctkDicomHostInterface.h

@@ -0,0 +1,51 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 CTKDICOMHOSTINTERFACE_H
+#define CTKDICOMHOSTINTERFACE_H
+
+#include <QObject>
+#include <QRect>
+
+#include "ctkDicomWG23Types.h"
+
+#include <org_commontk_dicom_wg23_core_Export.h>
+
+class org_commontk_dicom_wg23_core_EXPORT ctkDicomHostInterface : public QObject
+{
+  Q_OBJECT
+
+public:
+
+  // Host interface methods
+  virtual QString generateUID() = 0;
+  virtual QRect getAvailableScreen(const QRect& preferredScreen) = 0;
+  virtual QString getOutputLocation(const QStringList& preferredProtocols) = 0;
+  virtual void notifyStateChanged(State state) = 0;
+  virtual void notifyStatus(const Status& status) = 0;
+
+  // Data exchange interface methods
+  // ...
+
+};
+
+#endif // CTKDICOMHOSTINTERFACE_H

+ 52 - 0
Plugins/org.commontk.dicom.wg23.core/ctkDicomWG23Types.h

@@ -0,0 +1,52 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 CTKDICOMWG23TYPES_H
+#define CTKDICOMWG23TYPES_H
+
+namespace {
+
+  enum State {
+    IDLE,
+    INPROGRESS,
+    COMPLETED,
+    SUSPENDED,
+    CANCELED,
+    EXIT
+  };
+
+  enum StatusType {
+    INFORMATION,
+    WARNING,
+    ERROR,
+    FATALERROR
+  };
+
+  struct Status {
+    StatusType statusType;
+    QString codingSchemeDesignator;
+    QString codeValue;
+    QString codeMeaning;
+  };
+}
+
+#endif // CTKDICOMWG23TYPES_H

+ 43 - 0
Plugins/org.commontk.dicom.wg23.core/ctkSimpleSoapServer.cpp

@@ -0,0 +1,43 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 "ctkSimpleSoapServer.h"
+
+#include "ctkSoapConnectionRunnable_p.h"
+
+ctkSimpleSoapServer::ctkSimpleSoapServer(QObject *parent) :
+    QTcpServer(parent)
+{
+  qRegisterMetaType<QtSoapMessage>("QtSoapMessage");
+}
+
+void ctkSimpleSoapServer::incomingConnection(int socketDescriptor)
+{
+  qDebug() << "New incoming connection";
+  ctkSoapConnectionRunnable* runnable = new ctkSoapConnectionRunnable(socketDescriptor);
+
+  connect(runnable, SIGNAL(incomingSoapMessage(QtSoapMessage,QtSoapMessage*)),
+          this, SIGNAL(incomingSoapMessage(QtSoapMessage, QtSoapMessage*)),
+          Qt::BlockingQueuedConnection);
+
+  QThreadPool::globalInstance()->start(runnable);
+}

+ 52 - 0
Plugins/org.commontk.dicom.wg23.core/ctkSimpleSoapServer.h

@@ -0,0 +1,52 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 CTKSIMPLESOAPSERVER_H
+#define CTKSIMPLESOAPSERVER_H
+
+#include <QTcpServer>
+
+#include <qtsoap.h>
+
+#include <org_commontk_dicom_wg23_core_Export.h>
+
+class org_commontk_dicom_wg23_core_EXPORT ctkSimpleSoapServer : public QTcpServer
+{
+  Q_OBJECT
+
+public:
+
+  ctkSimpleSoapServer(QObject *parent = 0);
+
+signals:
+
+  void incomingSoapMessage(const QtSoapMessage& message, QtSoapMessage* reply);
+
+public slots:
+
+protected:
+
+  void incomingConnection(int socketDescriptor);
+
+};
+
+#endif // CTKSIMPLESOAPSERVER_H

+ 109 - 0
Plugins/org.commontk.dicom.wg23.core/ctkSoapConnectionRunnable.cpp

@@ -0,0 +1,109 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 "ctkSoapConnectionRunnable_p.h"
+
+#include <QTcpSocket>
+
+ctkSoapConnectionRunnable::ctkSoapConnectionRunnable(int socketDescriptor)
+  : socketDescriptor(socketDescriptor)
+{
+}
+
+ctkSoapConnectionRunnable::~ctkSoapConnectionRunnable()
+{
+
+}
+
+void ctkSoapConnectionRunnable::run()
+{
+  QTcpSocket tcpSocket;
+  if (!tcpSocket.setSocketDescriptor(socketDescriptor))
+  {
+    // error handling
+    return;
+  }
+
+
+  while (tcpSocket.state() == QTcpSocket::ConnectedState)
+  {
+    //const int timeout = 5 * 1000;
+
+    tcpSocket.waitForReadyRead(-1);
+
+    readClient(tcpSocket);
+  }
+}
+
+void ctkSoapConnectionRunnable::readClient(QTcpSocket& socket)
+{
+  //qDebug() << socket->readAll();
+  while (socket.canReadLine()) {
+    QString line = socket.readLine();
+    qDebug() << line;
+    if (line.trimmed().isEmpty())
+    {
+      // Read the http body, which contains the soap message
+      QByteArray body = socket.readAll();
+      qDebug() << body;
+
+      if (body.trimmed().isEmpty())
+      {
+        qDebug() << "Message body empty";
+        return;
+      }
+
+      QtSoapMessage msg;
+      if (!msg.setContent(body))
+      {
+        qDebug() << "QtSoap import failed:" << msg.errorString();
+        return;
+      }
+
+      QtSoapMessage reply;
+      emit incomingSoapMessage(msg, &reply);
+
+      if (reply.isFault())
+      {
+        qDebug() << "QtSoap reply faulty";
+        return;
+      }
+
+      qDebug() << "SOAP reply:";
+
+      QString soapContent = reply.toXmlString();
+
+      QByteArray block;
+      block.append("HTTP/1.1 200 OK\n");
+      block.append("Content-Type: text/xml;charset=utf-8\n");
+      block.append("Content-Length: ").append(QString::number(soapContent.size())).append("\n");
+      block.append("\n");
+
+      block.append(soapContent);
+
+      qDebug() << block;
+
+      socket.write(block);
+
+    }
+  }
+}

+ 54 - 0
Plugins/org.commontk.dicom.wg23.core/ctkSoapConnectionRunnable_p.h

@@ -0,0 +1,54 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 CTKSOAPCONNECTIONRUNNABLE_P_H
+#define CTKSOAPCONNECTIONRUNNABLE_P_H
+
+#include <QObject>
+#include <QRunnable>
+#include <QTcpSocket>
+
+#include <qtsoap.h>
+
+class ctkSoapConnectionRunnable : public QObject, public QRunnable
+{
+  Q_OBJECT
+
+public:
+
+  ctkSoapConnectionRunnable(int socketDescriptor);
+  ~ctkSoapConnectionRunnable();
+
+  void run();
+
+signals:
+
+  void incomingSoapMessage(const QtSoapMessage& message, QtSoapMessage* reply);
+
+private:
+
+  void readClient(QTcpSocket& socket);
+
+  int socketDescriptor;
+};
+
+#endif // CTKSOAPCONNECTIONRUNNABLE_P_H

+ 2 - 1
Plugins/org.commontk.dicom.wg23.core/target_libraries.cmake

@@ -6,5 +6,6 @@
 
 SET(target_libraries
   CTKPluginFramework
-  QTSOAP_LIBRARIES
+  QT_LIBRARIES
+  QTSOAP_LIBRARY
 )

+ 3 - 0
Plugins/org.commontk.dicom.wg23.host/CMakeLists.txt

@@ -3,11 +3,14 @@ PROJECT(org_commontk_dicom_wg23_host)
 SET(PLUGIN_export_directive "org_commontk_dicom_wg23_host_EXPORT")
 
 SET(PLUGIN_SRCS
+  ctkDicomHostServer.cpp
+  ctkDicomHostServerPrivate.cpp
   ctkDicomWG23HostPlugin.cpp
 )
 
 # Files which should be processed by Qts moc
 SET(PLUGIN_MOC_SRCS
+  ctkDicomHostServerPrivate.h
   ctkDicomWG23HostPlugin_p.h
 )
 

+ 31 - 0
Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServer.cpp

@@ -0,0 +1,31 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 "ctkDicomHostServer.h"
+
+#include "ctkDicomHostServerPrivate.h"
+
+ctkDicomHostServer::ctkDicomHostServer()
+  : d_ptr(new ctkDicomHostServerPrivate)
+{
+
+}

+ 41 - 0
Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServer.h

@@ -0,0 +1,41 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 CTKDICOMHOSTSERVER_H
+#define CTKDICOMHOSTSERVER_H
+
+#include <QScopedPointer>
+
+class ctkDicomHostServerPrivate;
+
+class ctkDicomHostServer
+{
+
+public:
+  ctkDicomHostServer();
+
+  Q_DECLARE_PRIVATE(ctkDicomHostServer)
+
+  const QScopedPointer<ctkDicomHostServerPrivate> d_ptr;
+};
+
+#endif // CTKDICOMHOSTSERVER_H

+ 87 - 0
Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServerPrivate.cpp

@@ -0,0 +1,87 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 "ctkDicomHostServerPrivate.h"
+
+#include "ctkDicomWG23HostPlugin_p.h"
+
+#include <ctkDicomHostInterface.h>
+
+#include <QHostAddress>
+
+#include <stdexcept>
+
+ctkDicomHostServerPrivate::ctkDicomHostServerPrivate(QObject *parent) :
+    QObject(parent)
+{
+  ctkPluginContext* context = ctkDicomWG23HostPlugin::getInstance()->getPluginContext();
+  ctkServiceReference* serviceRef = context->getServiceReference("ctkDicomHostInterface");
+  if (!serviceRef)
+  {
+    // this will change after mergin changes from branch plugin_framework
+    throw std::runtime_error("No Dicom Host Service found");
+  }
+
+  serviceBinding = qobject_cast<ctkDicomHostInterface*>(context->getService(serviceRef));
+
+  connect(&server, SIGNAL(incomingSoapMessage(QtSoapMessage,QtSoapMessage*)),
+          this, SLOT(incomingSoapMessage(QtSoapMessage,QtSoapMessage*)));
+
+  if (!server.listen(QHostAddress::LocalHost, 8080))
+  {
+    qCritical() << "Listening to 127.0.0.1:8080 failed.";
+  }
+}
+
+void ctkDicomHostServerPrivate::incomingSoapMessage(const QtSoapMessage& message,
+                                              QtSoapMessage* reply)
+{
+  const QtSoapType& method = message.method();
+  QString methodName = method.name().name();
+
+  qDebug() << "Received soap method request: " << methodName;
+
+  if (methodName == "GetAvailableScreen")
+  {
+    processGetAvailableScreen(message, reply);
+  }
+}
+
+void ctkDicomHostServerPrivate::processGetAvailableScreen(
+    const QtSoapMessage &message, QtSoapMessage *reply)
+{
+  const QtSoapType& preferredScreenType = message.method()["preferredScreen"];
+  QRect preferredScreen(preferredScreenType["RefPointX"].value().toInt(),
+                        preferredScreenType["RefPointY"].value().toInt(),
+                        preferredScreenType["Width"].value().toInt(),
+                        preferredScreenType["Height"].value().toInt());
+
+  QRect result = serviceBinding->getAvailableScreen(preferredScreen);
+
+  reply->setMethod("GetAvailableScreenResponse");
+  QtSoapStruct* availableScreenType = new QtSoapStruct(QtSoapQName("availableScreen"));
+  availableScreenType->insert(new QtSoapSimpleType(QtSoapQName("Height"), result.height()));
+  availableScreenType->insert(new QtSoapSimpleType(QtSoapQName("Width"), result.width()));
+  availableScreenType->insert(new QtSoapSimpleType(QtSoapQName("RefPointX"), result.x()));
+  availableScreenType->insert(new QtSoapSimpleType(QtSoapQName("RefPointY"), result.y()));
+  reply->addMethodArgument(availableScreenType);
+}

+ 56 - 0
Plugins/org.commontk.dicom.wg23.host/ctkDicomHostServerPrivate.h

@@ -0,0 +1,56 @@
+/*=============================================================================
+
+  Library: CTK
+
+  Copyright (c) 2010 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 CTKDICOMHOSTSERVERPRIVATE_H
+#define CTKDICOMHOSTSERVERPRIVATE_H
+
+#include <QObject>
+#include <QtSoapMessage>
+
+#include <ctkSimpleSoapServer.h>
+
+class ctkDicomHostInterface;
+
+class ctkDicomHostServerPrivate : public QObject
+{
+  Q_OBJECT
+
+public:
+  ctkDicomHostServerPrivate(QObject *parent = 0);
+
+  ctkSimpleSoapServer server;
+
+public slots:
+
+  void incomingSoapMessage(const QtSoapMessage& message,
+                           QtSoapMessage* reply);
+
+private:
+
+  void processGetAvailableScreen(const QtSoapMessage& message,
+                                 QtSoapMessage* reply);
+
+  ctkDicomHostInterface* serviceBinding;
+
+};
+
+#endif // CTKDICOMHOSTSERVERPRIVATE_H

+ 1 - 0
SuperBuild.cmake

@@ -236,6 +236,7 @@ ExternalProject_Add(${proj}
     -DPYTHONQT_INSTALL_DIR:PATH=${PYTHONQT_INSTALL_DIR} # FindPythonQt expects PYTHONQT_INSTALL_DIR variable to be defined
     -DPYTHONQTGENERATOR_EXECUTABLE:FILEPATH=${PYTHONQTGENERATOR_EXECUTABLE} #FindPythonQtGenerator expects PYTHONQTGENERATOR_EXECUTABLE to be defined
     -DLog4Qt_DIR:PATH=${Log4Qt_DIR} # FindLog4Qt expects Log4Qt_DIR variable to be defined
+    -DQtSOAP_DIR:PATH=${QtSOAP_DIR} # FindQtSOAP expects QtSOAP_DIR variable to be defined
   SOURCE_DIR ${CTK_SOURCE_DIR}
   BINARY_DIR ${CTK_BINARY_DIR}/CTK-build
   BUILD_COMMAND ""

+ 13 - 0
Utilities/QtSOAP/BuildScript.cmake.in

@@ -0,0 +1,13 @@
+set(work_dir @ep_source_dir@)
+set(proj_dir ${work_dir}/@proj@)
+
+EXECUTE_PROCESS(
+  COMMAND @QT_QMAKE_EXECUTABLE@
+  COMMAND @_make_cmd@
+  WORKING_DIRECTORY ${proj_dir}
+  ERROR_VARIABLE _error
+)
+
+IF(_error)
+  MESSAGE("${_error}")
+ENDIF()

+ 19 - 0
Utilities/QtSOAP/InstallScript.cmake.in

@@ -0,0 +1,19 @@
+set(work_dir @ep_source_dir@)
+set(proj_dir ${work_dir}/@proj@)
+
+SET(_int_dir )
+IF(INTERMEDIATE_DIRECTORY)
+  GET_FILENAME_COMPONENT(_int_dir ${INTERMEDIATE_DIRECTORY} NAME)
+ENDIF()
+
+FILE(GLOB _files "${proj_dir}/lib/*")
+FOREACH(_file ${_files})
+  CONFIGURE_FILE(${_file} "@CTK_CMAKE_LIBRARY_OUTPUT_DIRECTORY@/${_int_dir}/" COPYONLY)
+  MESSAGE("Copying ${_file} to @CTK_CMAKE_LIBRARY_OUTPUT_DIRECTORY@/${_int_dir}/")
+ENDFOREACH()
+
+
+SET(_qtsoap_config "FIND_LIBRARY(QTSOAP_LIBRARY QtSolutions_SOAP-2.7 \"@CTK_CMAKE_LIBRARY_OUTPUT_DIRECTORY@/${_int_dir}/\")
+SET(QTSOAP_INCLUDE_DIR \"${proj_dir}/src/\")")
+
+FILE(WRITE "@CTK_BINARY_DIR@/Utilities/QtSOAP/QtSOAPConfig.cmake" ${_qtsoap_config})