#ifndef __tdeparts__genericfactory_h__ #define __tdeparts__genericfactory_h__ #include #include #include #include #include namespace KParts { /** * @internal */ template class GenericFactoryBase : public KParts::Factory { public: GenericFactoryBase() { if ( s_self ) kdWarning() << "KParts::GenericFactory instantiated more than once!" << endl; s_self = this; } virtual ~GenericFactoryBase() { delete s_aboutData; delete s_instance; s_aboutData = 0; s_instance = 0; s_self = 0; } static TDEInstance *instance(); static TDEAboutData *aboutData(); protected: virtual TDEInstance *createInstance() { return new TDEInstance( aboutData() ); } virtual void virtual_hook( int id, void *data ) { if ( id != VIRTUAL_QUERY_INSTANCE_PARAMS ) { KParts::Factory::virtual_hook( id, data ); return; } QueryInstanceParams *params = reinterpret_cast( data ); params->instance = instance(); } private: static GenericFactoryBase *s_self; static TDEInstance *s_instance; static TDEAboutData *s_aboutData; }; /** * A template for a KParts::Factory implementation. It implements the pure virtual * createPartObject method by instantiating the template argument when requested * through the className field. In addition it is a container for a part's TDEInstance * object, by providing a static TDEInstance *instance() method. * * The template argument has to inherit from KParts::Part and has to implement two methods: * 1) There needs to be a public constructor with the following signature: * MyPart( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const TQStringList& args ) * * 2) It needs to provide one static method to create a TDEAboutData object per * request, holding information about the component's name, its authors, license, etc. * The signature of that static method has to be * TDEAboutData *createAboutData() * * The template will take care of memory management of the TDEInstance and the TDEAboutData object, * meaning ownership of what createAboutData returns is passed to the caller (this template) . * * For advanced use you can also inherit from the template and re-implement additionally the * virtual TDEInstance *createInstance() method, for example in case you want to extend the * paths of your instance's TDEStandardDirs object. * * If a KParts::ReadOnlyPart is requested through this factory and the template argument * implements a KParts::ReadWritePart then setReadWrite( false ) will automatically be * called in createPartObject. * * Use the factory through the K_EXPORT_COMPONENT_FACTORY macro, like that: * \code * typedef KParts::GenericFactory<YourKPart> YourKPartFactory; * K_EXPORT_COMPONENT_FACTORY( yourlibrary, YourKPartFactory ) * \endcode * yourlibrary is the library name that you compiled your KPart into. */ template class GenericFactory : public GenericFactoryBase { public: GenericFactory() { } virtual KParts::Part *createPartObject( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const char *className, const TQStringList &args ) { T *part = KDEPrivate::ConcreteFactory::create( parentWidget, widgetName, parent, name, className, args ); if ( part && !qstrcmp( className, "KParts::ReadOnlyPart" ) ) { KParts::ReadWritePart *rwp = dynamic_cast( part ); if ( rwp ) rwp->setReadWrite( false ); } return part; } }; template class GenericFactory< KTypeList > : public GenericFactoryBase { public: GenericFactory() { } virtual KParts::Part *createPartObject( TQWidget *parentWidget, const char *widgetName, TQObject *parent, const char *name, const char *className, const TQStringList &args ) { TQObject *object = KDEPrivate::MultiFactory< KTypeList >::create( parentWidget, widgetName, parent, name, className, args ); // (this cast is guaranteed to work...) KParts::Part *part = dynamic_cast( object ); if ( part && !qstrcmp( className, "KParts::ReadOnlyPart" ) ) { KParts::ReadWritePart *rwp = dynamic_cast( part ); if ( rwp ) rwp->setReadWrite( false ); } return part; } }; /** * @internal */ template GenericFactoryBase *GenericFactoryBase::s_self = 0; /** * @internal */ template TDEInstance *GenericFactoryBase::s_instance = 0; /** * @internal */ template TDEAboutData *GenericFactoryBase::s_aboutData = 0; /** * @internal */ template TDEInstance *GenericFactoryBase::instance() { if ( !s_instance ) { if ( s_self ) s_instance = s_self->createInstance(); else s_instance = new TDEInstance( aboutData() ); } return s_instance; } /** * @internal */ template TDEAboutData *GenericFactoryBase::aboutData() { if ( !s_aboutData ) s_aboutData = T::createAboutData(); return s_aboutData; } } #endif