[PATCH] kcmoduleinfo [WAS] Plugin linking problem

Matthias Kretz kretz at kde.org
Fri Aug 10 14:33:43 BST 2007


On Friday 10 August 2007, David Faure wrote:
> On Friday 10 August 2007, Simon Hausmann wrote:
> > On Friday 10 August 2007 10:41:16 Matthias Kretz wrote:
> > > On Friday 10 August 2007, Rafael Fernández López wrote:
> > > > Adapting more *.desktop files (now on kdepim) I see that on this
> > > > module this is pretty common. For example, note that:
> > >
> > > Yes, one could probably say that kdepim is the reason X-KDE-FactoryName
> > > exists.
> > >
> > > The right solution IMHO would be to have still one entry point though
> > > that returns one factory object but this one factory then creates the X
> > > different KCMs. Somehow it sounds wrong to me to have one library with
> > > X different factories to instantiate a plugin class.
> >
> > That's exactly what I was thinking, too.
>
> In fact I don't think it's wrong to have X different factories,

I didn't mean to say that it's wrong

> because it  keeps the code much more modular. You can just link together
> your kcontrol module code and your ktexteditor code plugin code, without the
> need for those two pieces of code to know about each other. If you had to
> create one mega-factory which can create both kinds of things, then you need
> to tie them together at the code level, making future refactorings more
> difficult.

Right.

I just realized KGenericFactory allows creating both a custom plugin and a KCM 
at the same time:

main.cpp:

#include "kcmfoo.h"
#include "pluginfoo.h"
#include <KGenericFactory>

typedef K_TYPELIST_2(KcmFoo, PluginFoo) Products;
K_EXPORT_COMPONENT_FACTORY(foo, KGenericFactory<Products>)

did any code ever use this?

Anyway, by deriving from a KCModuleFactory type of class it could look like 
this:

factory.h:
class MyFactory : public KGenericFactory
{
public:
  MyFactory();
  QObject *createObject(const KService::Ptr& service, QObject *parent, const 
char *className, const QStringList &args);
};

factory.cpp:
MyFactory::MyFactory() : KGenericFactory("kComponentDataName") {}

QObject *MyFactory::createObject(const KService::Ptr& service, QObject 
*parent, const char *className, const QStringList &args)
{
  const QString key = service->desktopEntryName();
  if (key == "kcm_foo") {
    return new KcmFoo(parent, args);
  } else if (key == "plugin_foo") {
    return new PluginFoo(parent, args);
  }
  return 0;
}

Q_EXPORT_PLUGIN2(foo, MyFactory)


This way other code can also call
MyFactory::componentData()
to access the KComponentData object that'll be shared for the whole DSO.


The reason why I like to have one factory instead of many is that IMHO it's 
more transparent what's happening, or perhaps you can ignore the details of 
how the entry symbol is constructed: no need to know about X-KDE-FactoryName 
and you can use Q_EXPORT_PLUGIN2.
Also with this approach the number of classes that can be instantiated is 
variable which is what is needed for implementing plugins using scripting 
languages without having to implement a C++ factory for every single 
plugin...

-- 
________________________________________________________
Matthias Kretz (Germany)                            <><
http://Vir.homelinux.org/
MatthiasKretz at gmx.net, kretz at kde.org,
Matthias.Kretz at urz.uni-heidelberg.de
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
URL: <http://mail.kde.org/pipermail/kde-core-devel/attachments/20070810/41414b7d/attachment.sig>


More information about the kde-core-devel mailing list