Parcourir la source

Added convenience and template methods for service registration.

The ctkPluginContext class now supports registering and retrieving a
service object by using its class type. This eliminates the explicit
usage of string ids for Qt interfaces.
Sascha Zelzer il y a 14 ans
Parent
commit
1b10137b58
31 fichiers modifiés avec 210 ajouts et 28 suppressions
  1. 1 0
      Applications/ctkExampleHost/ctkExampleHostMain.cpp
  2. 2 0
      Applications/ctkExampleHostedApp/ctkExampleHostedAppMain.cpp
  3. 1 13
      Applications/ctkPluginBrowser/ctkPluginBrowser.cpp
  4. 1 0
      Applications/ctkPluginBrowser/ctkPluginTableModel.h
  5. 1 0
      Applications/ctkPluginGenerator/ctkPluginGeneratorMain.cpp
  6. 4 1
      Libs/PluginFramework/Testing/Cpp/ctkPluginFrameworkTestMain.cpp
  7. 3 1
      Libs/PluginFramework/Testing/Cpp/ctkTestSuiteInterface.h
  8. 2 2
      Libs/PluginFramework/Testing/FrameworkTest/ctkPluginFrameworkTestActivator.cpp
  9. 3 3
      Libs/PluginFramework/Testing/FrameworkTest/ctkPluginFrameworkTestSuite.cpp
  10. 1 0
      Libs/PluginFramework/Testing/FrameworkTest/ctkPluginFrameworkTestSuite_p.h
  11. 1 0
      Libs/PluginFramework/Testing/FrameworkTest/ctkServiceListenerTestSuite_p.h
  12. 1 1
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA.cpp
  13. 4 0
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAService.h
  14. 1 0
      Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA_p.h
  15. 1 1
      Libs/PluginFramework/Testing/TestPlugins/pluginA_test/ctkTestPluginA.cpp
  16. 4 0
      Libs/PluginFramework/Testing/TestPlugins/pluginA_test/ctkTestPluginAService.h
  17. 1 0
      Libs/PluginFramework/Testing/TestPlugins/pluginA_test/ctkTestPluginA_p.h
  18. 1 1
      Libs/PluginFramework/Testing/TestPlugins/pluginSL1_test/ctkActivatorSL1.cpp
  19. 1 1
      Libs/PluginFramework/Testing/TestPlugins/pluginSL3_test/ctkActivatorSL3.cpp
  20. 1 1
      Libs/PluginFramework/Testing/TestPlugins/pluginSL4_test/ctkActivator.cpp
  21. 1 0
      Libs/PluginFramework/ctkLDAPSearchFilter.h
  22. 4 1
      Libs/PluginFramework/ctkPlugin.h
  23. 9 0
      Libs/PluginFramework/ctkPluginContext.cpp
  24. 117 2
      Libs/PluginFramework/ctkPluginContext.h
  25. 1 0
      Libs/PluginFramework/ctkPluginFrameworkPrivate.cpp
  26. 38 0
      Libs/PluginFramework/ctkPluginFramework_global.h
  27. 1 0
      Libs/PluginFramework/ctkPluginTracker.cpp
  28. 1 0
      Libs/PluginFramework/ctkServiceFactory.h
  29. 1 0
      Libs/PluginFramework/ctkServiceRegistrationPrivate.h
  30. 1 0
      Libs/PluginFramework/ctkServiceTracker.cpp
  31. 1 0
      Libs/PluginFramework/ctkServiceTrackerPrivate.cpp

+ 1 - 0
Applications/ctkExampleHost/ctkExampleHostMain.cpp

@@ -22,6 +22,7 @@
 #include <ctkPluginFrameworkFactory.h>
 #include <ctkPluginFramework.h>
 #include <ctkPluginException.h>
+#include <ctkPluginContext.h>
 
 #include <ctkExampleDicomHost.h>
 #include <ctkHostAppExampleWidget.h>

+ 2 - 0
Applications/ctkExampleHostedApp/ctkExampleHostedAppMain.cpp

@@ -22,6 +22,7 @@
 #include <ctkPluginFrameworkFactory.h>
 #include <ctkPluginFramework.h>
 #include <ctkPluginException.h>
+#include <ctkPluginContext.h>
 
 // for testing purposes use:
 // --hostURL http://localhost:8081/host --applicationURL http://localhost:8082/app dicomapp
@@ -33,6 +34,7 @@
 #include <QDirIterator>
 #include <QWidget>
 #include <QFileInfo>
+#include <QUrl>
 
 void print_usage()
 {

+ 1 - 13
Applications/ctkPluginBrowser/ctkPluginBrowser.cpp

@@ -32,6 +32,7 @@
 
 #include <ctkPluginException.h>
 #include <ctkPluginFramework.h>
+#include <ctkPluginContext.h>
 
 #include <QApplication>
 #include <QMainWindow>
@@ -189,19 +190,6 @@ void ctkPluginBrowser::pluginDoubleClicked(const QModelIndex& index)
     qDebug() << "Service from" << ref.getPlugin()->getSymbolicName() << ":" << ref.getPropertyKeys();
     qDebug() << "Object Classes:" << ref.getProperty(ctkPluginConstants::OBJECTCLASS).toStringList();
   }
-
-  try
-  {
-    ctkServiceReference cliRef(plugin->getPluginContext()->getServiceReference("ctkICLIManager"));
-    QObject* cliService = plugin->getPluginContext()->getService(cliRef);
-    if (cliService)
-      qDebug() << "Got service object: " << cliService->metaObject()->className();
-    else qDebug() << "Got null service";
-  }
-  catch (const ctkServiceException& e)
-  {
-    qDebug() << e;
-  }
 }
 
 void ctkPluginBrowser::qtResourceDoubleClicked(const QModelIndex& index)

+ 1 - 0
Applications/ctkPluginBrowser/ctkPluginTableModel.h

@@ -27,6 +27,7 @@
 #include <QList>
 
 #include <ctkPlugin.h>
+#include <ctkPluginEvent.h>
 
 class ctkPluginContext;
 

+ 1 - 0
Applications/ctkPluginGenerator/ctkPluginGeneratorMain.cpp

@@ -23,6 +23,7 @@
 #include <ctkPluginFramework.h>
 #include <ctkPluginException.h>
 #include <ctkPluginGeneratorConstants.h>
+#include <ctkPluginContext.h>
 
 #include "ctkPluginGenerator_p.h"
 

+ 4 - 1
Libs/PluginFramework/Testing/Cpp/ctkPluginFrameworkTestMain.cpp

@@ -24,12 +24,15 @@
 #include <QTest>
 #include <QThread>
 
+#include <ctkPluginContext.h>
 #include <ctkPluginConstants.h>
 #include <ctkPluginFrameworkFactory.h>
 #include <ctkPluginFramework.h>
 #include <ctkPluginException.h>
 #include <ctkServiceReference.h>
 
+#include "ctkTestSuiteInterface.h"
+
 class TestRunner : public QThread
 {
 public:
@@ -46,7 +49,7 @@ public:
     QSharedPointer<ctkPlugin> fwTest = context->getPlugin(testPluginId);
     fwTest->start();
 
-    QList<ctkServiceReference> refs = context->getServiceReferences("ctkTestSuiteInterface");
+    QList<ctkServiceReference> refs = context->getServiceReferences<ctkTestSuiteInterface>();
 
     int result = 0;
     foreach(ctkServiceReference ref, refs)

+ 3 - 1
Libs/PluginFramework/Testing/Cpp/ctkTestSuiteInterface.h

@@ -23,11 +23,13 @@
 #ifndef CTKTESTSUITEINTERFACE_H
 #define CTKTESTSUITEINTERFACE_H
 
-#include <qglobal.h>
+#include <ctkPluginFramework_global.h>
 
 struct ctkTestSuiteInterface
 {
   virtual ~ctkTestSuiteInterface() {}
 };
 
+Q_DECLARE_INTERFACE(ctkTestSuiteInterface, "org.commontk.TestSuiteInterface/1.0")
+
 #endif // CTKTESTSUITEINTERFACE_H

+ 2 - 2
Libs/PluginFramework/Testing/FrameworkTest/ctkPluginFrameworkTestActivator.cpp

@@ -37,11 +37,11 @@ void ctkPluginFrameworkTestActivator::start(ctkPluginContext* context)
   frameworkTestSuite = new ctkPluginFrameworkTestSuite(context);
   props.clear();
   props.insert(ctkPluginConstants::SERVICE_PID, frameworkTestSuite->metaObject()->className());
-  context->registerService(QStringList("ctkTestSuiteInterface"), frameworkTestSuite, props);
+  context->registerService<ctkTestSuiteInterface>(frameworkTestSuite, props);
 
   serviceListenerTestSuite = new ctkServiceListenerTestSuite(context);
   props.insert(ctkPluginConstants::SERVICE_PID, frameworkTestSuite->metaObject()->className());
-  context->registerService(QStringList("ctkTestSuiteInterface"), serviceListenerTestSuite, props);
+  context->registerService<ctkTestSuiteInterface>(serviceListenerTestSuite, props);
 }
 
 void ctkPluginFrameworkTestActivator::stop(ctkPluginContext* context)

+ 3 - 3
Libs/PluginFramework/Testing/FrameworkTest/ctkPluginFrameworkTestSuite.cpp

@@ -215,7 +215,7 @@ void ctkPluginFrameworkTestSuite::frame020a()
   // Check that no service reference exist yet.
   try
   {
-    pc->getServiceReference("ctkTestPluginAService");
+    pc->getServiceReference("org.commontk.TestPluginAService");
     QFAIL("framework test plugin, service from test plugin A unexpectedly found");
   }
   catch (ctkServiceException& /*e*/)
@@ -254,7 +254,7 @@ void ctkPluginFrameworkTestSuite::frame025b()
   // Check if pluginA_test registered the expected service
   try
   {
-    ctkServiceReference sr1 = pc->getServiceReference("ctkTestPluginAService");
+    ctkServiceReference sr1 = pc->getServiceReference("org.commontk.TestPluginAService");
     QObject* o1 = pc->getService(sr1);
     QVERIFY2(o1 != 0, "no service object found");
 
@@ -294,7 +294,7 @@ void ctkPluginFrameworkTestSuite::frame025b()
 void ctkPluginFrameworkTestSuite::frame030b()
 {
   ctkServiceReference sr1
-      = pc->getServiceReference("ctkTestPluginAService");
+      = pc->getServiceReference("org.commontk.TestPluginAService");
 
   try
   {

+ 1 - 0
Libs/PluginFramework/Testing/FrameworkTest/ctkPluginFrameworkTestSuite_p.h

@@ -36,6 +36,7 @@ class ctkPluginFrameworkTestSuite : public QObject,
                                     public ctkTestSuiteInterface
 {
   Q_OBJECT
+  Q_INTERFACES(ctkTestSuiteInterface)
 
 public:
 

+ 1 - 0
Libs/PluginFramework/Testing/FrameworkTest/ctkServiceListenerTestSuite_p.h

@@ -35,6 +35,7 @@ class ctkServiceListenerTestSuite : public QObject,
     public ctkTestSuiteInterface
 {
   Q_OBJECT
+  Q_INTERFACES(ctkTestSuiteInterface)
 
 public:
     ctkServiceListenerTestSuite(ctkPluginContext* pc);

+ 1 - 1
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA.cpp

@@ -29,7 +29,7 @@
 
 ctkTestPluginA::ctkTestPluginA(ctkPluginContext* pc)
 {
-  sr = pc->registerService(QStringList("ctkTestPluginAService"), this);
+  sr = pc->registerService<ctkTestPluginAService>(this);
 }
 
 void ctkTestPluginA::unregister()

+ 4 - 0
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginAService.h

@@ -23,9 +23,13 @@
 #ifndef CTKTESTPLUGINASERVICE_H
 #define CTKTESTPLUGINASERVICE_H
 
+#include <qglobal.h>
+
 struct ctkTestPluginAService
 {
   virtual ~ctkTestPluginAService() {}
 };
 
+Q_DECLARE_INTERFACE(ctkTestPluginAService, "org.commontk.TestPluginAService")
+
 #endif // CTKTESTPLUGINASERVICE_H

+ 1 - 0
Libs/PluginFramework/Testing/TestPlugins/pluginA2_test/ctkTestPluginA_p.h

@@ -34,6 +34,7 @@ class ctkTestPluginA : public QObject,
                        public ctkTestPluginAService
 {
   Q_OBJECT
+  Q_INTERFACES(ctkTestPluginAService)
 
 public:
     ctkTestPluginA(ctkPluginContext* pc);

+ 1 - 1
Libs/PluginFramework/Testing/TestPlugins/pluginA_test/ctkTestPluginA.cpp

@@ -28,5 +28,5 @@
 
 ctkTestPluginA::ctkTestPluginA(ctkPluginContext* pc)
 {
-  pc->registerService(QStringList("ctkTestPluginAService"), this);
+  pc->registerService<ctkTestPluginAService>(this);
 }

+ 4 - 0
Libs/PluginFramework/Testing/TestPlugins/pluginA_test/ctkTestPluginAService.h

@@ -23,9 +23,13 @@
 #ifndef CTKTESTPLUGINASERVICE_H
 #define CTKTESTPLUGINASERVICE_H
 
+#include <qglobal.h>
+
 struct ctkTestPluginAService
 {
   virtual ~ctkTestPluginAService() {}
 };
 
+Q_DECLARE_INTERFACE(ctkTestPluginAService, "org.commontk.TestPluginAService")
+
 #endif // CTKTESTPLUGINASERVICE_H

+ 1 - 0
Libs/PluginFramework/Testing/TestPlugins/pluginA_test/ctkTestPluginA_p.h

@@ -33,6 +33,7 @@ class ctkTestPluginA : public QObject,
                        public ctkTestPluginAService
 {
   Q_OBJECT
+  Q_INTERFACES(ctkTestPluginAService)
 
 public:
     ctkTestPluginA(ctkPluginContext* pc);

+ 1 - 1
Libs/PluginFramework/Testing/TestPlugins/pluginSL1_test/ctkActivatorSL1.cpp

@@ -41,7 +41,7 @@ void ctkActivatorSL1::start(ctkPluginContext* context)
 {
   this->context = context;
 
-  context->registerService(QStringList(this->metaObject()->className()), this);
+  context->registerService(this->metaObject()->className(), this);
 
   tracker.reset(new ctkServiceTracker(context, "ctkFooService", this));
   tracker->open();

+ 1 - 1
Libs/PluginFramework/Testing/TestPlugins/pluginSL3_test/ctkActivatorSL3.cpp

@@ -41,7 +41,7 @@ void ctkActivatorSL3::start(ctkPluginContext* context)
 {
   this->context = context;
 
-  context->registerService(QStringList(this->metaObject()->className()), this);
+  context->registerService(this->metaObject()->className(), this);
   tracker.reset(new ctkServiceTracker(context, "ctkFooService", this));
   tracker->open();
 }

+ 1 - 1
Libs/PluginFramework/Testing/TestPlugins/pluginSL4_test/ctkActivator.cpp

@@ -34,7 +34,7 @@ void ctkActivator::foo()
 void ctkActivator::start(ctkPluginContext* context)
 {
   ctkServiceRegistration* registration =
-      context->registerService(QStringList("ctkFooService"), this);
+      context->registerService<ctkFooService>(this);
   qDebug() << "pluginSL4: Registered" << registration;
 }
 

+ 1 - 0
Libs/PluginFramework/ctkLDAPSearchFilter.h

@@ -25,6 +25,7 @@
 #include "ctkPluginFrameworkExport.h"
 
 #include "ctkServiceReference.h"
+#include "ctkPluginFramework_global.h"
 
 #include <QSharedDataPointer>
 #include <QDebug>

+ 4 - 1
Libs/PluginFramework/ctkPlugin.h

@@ -22,10 +22,13 @@
 #ifndef CTKPLUGIN_H
 #define CTKPLUGIN_H
 
-#include "ctkPluginContext.h"
+#include <QHash>
+#include <QWeakPointer>
+#include <QMetaType>
 
 #include "ctkVersion.h"
 
+class ctkPluginContext;
 class ctkPluginArchive;
 class ctkPluginFrameworkContext;
 class ctkPluginPrivate;

+ 9 - 0
Libs/PluginFramework/ctkPluginContext.cpp

@@ -116,6 +116,15 @@ ctkServiceRegistration* ctkPluginContext::registerService(const QStringList& cla
   return d->plugin->fwCtx->services->registerService(d->plugin, clazzes, service, properties);
 }
 
+ctkServiceRegistration* ctkPluginContext::registerService(const char* clazz, QObject* service, const ServiceProperties& properties)
+{
+  Q_D(ctkPluginContext);
+  d->isPluginContextValid();
+  QStringList clazzes;
+  clazzes.append(clazz);
+  return d->plugin->fwCtx->services->registerService(d->plugin, clazzes, service, properties);
+}
+
 QList<ctkServiceReference> ctkPluginContext::getServiceReferences(const QString& clazz, const QString& filter)
 {
   Q_D(ctkPluginContext);

+ 117 - 2
Libs/PluginFramework/ctkPluginContext.h

@@ -32,6 +32,8 @@
 #include "ctkPluginFramework_global.h"
 
 #include "ctkPluginEvent.h"
+#include "ctkServiceException.h"
+#include "ctkServiceReference.h"
 
 #include "ctkPluginFrameworkExport.h"
 
@@ -40,7 +42,6 @@
 class ctkPlugin;
 class ctkPluginPrivate;
 class ctkServiceRegistration;
-class ctkServiceReference;
 class ctkPluginContextPrivate;
 
 /**
@@ -213,6 +214,41 @@ public:
   ctkServiceRegistration* registerService(const QStringList& clazzes, QObject* service, const ServiceProperties& properties = ServiceProperties());
 
   /**
+   * Registers the specified service object with the specified properties
+   * under the specified class name with the Framework.
+   *
+   * <p>
+   * This method is otherwise identical to
+   * registerService(const QStringList&, QObject*, const ServiceProperties&) and is provided as
+   * a convenience when <code>service</code> will only be registered under a single
+   * class name. Note that even in this case the value of the service's
+   * ctkPluginConstants::OBJECTCLASS property will be a QStringList, rather
+   * than just a single string.
+   *
+   * @param clazz The class name under which the service can be located.
+   * @param service The service object or a ctkServiceFactory object.
+   * @param properties The properties for this service.
+   * @return A ctkServiceRegistration object for use by the plugin
+   *         registering the service to update the service's properties or to
+   *         unregister the service.
+   * @throws std::logic_error If this ctkPluginContext is no longer valid.
+   * @see registerService(const QStringList&, QObject*, const ServiceProperties&)
+   */
+  ctkServiceRegistration* registerService(const char* clazz, QObject* service, const ServiceProperties& properties = ServiceProperties());
+
+  template<class S>
+  ctkServiceRegistration* registerService(QObject* service, const ServiceProperties& properties = ServiceProperties())
+  {
+    const char* clazz = qobject_interface_iid<S*>();
+    if (clazz == 0)
+    {
+      throw ctkServiceException(QString("The interface class you are registering your service %1 against has no Q_DECLARE_INTERFACE macro")
+                                .arg(service->metaObject()->className()));
+    }
+    return registerService(clazz, service, properties);
+  }
+
+  /**
    * Returns a list of <code>ctkServiceReference</code> objects. The returned
    * list contains services that
    * were registered under the specified class and match the specified filter
@@ -260,6 +296,34 @@ public:
   QList<ctkServiceReference> getServiceReferences(const QString& clazz, const QString& filter = QString());
 
   /**
+   * Returns a list of <code>ctkServiceReference</code> objects. The returned
+   * list contains services that
+   * were registered under the Qt interface id of the template argument <code>S</code>
+   * and match the specified filter expression.
+   *
+   * <p>
+   * This method is identical to getServiceReferences(const QString&, const QString&) except that
+   * the class name for the service object is automatically deduced from the template argument.
+   *
+   * @param filter The filter expression or empty for all
+   *        services.
+   * @return A list of <code>ctkServiceReference</code> objects or
+   *         an empty list if no services are registered which satisfy the
+   *         search.
+   * @throws std::invalid_argument If the specified <code>filter</code>
+   *         contains an invalid filter expression that cannot be parsed.
+   * @throws std::logic_error If this ctkPluginContext is no longer valid.
+   * @see getServiceReferences(const QString&, const QString&)
+   */
+  template<class S>
+  QList<ctkServiceReference> getServiceReferences(const QString& filter = QString())
+  {
+    const char* clazz = qobject_interface_iid<S*>();
+    if (clazz == 0) throw ctkServiceException("The service interface class has no Q_DECLARE_INTERFACE macro");
+    return getServiceReferences(QString(clazz), filter);
+  }
+
+  /**
    * Returns a <code>ctkServiceReference</code> object for a service that
    * implements and was registered under the specified class.
    *
@@ -292,6 +356,29 @@ public:
   ctkServiceReference getServiceReference(const QString& clazz);
 
   /**
+   * Returns a <code>ctkServiceReference</code> object for a service that
+   * implements and was registered under the specified template class argument.
+   *
+   * <p>
+   * This method is identical to getServiceReference(const QString&) except that
+   * the class name for the service object is automatically deduced from the template argument.
+   *
+   * @return A <code>ctkServiceReference</code> object, or <code>0</code> if
+   *         no services are registered which implement the named class.
+   * @throws std::logic_error If this ctkPluginContext is no longer valid.
+   * @throws ctkServiceException It no service was registered under the given class name.
+   * @see #getServiceReference(const QString&)
+   * @see #getServiceReferences(const QString&)
+   */
+  template<class S>
+  ctkServiceReference getServiceReference()
+  {
+    const char* clazz = qobject_interface_iid<S*>();
+    if (clazz == 0) throw ctkServiceException("The service interface class has no Q_DECLARE_INTERFACE macro");
+    return getServiceReference(QString(clazz));
+  }
+
+  /**
    * Returns the service object referenced by the specified
    * <code>ctkServiceReference</code> object.
    * <p>
@@ -345,12 +432,40 @@ public:
    * @throws std::invalid_argument If the specified
    *         <code>ctkServiceReference</code> was not created by the same
    *         framework instance as this <code>ctkPluginContext</code>.
-   * @see #ungetService(ctkServiceReference*)
+   * @see #ungetService(const ctkServiceReference&)
    * @see ctkServiceFactory
    */
   QObject* getService(ctkServiceReference reference);
 
   /**
+   * Returns the service object referenced by the specified
+   * <code>ctkServiceReference</code> object.
+   * <p>
+   * This is a convenience method which is identical to QObject* getService(ctkServiceReference)
+   * except that it casts the service object to the supplied template argument type
+   *
+   * @return A service object for the service associated with
+   *         <code>reference</code> or <code>0</code> if the service is not
+   *         registered, the service object returned by a
+   *         <code>ctkServiceFactory</code> does not implement the classes under
+   *         which it was registered, the <code>ctkServiceFactory</code> threw
+   *         an exception or the service could not be casted to the desired type.
+   * @throws std::logic_error If this ctkPluginContext is no
+   *         longer valid.
+   * @throws std::invalid_argument If the specified
+   *         <code>ctkServiceReference</code> was not created by the same
+   *         framework instance as this <code>ctkPluginContext</code>.
+   * @see #getService(ctkServiceReference)
+   * @see #ungetService(const ctkServiceReference&)
+   * @see ctkServiceFactory
+   */
+  template<class S>
+  S* getService(ctkServiceReference reference)
+  {
+    return qobject_cast<S*>(getService(reference));
+  }
+
+  /**
    * Releases the service object referenced by the specified
    * <code>ctkServiceReference</code> object. If the context plugin's use count
    * for the service is zero, this method returns <code>false</code>.

+ 1 - 0
Libs/PluginFramework/ctkPluginFrameworkPrivate.cpp

@@ -23,6 +23,7 @@
 
 #include "ctkPluginFramework.h"
 #include "ctkPluginConstants.h"
+#include "ctkPluginContext.h"
 #include "ctkPluginContext_p.h"
 #include "ctkPluginFrameworkContext_p.h"
 

+ 38 - 0
Libs/PluginFramework/ctkPluginFramework_global.h

@@ -24,6 +24,7 @@
 #define CTKPLUGINFRAMEWORK_GLOBAL_H
 
 #include <QHash>
+#include <QStringList>
 
 typedef QHash<QString, QVariant> ServiceProperties;
 typedef QHash<QString, QVariant> ctkDictionary;
@@ -38,4 +39,41 @@ inline uint qHash(const QSharedPointer<T>& ptr)
 }
 #endif
 
+
+template<class A>
+QStringList getIIDs()
+{
+  return QString(qobject_interface_iid<A*>());
+}
+
+template<class A, class B>
+QStringList getIIDs()
+{
+  QStringList ids;
+  ids << qobject_interface_iid<A*>();
+  ids << qobject_interface_iid<B*>();
+  return ids;
+}
+
+template<class A, class B, class C>
+QStringList getIIDs()
+{
+  QStringList ids;
+  ids << qobject_interface_iid<A*>();
+  ids << qobject_interface_iid<B*>();
+  ids << qobject_interface_iid<C*>();
+  return ids;
+}
+
+template<class A, class B, class C, class D>
+QStringList getIIDs()
+{
+  QStringList ids;
+  ids << qobject_interface_iid<A*>();
+  ids << qobject_interface_iid<B*>();
+  ids << qobject_interface_iid<C*>();
+  ids << qobject_interface_iid<D*>();
+  return ids;
+}
+
 #endif // CTKPLUGINFRAMEWORK_GLOBAL_H

+ 1 - 0
Libs/PluginFramework/ctkPluginTracker.cpp

@@ -22,6 +22,7 @@
 
 #include "ctkPluginTracker.h"
 
+#include "ctkPluginContext.h"
 #include "ctkPluginTrackerPrivate.h"
 #include "ctkTrackedPlugin_p.h"
 

+ 1 - 0
Libs/PluginFramework/ctkServiceFactory.h

@@ -26,6 +26,7 @@
 
 #include "ctkPluginFrameworkExport.h"
 
+class ctkServiceRegistration;
 
   /**
    * Allows services to provide customized service objects in the plugin

+ 1 - 0
Libs/PluginFramework/ctkServiceRegistrationPrivate.h

@@ -26,6 +26,7 @@
 #include <QHash>
 #include <QMutex>
 
+#include "ctkPluginFramework_global.h"
 #include "ctkServiceReference.h"
 
 

+ 1 - 0
Libs/PluginFramework/ctkServiceTracker.cpp

@@ -25,6 +25,7 @@
 #include "ctkTrackedService_p.h"
 #include "ctkServiceException.h"
 #include "ctkPluginConstants.h"
+#include "ctkPluginContext.h"
 
 #include <QVarLengthArray>
 #include <QDebug>

+ 1 - 0
Libs/PluginFramework/ctkServiceTrackerPrivate.cpp

@@ -23,6 +23,7 @@
 #include "ctkServiceTrackerPrivate.h"
 #include "ctkTrackedService_p.h"
 
+#include "ctkPluginContext.h"
 #include "ctkPluginConstants.h"
 #include "ctkLDAPSearchFilter.h"
 #include "ctkServiceTracker.h"