[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kfm-devel
Subject:    Re: Plugins for non-major Parts
From:       Simon Hausmann <hausmann () kde ! org>
Date:       2001-09-11 8:16:04
[Download RAW message or body]

On Mon, Sep 10, 2001 at 05:17:37PM -0700, Kurt Granroth wrote:
> It's easy enough to create plugins for the major Parts like KHTMLPart and 
> KonqDirPart.. but what about run-of-the-mill parts?
> 
> You see, to *effectively* use a Part, the plugin needs to
> 
> a) link to the part's library file
> b) cast to the parent() to the part, thus must include the part's header file
> 
> This isn't a problem with KHTMLPart or KonqDirPart since both are part of 
> major libraries (libkhtml and libkonq, resp.) and thus have their libraries 
> and header files already installed.
> 
> By default for "normal" Parts, though, there is no installed header and 
> moresoe, the library is installed in $KDEDIR/lib/kde2/ and not in $KDEDIR/lib 
> (thus making linking difficult).
> 
> Has this already been thought of and I'm just missing the solution?  Or does 
> something need to be done, here?

Well, I think that's absolutely normal. If you write a plugin to a component
and you want to call methods or change properties beyond of what the standard
discovery facitilites of Qt provide (signals/slots, properties, etc.) then
you need a well defined interface. That can either be part of a public (exported)
base class of the component or a pure abstract C++ interface which involves
no library dependency. In either way you need a header file declaring your 
interface. The main difference between the normal class and library based
interfacing opposed to the abstract interfacing is that for the latter you can't
use signal/slot sugar (or anything QObject provides) and that it is hard to
discover an implementation of that interface safely. That means you can't
cast the reference to the component you get in form of a QObject pointer
safely to your pure abstract interface structure (can't use RTTI I think) .

What we could do is to provide a method in KParts::Part (to that one you can
cast safely) to retrieve a reference to a QUnknownInterface object. From that
one on you could can safely cas^H^H^Hquery to your pure abstract interface
by unique id.

The reason why I favour a separate method in contrast to direct virtual 
inheritance of KParts::Part from QUI is because KParts::Part inherits from
QObject which strictly speaking conflicts with QUI in terms of lifetime
management (that is, a QUI is refcounted while a QObject has different
lifetime management (parent/child mechanism) . Although one could do
hacks like the part ref()'ing itself to avoid dying too early I think
we should instead separate that clearly in our interface. People who
feel like doing that hack for convenience can still do so by inheriting
themselves from QUI and making that methods return a this pointer.

A 'merge' with the world of QUI imposes another problem: For KParts 
components it is clearly defined when a library holding a component
can be unloaded. It's when all objects created by the initial factory
have been destroyed. By providing a 'bridge' to QUI however it could
happen that all parts die but someone still having a reference to a
QUI component, initially retrieved from a part. (and we can't connect
to any sort of destroyed() signal here ;-)

I think the solution Qt provides for that is to utilize the 
QLibrayInterface and let the component itself decide when
it is capable of being unloaded.

Maybe we should use a similar trick to query a QUI from a KLibFactory
for being able to ask for a QLibraryInterface from that to be able to
ask with canUnload() . A bit of an experimental thought, I admit ;-)


Simon

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic