1 /*============================================================================= 2 3 Library: CTK 4 5 Copyright (c) German Cancer Research Center, 6 Division of Medical and Biological Informatics 7 8 Licensed under the Apache License, Version 2.0 (the "License"); 9 you may not use this file except in compliance with the License. 10 You may obtain a copy of the License at 11 12 http://www.apache.org/licenses/LICENSE-2.0 13 14 Unless required by applicable law or agreed to in writing, software 15 distributed under the License is distributed on an "AS IS" BASIS, 16 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 See the License for the specific language governing permissions and 18 limitations under the License. 19 20 =============================================================================*/ 21 22 #ifndef CTKPLUGINCONTEXT_H_ 23 #define CTKPLUGINCONTEXT_H_ 24 25 #include <QHash> 26 #include <QString> 27 #include <QVariant> 28 #include <QUrl> 29 #include <QSharedPointer> 30 #include <QFileInfo> 31 32 #include "ctkPluginFramework_global.h" 33 34 #include "ctkPluginEvent.h" 35 #include "ctkServiceException.h" 36 #include "ctkServiceReference.h" 37 #include "ctkServiceRegistration.h" 38 39 #include "ctkPluginFrameworkExport.h" 40 41 42 // CTK class forward declarations 43 class ctkPlugin; 44 class ctkPluginPrivate; 45 class ctkPluginContextPrivate; 46 47 /** 48 * \ingroup PluginFramework 49 * 50 * A plugin's execution context within the Framework. The context is used to 51 * grant access to other methods so that this plugin can interact with the 52 * Framework. 53 * 54 * <p> 55 * <code>ctkPluginContext</code> methods allow a plugin to: 56 * <ul> 57 * <li>Subscribe to events published by the Framework. 58 * <li>Register service objects with the Framework service registry. 59 * <li>Retrieve <code>ServiceReferences</code> from the Framework service 60 * registry. 61 * <li>Get and release service objects for a referenced service. 62 * <li>Install new plugins in the Framework. 63 * <li>Get the list of plugins installed in the Framework. 64 * <li>Get the {@link ctkPlugin} object for a plugin. 65 * <li>Create <code>QFile</code> objects for files in a persistent storage 66 * area provided for the plugin by the Framework. 67 * </ul> 68 * 69 * <p> 70 * A <code>ctkPluginContext</code> object will be created and provided to the 71 * plugin associated with this context when it is started using the 72 * {@link ctkPluginActivator::start} method. The same <code>ctkPluginContext</code> 73 * object will be passed to the plugin associated with this context when it is 74 * stopped using the {@link ctkPluginActivator::stop} method. A 75 * <code>ctkPluginContext</code> object is generally for the private use of its 76 * associated plugin and is not meant to be shared with other plugins in the 77 * plugin environment. 78 * 79 * <p> 80 * The <code>ctkPlugin</code> object associated with a <code>ctkPluginContext</code> 81 * object is called the <em>context plugin</em>. 82 * 83 * <p> 84 * The <code>ctkPluginContext</code> object is only valid during the execution of 85 * its context plugin; that is, during the period from when the context plugin 86 * is in the <code>STARTING</code>, <code>STOPPING</code>, and 87 * <code>ACTIVE</code> plugin states. If the <code>ctkPluginContext</code> 88 * object is used subsequently, a <code>ctkIllegalStateException</code> must be 89 * thrown. The <code>ctkPluginContext</code> object must never be reused after 90 * its context plugin is stopped. 91 * 92 * <p> 93 * The Framework is the only entity that can create <code>ctkPluginContext</code> 94 * objects and they are only valid within the Framework that created them. 95 * 96 * @remarks This class is thread safe. 97 */ 98 class CTK_PLUGINFW_EXPORT ctkPluginContext 99 { 100 101 public: 102 103 ~ctkPluginContext(); 104 105 /** 106 * Returns the value of the specified property. If the key is not found in 107 * the Framework properties, the system properties are then searched. The 108 * method returns an invalid QVariant if the property is not found. 109 * 110 * @param key The name of the requested property. 111 * @return The value of the requested property, or an invalid QVariant if 112 * the property is undefined. 113 */ 114 QVariant getProperty(const QString& key) const; 115 116 /** 117 * Returns the <code>ctkPlugin</code> object associated with this 118 * <code>ctkPluginContext</code>. This plugin is called the context plugin. 119 * 120 * @return The <code>ctkPlugin</code> object associated with this 121 * <code>ctkPluginContext</code>. 122 * @throws ctkIllegalStateException If this ctkPluginContext is no 123 * longer valid. 124 */ 125 QSharedPointer<ctkPlugin> getPlugin() const; 126 127 /** 128 * Returns the plugin with the specified identifier. 129 * 130 * @param id The identifier of the plugin to retrieve. 131 * @return A <code>ctkPlugin</code> object or <code>0</code> if the 132 * identifier does not match any installed plugin. 133 */ 134 QSharedPointer<ctkPlugin> getPlugin(long id) const; 135 136 137 /** 138 * Returns a list of all installed plugins. 139 * <p> 140 * This method returns a list of all plugins installed in the plugin 141 * environment at the time of the call to this method. However, since the 142 * Framework is a very dynamic environment, plugins can be installed or 143 * uninstalled at anytime. 144 * 145 * @return A QList of <code>ctkPlugin</code> objects, one object per 146 * installed plugin. 147 */ 148 QList<QSharedPointer<ctkPlugin> > getPlugins() const; 149 150 /** 151 * Registers the specified service object with the specified properties 152 * under the specified class names into the Framework. A 153 * <code>ctkServiceRegistration</code> object is returned. The 154 * <code>ctkServiceRegistration</code> object is for the private use of the 155 * plugin registering the service and should not be shared with other 156 * plugins. The registering plugin is defined to be the context plugin. 157 * Other plugins can locate the service by using either the 158 * {@link #getServiceReferences} or {@link #getServiceReference} method. 159 * 160 * <p> 161 * A plugin can register a service object that implements the 162 * {@link ctkServiceFactory} interface to have more flexibility in providing 163 * service objects to other plugins. 164 * 165 * <p> 166 * The following steps are required to register a service: 167 * <ol> 168 * <li>If <code>service</code> is not a <code>ctkServiceFactory</code>, an 169 * <code>ctkInvalidArgumentException</code> is thrown if <code>service</code> 170 * is not an instance of all the specified class names. 171 * <li>The Framework adds the following service properties to the service 172 * properties from the specified <code>ctkDictionary</code> (which may be 173 * omitted): <br/> 174 * A property named {@link ctkPluginConstants#SERVICE_ID} identifying the 175 * registration number of the service <br/> 176 * A property named {@link ctkPluginConstants#OBJECTCLASS} containing all the 177 * specified classes. <br/> 178 * Properties with these names in the specified <code>ctkDictionary</code> will 179 * be ignored. 180 * <li>The service is added to the Framework service registry and may now be 181 * used by other plugins. 182 * <li>A service event of type {@link ctkServiceEvent#REGISTERED} is fired. 183 * <li>A <code>ctkServiceRegistration</code> object for this registration is 184 * returned. 185 * </ol> 186 * 187 * @param clazzes The class names under which the service can be located. 188 * The class names will be stored in the service's 189 * properties under the key {@link ctkPluginConstants#OBJECTCLASS}. 190 * @param service The service object or a <code>ctkServiceFactory</code> 191 * object. 192 * @param properties The properties for this service. The keys in the 193 * properties object must all be <code>QString</code> objects. See 194 * {@link ctkPluginConstants} for a list of standard service property keys. 195 * Changes should not be made to this object after calling this 196 * method. To update the service's properties the 197 * {@link ctkServiceRegistration::setProperties} method must be called. 198 * The set of properties may be omitted if the service has 199 * no properties. 200 * @return A <code>ctkServiceRegistration</code> object for use by the plugin 201 * registering the service to update the service's properties or to 202 * unregister the service. 203 * @throws ctkInvalidArgumentException If one of the following is true: 204 * <ul> 205 * <li><code>service</code> is <code>0</code>. <li><code>service 206 * </code> is not a <code>ctkServiceFactory</code> object and is not an 207 * instance of all the named classes in <code>clazzes</code>. <li> 208 * <code>properties</code> contains case variants of the same key 209 * name. 210 * </ul> 211 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 212 * @see ctkServiceRegistration 213 * @see ctkServiceFactory 214 */ 215 ctkServiceRegistration registerService(const QStringList& clazzes, QObject* service, const ctkDictionary& properties = ctkDictionary()); 216 217 /** 218 * Registers the specified service object with the specified properties 219 * under the specified class name with the Framework. 220 * 221 * <p> 222 * This method is otherwise identical to 223 * registerService(const QStringList&, QObject*, const ctkDictionary&) and is provided as 224 * a convenience when <code>service</code> will only be registered under a single 225 * class name. Note that even in this case the value of the service's 226 * ctkPluginConstants::OBJECTCLASS property will be a QStringList, rather 227 * than just a single string. 228 * 229 * @param clazz The class name under which the service can be located. 230 * @param service The service object or a ctkServiceFactory object. 231 * @param properties The properties for this service. 232 * @return A ctkServiceRegistration object for use by the plugin 233 * registering the service to update the service's properties or to 234 * unregister the service. 235 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 236 * @see registerService(const QStringList&, QObject*, const ctkDictionary&) 237 */ 238 ctkServiceRegistration registerService(const char* clazz, QObject* service, const ctkDictionary& properties = ctkDictionary()); 239 240 template<class S> 241 ctkServiceRegistration registerService(QObject* service, const ctkDictionary& properties = ctkDictionary()) 242 { 243 const char* clazz = qobject_interface_iid<S*>(); 244 if (clazz == 0) 245 { 246 throw ctkServiceException(QString("The interface class you are registering your service %1 against has no Q_DECLARE_INTERFACE macro") 247 .arg(service->metaObject()->className())); 248 } 249 return registerService(clazz, service, properties); 250 } 251 252 /** 253 * Returns a list of <code>ctkServiceReference</code> objects. The returned 254 * list contains services that 255 * were registered under the specified class and match the specified filter 256 * expression. 257 * 258 * <p> 259 * The list is valid at the time of the call to this method. However since 260 * the Framework is a very dynamic environment, services can be modified or 261 * unregistered at any time. 262 * 263 * <p> 264 * The specified <code>filter</code> expression is used to select the 265 * registered services whose service properties contain keys and values 266 * which satisfy the filter expression. See {@link ctkLDAPSearchFilter} for a description 267 * of the filter syntax. If the specified <code>filter</code> is 268 * empty, all registered services are considered to match the 269 * filter. If the specified <code>filter</code> expression cannot be parsed, 270 * an <code>ctkInvalidArgumentException</code> will be thrown with a human readable 271 * message where the filter became unparsable. 272 * 273 * <p> 274 * The result is a list of <code>ctkServiceReference</code> objects for all 275 * services that meet all of the following conditions: 276 * <ul> 277 * <li>If the specified class name, <code>clazz</code>, is not 278 * empty, the service must have been registered with the 279 * specified class name. The complete list of class names with which a 280 * service was registered is available from the service's 281 * {@link ctkPluginConstants::OBJECTCLASS objectClass} property. 282 * <li>If the specified <code>filter</code> is not empty, the 283 * filter expression must match the service. 284 * </ul> 285 * 286 * @param clazz The class name with which the service was registered or 287 * an empty string for all services. 288 * @param filter The filter expression or empty for all 289 * services. 290 * @return A list of <code>ctkServiceReference</code> objects or 291 * an empty list if no services are registered which satisfy the 292 * search. 293 * @throws ctkInvalidArgumentException If the specified <code>filter</code> 294 * contains an invalid filter expression that cannot be parsed. 295 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 296 */ 297 QList<ctkServiceReference> getServiceReferences(const QString& clazz, const QString& filter = QString()); 298 299 /** 300 * Returns a list of <code>ctkServiceReference</code> objects. The returned 301 * list contains services that 302 * were registered under the Qt interface id of the template argument <code>S</code> 303 * and match the specified filter expression. 304 * 305 * <p> 306 * This method is identical to getServiceReferences(const QString&, const QString&) except that 307 * the class name for the service object is automatically deduced from the template argument. 308 * 309 * @param filter The filter expression or empty for all 310 * services. 311 * @return A list of <code>ctkServiceReference</code> objects or 312 * an empty list if no services are registered which satisfy the 313 * search. 314 * @throws ctkInvalidArgumentException If the specified <code>filter</code> 315 * contains an invalid filter expression that cannot be parsed. 316 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 317 * @see getServiceReferences(const QString&, const QString&) 318 */ 319 template<class S> 320 QList<ctkServiceReference> getServiceReferences(const QString& filter = QString()) 321 { 322 const char* clazz = qobject_interface_iid<S*>(); 323 if (clazz == 0) throw ctkServiceException("The service interface class has no Q_DECLARE_INTERFACE macro"); 324 return getServiceReferences(QString(clazz), filter); 325 } 326 327 /** 328 * Returns a <code>ctkServiceReference</code> object for a service that 329 * implements and was registered under the specified class. 330 * 331 * <p> 332 * The returned <code>ctkServiceReference</code> object is valid at the time of 333 * the call to this method. However as the Framework is a very dynamic 334 * environment, services can be modified or unregistered at any time. 335 * 336 * <p> 337 * This method is the same as calling 338 * {@link ctkPluginContext::getServiceReferences(const QString&, const QString&)} with an 339 * empty filter expression. It is provided as a convenience for 340 * when the caller is interested in any service that implements the 341 * specified class. 342 * <p> 343 * If multiple such services exist, the service with the highest ranking (as 344 * specified in its {@link ctkPluginConstants::SERVICE_RANKING} property) is returned. 345 * <p> 346 * If there is a tie in ranking, the service with the lowest service ID (as 347 * specified in its {@link ctkPluginConstants::SERVICE_ID} property); that is, the 348 * service that was registered first is returned. 349 * 350 * @param clazz The class name with which the service was registered. 351 * @return A <code>ctkServiceReference</code> object, or <code>0</code> if 352 * no services are registered which implement the named class. 353 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 354 * @throws ctkServiceException It no service was registered under the given class name. 355 * @see #getServiceReferences(const QString&, const QString&) 356 */ 357 ctkServiceReference getServiceReference(const QString& clazz); 358 359 /** 360 * Returns a <code>ctkServiceReference</code> object for a service that 361 * implements and was registered under the specified template class argument. 362 * 363 * <p> 364 * This method is identical to getServiceReference(const QString&) except that 365 * the class name for the service object is automatically deduced from the template argument. 366 * 367 * @return A <code>ctkServiceReference</code> object, or <code>0</code> if 368 * no services are registered which implement the named class. 369 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 370 * @throws ctkServiceException It no service was registered under the given class name. 371 * @see #getServiceReference(const QString&) 372 * @see #getServiceReferences(const QString&) 373 */ 374 template<class S> getServiceReference()375 ctkServiceReference getServiceReference() 376 { 377 const char* clazz = qobject_interface_iid<S*>(); 378 if (clazz == 0) throw ctkServiceException("The service interface class has no Q_DECLARE_INTERFACE macro"); 379 return getServiceReference(QString(clazz)); 380 } 381 382 /** 383 * Returns the service object referenced by the specified 384 * <code>ctkServiceReference</code> object. 385 * <p> 386 * A plugin's use of a service is tracked by the plugin's use count of that 387 * service. Each time a service's service object is returned by 388 * {@link #getService(const ctkServiceReference&)} the context plugin's use count for 389 * that service is incremented by one. Each time the service is released by 390 * {@link #ungetService(const ctkServiceReference&)} the context plugin's use count 391 * for that service is decremented by one. 392 * <p> 393 * When a plugin's use count for a service drops to zero, the plugin should 394 * no longer use that service. 395 * 396 * <p> 397 * This method will always return <code>0</code> when the service 398 * associated with this <code>reference</code> has been unregistered. 399 * 400 * <p> 401 * The following steps are required to get the service object: 402 * <ol> 403 * <li>If the service has been unregistered, <code>0</code> is returned. 404 * <li>The context plugin's use count for this service is incremented by 405 * one. 406 * <li>If the context plugin's use count for the service is currently one 407 * and the service was registered with an object implementing the 408 * <code>ctkServiceFactory</code> interface, the 409 * {@link ctkServiceFactory::getService} method is 410 * called to create a service object for the context plugin. This service 411 * object is cached by the Framework. While the context plugin's use count 412 * for the service is greater than zero, subsequent calls to get the 413 * services's service object for the context plugin will return the cached 414 * service object. <br> 415 * If the service object returned by the <code>ctkServiceFactory</code> object 416 * is not an instance of all the classes named when the service 417 * was registered or the <code>ctkServiceFactory</code> object throws an 418 * exception, <code>0</code> is returned and a Framework event of type 419 * {@link ctkPluginFrameworkEvent::PLUGIN_ERROR} containing a {@link ctkServiceException} 420 * describing the error is fired. 421 * <li>The service object for the service is returned. 422 * </ol> 423 * 424 * @param reference A reference to the service. 425 * @return A service object for the service associated with 426 * <code>reference</code> or <code>0</code> if the service is not 427 * registered, the service object returned by a 428 * <code>ctkServiceFactory</code> does not implement the classes under 429 * which it was registered or the <code>ctkServiceFactory</code> threw 430 * an exception. 431 * @throws ctkIllegalStateException If this ctkPluginContext is no 432 * longer valid. 433 * @throws ctkInvalidArgumentException If the specified 434 * <code>ctkServiceReference</code> was not created by the same 435 * framework instance as this <code>ctkPluginContext</code> or 436 * if it is invalid (default constructed). 437 * @see #ungetService(const ctkServiceReference&) 438 * @see ctkServiceFactory 439 */ 440 QObject* getService(const ctkServiceReference& reference); 441 442 /** 443 * Returns the service object referenced by the specified 444 * <code>ctkServiceReference</code> object. 445 * <p> 446 * This is a convenience method which is identical to QObject* getService(ctkServiceReference) 447 * except that it casts the service object to the supplied template argument type 448 * 449 * @return A service object for the service associated with 450 * <code>reference</code> or <code>0</code> if the service is not 451 * registered, the service object returned by a 452 * <code>ctkServiceFactory</code> does not implement the classes under 453 * which it was registered, the <code>ctkServiceFactory</code> threw 454 * an exception or the service could not be casted to the desired type. 455 * @throws ctkIllegalStateException If this ctkPluginContext is no 456 * longer valid. 457 * @throws ctkInvalidArgumentException If the specified 458 * <code>ctkServiceReference</code> was not created by the same 459 * framework instance as this <code>ctkPluginContext</code> or 460 * if it is invalid (default constructed). 461 * @see #getService(const ctkServiceReference&) 462 * @see #ungetService(const ctkServiceReference&) 463 * @see ctkServiceFactory 464 */ 465 template<class S> getService(const ctkServiceReference & reference)466 S* getService(const ctkServiceReference& reference) 467 { 468 return qobject_cast<S*>(getService(reference)); 469 } 470 471 /** 472 * Releases the service object referenced by the specified 473 * <code>ctkServiceReference</code> object. If the context plugin's use count 474 * for the service is zero, this method returns <code>false</code>. 475 * Otherwise, the context plugins's use count for the service is decremented 476 * by one. 477 * 478 * <p> 479 * The service's service object should no longer be used and all references 480 * to it should be destroyed when a bundle's use count for the service drops 481 * to zero. 482 * 483 * <p> 484 * The following steps are required to unget the service object: 485 * <ol> 486 * <li>If the context plugin's use count for the service is zero or the 487 * service has been unregistered, <code>false</code> is returned. 488 * <li>The context plugin's use count for this service is decremented by 489 * one. 490 * <li>If the context plugin's use count for the service is currently zero 491 * and the service was registered with a <code>ctkServiceFactory</code> object, 492 * the 493 * {@link ctkServiceFactory#ungetService} 494 * method is called to release the service object for the context plugin. 495 * <li><code>true</code> is returned. 496 * </ol> 497 * 498 * @param reference A reference to the service to be released. 499 * @return <code>false</code> if the context plugin's use count for the 500 * service is zero or if the service has been unregistered; 501 * <code>true</code> otherwise. 502 * @throws ctkIllegalStateException If this ctkPluginContext is no 503 * longer valid. 504 * @throws ctkInvalidArgumentException If the specified 505 * <code>ctkServiceReference</code> was not created by the same 506 * framework instance as this <code>ctkPluginContext</code>. 507 * @see #getService 508 * @see ctkServiceFactory 509 */ 510 bool ungetService(const ctkServiceReference& reference); 511 512 /** 513 * Creates a <code>QFileInfo</code> object for a file or directoryin the 514 * persistent storage area provided for the plugin by the Framework. 515 * 516 * <p> 517 * A <code>QFileInfo</code> object for the base directory of the persistent 518 * storage area provided for the context plugin by the Framework can be 519 * obtained by calling this method with an empty string as 520 * <code>filename</code>. 521 * 522 * <p> 523 * If the permissions are enabled, the Framework will 524 * ensure that the plugin has the <code>ctkFilePermission</code> with 525 * actions <code>read</code>,<code>write</code>,<code>delete</code> 526 * for all files (recursively) in the persistent storage area provided for 527 * the context plugin. 528 * 529 * @param filename A relative name to the file or directory to be accessed. 530 * @return A <code>QFileInfo</code> object that represents the requested file 531 * or directory. 532 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 533 */ 534 QFileInfo getDataFile(const QString& filename); 535 536 /** 537 * Installs a plugin from the specified <code>QIODevice</code> object. 538 * 539 * <p> 540 * If the specified <code>QIODevice</code> is <code>null</code>, the 541 * Framework must create the <code>QIODevice</code> from which to read the 542 * plugin by interpreting, in an implementation dependent manner, the 543 * specified <code>location</code>. 544 * 545 * <p> 546 * The specified <code>location</code> identifier will be used as the 547 * identity of the plugin. Every installed plugin is uniquely identified by 548 * its location identifier which is typically in the form of a URL. 549 * 550 * <p> 551 * The following steps are required to install a plugin: 552 * <ol> 553 * <li>If a plugin containing the same location identifier is already 554 * installed, the <code>ctkPlugin</code> object for that plugin is returned. 555 * 556 * <li>The plugin's content is read from the input stream. If this fails, a 557 * {@link ctkPluginException} is thrown. 558 * 559 * <li>The plugin's associated resources are allocated. The associated 560 * resources minimally consist of a unique identifier and a persistent 561 * storage area. If this step fails, a <code>ctkPluginException</code> 562 * is thrown. 563 * 564 * <li>The plugin's state is set to <code>INSTALLED</code>. 565 * 566 * <li>A plugin event of type {@link ctkPluginEvent#INSTALLED} is fired. 567 * 568 * <li>The <code>ctkPlugin</code> object for the newly or previously installed 569 * plugin is returned. 570 * </ol> 571 * 572 * <b>Postconditions, no exceptions thrown </b> 573 * <ul> 574 * <li><code>getState()</code> in { <code>INSTALLED</code>, 575 * <code>RESOLVED</code> }. 576 * <li>Plugin has a unique ID. 577 * </ul> 578 * <b>Postconditions, when an exception is thrown </b> 579 * <ul> 580 * <li>Plugin is not installed and no trace of the plugin exists. 581 * </ul> 582 * 583 * @param location The location identifier of the plugin to install. 584 * @param input The <code>QIODevice</code> object from which this plugin 585 * will be read or <code>null</code> to indicate the Framework must 586 * create the I/O device from the specified location identifier. 587 * The I/O device must always be closed when this method completes, 588 * even if an exception is thrown. 589 * @return The <code>ctkPlugin</code> object of the installed plugin. 590 * @throws ctkPluginException If the I/O device cannot be read or the 591 * installation failed. 592 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 593 */ 594 QSharedPointer<ctkPlugin> installPlugin(const QUrl& location, QIODevice* input = 0); 595 596 /** 597 * Connects the specified <code>slot</code> to the context 598 * plugins's signal which is emitted when a plugin has 599 * a lifecycle state change. The signature of the slot 600 * must be "slotName(ctkPluginEvent)". 601 * 602 * @param receiver The object to connect to. 603 * @param slot The slot to be connected. 604 * @param type The Qt connection type. Only Qt::DirectConnection, 605 * Qt::QueuedConnection, or Qt::BlockingQueuedConnection is allowed. 606 * @returns <code>true</code> if the connection was successfull; 607 * <code>false</code> otherwise. 608 * @throws ctkIllegalStateException If this ctkPluginContext is no 609 * longer valid. 610 * @see ctkPluginEvent 611 * @see ctkEventBus 612 */ 613 bool connectPluginListener(const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::QueuedConnection); 614 615 /** 616 * Disconnects the specified <code>slot</code> from the context 617 * plugin. 618 * 619 * <p> 620 * If <code>slot</code> is not connected to the context plugin, 621 * this method does nothing. 622 * 623 * @param receiver The object which has previously connected <code>slot</code>. 624 * @param slot The Qt slot to be disconnected. If <code>NULL</code>, all slots 625 * previously connected via connectPluginListener are disconnected. 626 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 627 */ 628 void disconnectPluginListener(const QObject* receiver, const char* slot = 0); 629 630 /** 631 * Connects the specified <code>slot</code> to the context 632 * plugin's signal which emits general Framework events. The signature 633 * of the slot must be "slotName(ctkPluginFrameworkEvent)". 634 * 635 * @param receiver The object to connect to. 636 * @param slot The slot to be connected. 637 * @param type The Qt connection type. 638 * @returns <code>true</code> if the connection was successfull; 639 * <code>false</code> otherwise. 640 * @throws ctkIllegalStateException If this ctkPluginContext is no 641 * longer valid. 642 * @see ctkPluginFrameworkEvent 643 * @see ctkEventBus 644 */ 645 bool connectFrameworkListener(const QObject* receiver, const char* slot, Qt::ConnectionType type = Qt::QueuedConnection); 646 647 /** 648 * Disconnects the specified <code>slot</code> from the context 649 * plugin. 650 * 651 * <p> 652 * If <code>slot</code> is not connected to the context plugin, 653 * this method does nothing. 654 * 655 * @param receiver The object which has previously connected <code>slot</code>. 656 * @param slot The Qt slot to be disconnected. If <code>NULL</code>, all slots 657 * previously connected via connectFrameworkListener are disconnected. 658 * @throws ctkIllegalStateException If this ctkPluginContext is no longer valid. 659 */ 660 void disconnectFrameworkListener(const QObject* receiver, const char* slot = 0); 661 662 /** 663 * Connects the specified <code>slot</code> with the 664 * specified <code>filter</code> to the context plugins's signal emitting 665 * service events when a service has a lifecycle state change. The signature 666 * of the slot must be "slotName(const ctkServiceEvent&)", but only the name 667 * of the slot must be provided as the argument. 668 * See {@link ctkLDAPSearchFilter} for a description of 669 * the filter syntax. 670 * 671 * <p> 672 * If the object to connect to is destroyed, the slot is automatically 673 * disconnected. To explicitly disconnect the slot, use 674 * disconnectServiceListener(). 675 * 676 * <p> 677 * If the context plugin's list of listeners already contains the same 678 * slot for the given receiver, then this 679 * method replaces that slot's filter (which may be <code>null</code>) 680 * with the specified one (which may be <code>null</code>). 681 * 682 * <p> 683 * The slot is called if the filter criteria is met. To filter based 684 * upon the class of the service, the filter should reference the 685 * {@link ctkPluginConstants#OBJECTCLASS} property. If <code>filter</code> is 686 * <code>null</code>, all services are considered to match the filter. 687 * 688 * <p> 689 * When using a <code>filter</code>, it is possible that the 690 * <code>ctkServiceEvent</code>s for the complete lifecycle of a service 691 * will not be delivered to the slot. For example, if the 692 * <code>filter</code> only matches when the property <code>x</code> has 693 * the value <code>1</code>, the listener will not be called if the 694 * service is registered with the property <code>x</code> not set to the 695 * value <code>1</code>. Subsequently, when the service is modified 696 * setting property <code>x</code> to the value <code>1</code>, the 697 * filter will match and the slot will be called with a 698 * <code>ServiceEvent</code> of type <code>MODIFIED</code>. Thus, the 699 * slot will not be called with a <code>ServiceEvent</code> of type 700 * <code>REGISTERED</code>. 701 * 702 * @param receiver The object to connect to. 703 * @param slot The name of the slot to be connected. 704 * @param filter The filter criteria. 705 * @throws ctkInvalidArgumentException If <code>filter</code> contains an 706 * invalid filter string that cannot be parsed. 707 * @throws ctkIllegalStateException If this ctkPluginContext is no 708 * longer valid. 709 * @see ctkServiceEvent 710 * @see disconnectServiceListener() 711 * @see ctkEventBus 712 */ 713 void connectServiceListener(QObject* receiver, const char* slot, 714 const QString& filter = QString()); 715 716 /** 717 * Disconnects a slot which has been previously connected 718 * with a call to connectServiceListener(). 719 * 720 * @param receiver The object containing the slot. 721 * @param slot The slot to be disconnected. 722 * @see connectServiceListener() 723 */ 724 void disconnectServiceListener(QObject* receiver, const char* slot); 725 726 protected: 727 728 friend class ctkPluginFrameworkPrivate; 729 friend class ctkPlugin; 730 friend class ctkPluginPrivate; 731 732 ctkPluginContext(ctkPluginPrivate* plugin); 733 734 ctkPluginContextPrivate * const d_ptr; 735 736 private: 737 Q_DECLARE_PRIVATE(ctkPluginContext) 738 }; 739 740 741 #endif /* CTKPLUGINCONTEXT_H_ */ 742