diff options
Diffstat (limited to 'kparts/componentfactory.h')
-rw-r--r-- | kparts/componentfactory.h | 401 |
1 files changed, 401 insertions, 0 deletions
diff --git a/kparts/componentfactory.h b/kparts/componentfactory.h new file mode 100644 index 000000000..01616d89f --- /dev/null +++ b/kparts/componentfactory.h @@ -0,0 +1,401 @@ +#ifndef __kparts_componentfactory_h__ +#define __kparts_componentfactory_h__ + +#include <kparts/factory.h> +#include <kparts/part.h> +#include <ktrader.h> +#include <qmetaobject.h> + +namespace KParts +{ + + // this is a namespace and not a class because stupid egcs 1.1.2 doesn't grok + // static template methods in classes. !@%@#$! + /** + * Namespace for KParts components + */ + namespace ComponentFactory + { + /** + * This enum type defines the possible error cases that can happen + * when loading a component. + * + * <ul> + * <li><code>ErrNoServiceFound</code> - no service implementing the + * given mimetype and fullfilling the given constraint expression + * can be found.</li> + * <li><code>ErrServiceProvidesNoLibrary</code> - the specified service + * provides no shared library</li> + * <li><code>ErrNoLibrary</code> - the specified library could not be + * loaded. Use KLibLoader::lastErrorMessage for details.</li> + * <li><code>ErrNoFactory</code> - the library does not export a factory + * for creating components</li> + * <li><code>ErrNoComponent</code> - the factory does not support creating + * components of the specified type</li> + * </ul> + */ + enum ComponentLoadingError { ErrNoServiceFound = 1, + ErrServiceProvidesNoLibrary, + ErrNoLibrary, + ErrNoFactory, + ErrNoComponent }; + + /** + * This template function allows to ask the given factory to create an + * instance of the given template type. + * + * Example of usage: + * \code + * MyPlugin *plugin = KParts::ComponentFactory::createInstanceFromFactory<MyPlugin>( factory, parent ); + * \endcode + * + * @param factory The factory to ask for the creation of the component + * @param parent The parent object (see QObject constructor) + * @param name The name of the object to create (see QObject constructor) + * @param args A list of string arguments, passed to the factory and possibly + * to the component (see KLibFactory) + * @return A pointer to the newly created object or a null pointer if the + * factory was unable to create an object of the given type. + */ + template <class T> + static T *createInstanceFromFactory( KLibFactory *factory, QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList() ) + { + QObject *object = factory->create( parent, name, + T::staticMetaObject()->className(), + args ); + + T *result = dynamic_cast<T *>( object ); + if ( !result ) + delete object; + return result; + } + + /** + * This template function allows to ask the given kparts factory to create an + * instance of the given template type. + * + * Example of usage: + * \code + * KViewPart *doc = KParts::ComponentFactory::createPartInstanceFromFactory<KViewPart>( factory, parent ); + * \endcode + * + * @param factory The factory to ask for the creation of the component + * @param parentWidget the parent widget for the part + * @param widgetName the name of the part's widget + * @param parent The parent object (see QObject constructor) + * @param name The name of the object to create (see QObject constructor) + * @param args A list of string arguments, passed to the factory and possibly + * to the component (see KLibFactory) + * @return A pointer to the newly created object or a null pointer if the + * factory was unable to create an object of the given type. + */ + template <class T> + static T *createPartInstanceFromFactory( KParts::Factory *factory, + QWidget *parentWidget = 0, + const char *widgetName = 0, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList() ) + { + KParts::Part *object = factory->createPart( parentWidget, widgetName, + parent, name, + T::staticMetaObject()->className(), + args ); + + T *result = dynamic_cast<T *>( object ); + if ( !result ) + delete object; + return result; + } + + /** + * This template allows to load the specified library and ask the + * factory to create an instance of the given template type. + * + * @param libraryName The library to open + * @param parent The parent object (see QObject constructor) + * @param name The name of the object to create (see QObject constructor) + * @param args A list of string arguments, passed to the factory and possibly + * to the component (see KLibFactory) + * @param error + * @return A pointer to the newly created object or a null pointer if the + * factory was unable to create an object of the given type. + */ + template <class T> + static T *createInstanceFromLibrary( const char *libraryName, QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + KLibrary *library = KLibLoader::self()->library( libraryName ); + if ( !library ) + { + if ( error ) + *error = ErrNoLibrary; + return 0; + } + KLibFactory *factory = library->factory(); + if ( !factory ) + { + library->unload(); + if ( error ) + *error = ErrNoFactory; + return 0; + } + T *res = createInstanceFromFactory<T>( factory, parent, name, args ); + if ( !res ) + { + library->unload(); + if ( error ) + *error = ErrNoComponent; + } + return res; + } + + template <class T> + static T *createPartInstanceFromLibrary( const char *libraryName, + QWidget *parentWidget = 0, + const char *widgetName = 0, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + KLibrary *library = KLibLoader::self()->library( libraryName ); + if ( !library ) + { + if ( error ) + *error = ErrNoLibrary; + return 0; + } + KLibFactory *factory = library->factory(); + if ( !factory ) + { + library->unload(); + if ( error ) + *error = ErrNoFactory; + return 0; + } + KParts::Factory *partFactory = dynamic_cast<KParts::Factory *>( factory ); + if ( !partFactory ) + { + library->unload(); + if ( error ) + *error = ErrNoFactory; + return 0; + } + T *res = createPartInstanceFromFactory<T>( partFactory, parentWidget, + widgetName, parent, name, args ); + if ( !res ) + { + library->unload(); + if ( error ) + *error = ErrNoComponent; + } + return res; + } + + template <class T> + static T *createInstanceFromService( const KService::Ptr &service, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + QString library = service->library(); + if ( library.isEmpty() ) + { + if ( error ) + *error = ErrServiceProvidesNoLibrary; + return 0; + } + + return createInstanceFromLibrary<T>( library.local8Bit().data(), parent, + name, args, error ); + } + + template <class T> + static T *createPartInstanceFromService( const KService::Ptr &service, + QWidget *parentWidget = 0, + const char *widgetName = 0, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + QString library = service->library(); + if ( library.isEmpty() ) + { + if ( error ) + *error = ErrServiceProvidesNoLibrary; + return 0; + } + + return createPartInstanceFromLibrary<T>( library.local8Bit().data(), parentWidget, + widgetName, parent, name, args, error ); + } + + template <class T, class ServiceIterator> + static T *createInstanceFromServices( ServiceIterator begin, ServiceIterator end, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + for (; begin != end; ++begin ) + { + KService::Ptr service = *begin; + + if ( error ) + *error = 0; + + T *component = createInstanceFromService<T>( service, parent, name, + args, error ); + if ( component ) + return component; + } + + if ( error ) + *error = ErrNoServiceFound; + + return 0; + + } + + template <class T, class ServiceIterator> + static T *createPartInstanceFromServices( ServiceIterator begin, + ServiceIterator end, + QWidget *parentWidget = 0, + const char *widgetName = 0, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + for (; begin != end; ++begin ) + { + KService::Ptr service = *begin; + + if ( error ) + *error = 0; + + T *component = createPartInstanceFromService<T>( service, parentWidget, + widgetName, parent, + name, args, error ); + if ( component ) + return component; + } + + if ( error ) + *error = ErrNoServiceFound; + + return 0; + + } + + /** + * This method creates and returns a plugin, from the trader query for a given serviceType. + * + * Example: + * \code + * KMyAppPlugin* plugin = KParts::ComponentFactory::createInstanceFromQuery<KMyAppPlugin>( serviceType, QString::null, parentObject ); + * if ( plugin ) { + * .... + * } + * \endcode + * + * @param serviceType the type of service for which to find a plugin + * @param constraint an optional constraint to pass to the trader (see KIO::KTrader) + * @param parent the parent object for the part itself + * @param name the name that will be given to the part + * @param args A list of string arguments, passed to the factory and possibly + * to the component (see KLibFactory) + * @param error The int passed here will receive an error code in case of errors. + * (See enum #ComponentLoadingError) + * @return A pointer to the newly created object or a null pointer if the + * factory was unable to create an object of the given type. + */ + template <class T> + static T *createInstanceFromQuery( const QString &serviceType, + const QString &constraint = QString::null, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + KTrader::OfferList offers = KTrader::self()->query( serviceType, constraint ); + if ( offers.isEmpty() ) + { + if ( error ) + *error = ErrNoServiceFound; + return 0; + } + + return createInstanceFromServices<T>( offers.begin(), + offers.end(), + parent, name, args, error ); + } + + /** + * This method creates and returns a KParts part from a serviceType (e.g. a mimetype). + * + * You can use this method to create a generic viewer - that can display any + * kind of file, provided that there is a ReadOnlyPart installed for it - in 5 lines: + * \code + * // Given the following: KURL url, QWidget* parentWidget and QObject* parentObject. + * QString mimetype = KMimeType::findByURL( url )->name(); + * KParts::ReadOnlyPart* part = KParts::ComponentFactory::createPartInstanceFromQuery<KParts::ReadOnlyPart>( mimetype, QString::null, parentWidget, 0, parentObject, 0 ); + * if ( part ) { + * part->openURL( url ); + * part->widget()->show(); // also insert the widget into a layout, or simply use a QVBox as parentWidget + * } + * \endcode + * + * @param serviceType the type of service for which to find a part, e.g. a mimetype + * @param constraint an optional constraint to pass to the trader (see KTrader) + * @param parentWidget the parent widget, will be set as the parent of the part's widget + * @param widgetName the name that will be given to the part's widget + * @param parent the parent object for the part itself + * @param name the name that will be given to the part + * @param args A list of string arguments, passed to the factory and possibly + * to the component (see KLibFactory) + * @param error The int passed here will receive an error code in case of errors. + * (See enum #ComponentLoadingError) + * @return A pointer to the newly created object or a null pointer if the + * factory was unable to create an object of the given type. + */ + template <class T> + static T *createPartInstanceFromQuery( const QString &serviceType, + const QString &constraint, + QWidget *parentWidget = 0, + const char *widgetName = 0, + QObject *parent = 0, + const char *name = 0, + const QStringList &args = QStringList(), + int *error = 0 ) + { + KTrader::OfferList offers = KTrader::self()->query( serviceType, QString::fromLatin1("KParts/ReadOnlyPart"), constraint, QString::null ); + if ( offers.isEmpty() ) + { + if ( error ) + *error = ErrNoServiceFound; + return 0; + } + + return createPartInstanceFromServices<T>( offers.begin(), offers.end(), + parentWidget, widgetName, + parent, name, args, error ); + } + + } + +} + +/* + * vim: et sw=4 + */ + +#endif + |