DevHeads.net

Prepping KDirModel and KFileItem for QML

Hi,

In my project i need to use the KDirModel and KFileItem
functionalities. KDirModel is exposed through the custom class that
Marco Martin made [1] and it works. However, that custom class does
(apparently) need to expose some QML ready data hence the get function
[2] (from line 99).

So i was thinking: Why don't we just make KFileItem available in QML.
It doesn't have to be a QML component, but if KFileItem where to have
Q_PROPERTY lines then most of the data would already be possible to
make available. I did this in my code and it works rather nice though
i inherited KFileItem as "FileItem". It's a header only class [3].

Also while doing this it made me realize that KDirModel only needs
minor changes for it to work in QML as well. Most notably are the
roles [4] that will have to be exposed to QML. That's something Marco
made a start with in DirModel and i made it more complete in my
version [5].

What i want to do is discuss these changes that Marco and I have made
and merge them back in kdelibs 4.10 branch in KDirModel and KFileItem.
Then KDirModel (not KFileItem) still has to be made available in QML.
I want to do that in either org.kde.plasma.core or introduce a new
import for kdelibs components and name that: "org.kde.libs" or
something along those lines. The latter one has my preference since it
really doesn't belong in plasma.

Another thing i would like to discuss is exposing things and settings.
For example, the current DirModel from both Marco and I have a
hardcoded thumbnail size (not exposed to QML). "if" that thumbnail
even belongs in the model is a question i have (i think it should be a
separate component) and even if it does belong in the model then it
should be a settable property. Perhaps with a default value. Last
thing is what about the properties of KFileItem that are not directly
exposable to QML. Non exposable functions:
- ACL() (due to KACL not being available in QML)
- assign(KFileItem) (possible, but would we want that?)
- cmp(KFileItem) (possible, but would we want that?)
- determineMimeType() (due to return type not being available in QML)
- entry() (due to return type not being available in QML)
- extraData() (ehh..?)
- ... and a bunch of others.

And what needs to be done with refresh? As the header currently stands
[3] it's all static data. Would we want refresh to be working and
change the data? In my case i don't need that functionality because i
only pull up the KFileItem data when i actually click a file.

Cheers,
Mark

[1] <a href="http://quickgit.kde.org/?p=plasma-mobile.git&amp;a=tree&amp;h=0be8c2064e1f1991df9196878d506de0eed688f5&amp;hb=7ad9867427078918939f8d5a0be6201368ede63f&amp;f=components%2Fdirmodel" title="http://quickgit.kde.org/?p=plasma-mobile.git&amp;a=tree&amp;h=0be8c2064e1f1991df9196878d506de0eed688f5&amp;hb=7ad9867427078918939f8d5a0be6201368ede63f&amp;f=components%2Fdirmodel">http://quickgit.kde.org/?p=plasma-mobile.git&amp;a=tree&amp;h=0be8c2064e1f1991df...</a>
[2] <a href="http://quickgit.kde.org/?p=plasma-mobile.git&amp;a=blob&amp;h=1539ae3d6cf54f96af216593e5c7517df820a6b8&amp;hb=7ad9867427078918939f8d5a0be6201368ede63f&amp;f=components%2Fdirmodel%2Fdirmodel.cpp" title="http://quickgit.kde.org/?p=plasma-mobile.git&amp;a=blob&amp;h=1539ae3d6cf54f96af216593e5c7517df820a6b8&amp;hb=7ad9867427078918939f8d5a0be6201368ede63f&amp;f=components%2Fdirmodel%2Fdirmodel.cpp">http://quickgit.kde.org/?p=plasma-mobile.git&amp;a=blob&amp;h=1539ae3d6cf54f96af...</a>
[3] <a href="https://gitorious.org/porpoise/master/blobs/master/fileitem.h" title="https://gitorious.org/porpoise/master/blobs/master/fileitem.h">https://gitorious.org/porpoise/master/blobs/master/fileitem.h</a>
[4] <a href="http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKDirModel.html#ac91fa3775de77f10d77db06276512d47" title="http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKDirModel.html#ac91fa3775de77f10d77db06276512d47">http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKDirModel.html#...</a>
[5] <a href="https://gitorious.org/porpoise/master/blobs/master/dirmodel.cpp#line44" title="https://gitorious.org/porpoise/master/blobs/master/dirmodel.cpp#line44">https://gitorious.org/porpoise/master/blobs/master/dirmodel.cpp#line44</a>

Comments

Re: Prepping KDirModel and KFileItem for QML

By Aaron J. Seigo at 11/17/2012 - 12:04

On Saturday, November 17, 2012 16:22:07 Mark wrote:
because this means making KFileItem a QObject, which makes it non-copyable and
brings in QObject overhead that we don't need.

for QML, accessing the relevant data via the model is probably the easiest
approach anyways ...

Yes, it would be rather nice if all models in kdelibs that are sensibly usable
from QML set roles.

this is frameworks stuff.

probably not "org.kde.libs" .. it's just begging to become a drop zone for
random and unrelated $STUFF. org.kde.dirmodel or org.kde.filesystem would be
good enough in this case? as is happening with frameworks, these things should
be thoughtfully grouped into sensible modules.

why a separate component? i agree that it should (if it isn't already) be both
lazy-loaded and able to be disabled via a property (so usage where this is not
needed avoids the overhead) ... but do we really need a completely separate
component for this? i would expect a fair amount of data duplication if it
were, though some spelunking in the code may show otherwise.

yes, the size should be setable with a sensible default.

you mean updating the KFI when the on-disk file changes? i would hope the model
itself already does that ... ?

Re: Prepping KDirModel and KFileItem for QML

By Mark at 11/17/2012 - 13:02

On Sat, Nov 17, 2012 at 5:04 PM, Aaron J. Seigo < ... at kde dot org> wrote:
Ahh right. So it has to be a subclass.
Not really. Not all data from KFileItem is stored in the Model. You
can see it at the roles that i'm setting. That all data that is
stored. There is a lot more. I guess this depends on style:
1. Add more data to the model thus a "QMLized KFileItem" is not needed anymore.
2. Let the roles be as they are and use a "QMLized KFileItem" for file details.

Yeah. Would a patch for that be accepted in KDE 4.11?
I quite like Kevin' suggestion for "org.kde.kio". That's nicely
grouped and sensible.
Well, now you're getting "slightly odd" things in your model class. It
makes and maintains a KImageCache, creates the actual thumbnails and
puts it on a pixmap. In my opinion that is functionality that has
nothing to do with a model and should be separated out in it's own
class. Something like a "KThumbnail" or "KPreview" which is then also
exposed to QML.
Yes, the model does that, but KFI itself "seems" to have functionality
for it as well. Why else would it have a refresh function. [1]
@Kevin, yes, i meant 4.11 :)

Cheers,
Mark

[1] <a href="http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKFileItem.html#afcd50458f3068076a1101c5b6a3b140a" title="http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKFileItem.html#afcd50458f3068076a1101c5b6a3b140a">http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKFileItem.html#...</a>

Re: Prepping KDirModel and KFileItem for QML

By David Faure at 11/19/2012 - 07:05

On Saturday 17 November 2012 18:02:59 Mark wrote:
No, it should probably be a QObject that owns a KFileItem, as Kevin Krammer
said.

Inheriting from a value class is like having "class Customer : public QString"
-- you wouldn't write that...

I don't have an issue with adding a few trivial roles to KDirModel, but
anything bigger sounds like KF5 material.

Oh come on. Why does everyone "wait on frameworks"? Do you think it will
happen all by itself, magically?

There's 10000 people who expressed interest in frameworks, and 3 actually
doing some work on it. See the issue? This waiting will go on for a very long
time, if people don't start to actually get involved and make it happen.

Yes, the framework will be called kio.

... so that the model can call it?
You seem to assume it's two different functionalities, when in fact it's the
same.

OK, to make this more confusing: there are actually two functionalities, but
not the ones you think.

1) if KDirNotify (a bunch of DBus signals emitted by high-level KIO jobs and
file managers) says something changed in a given directory, KDirLister re-lists
it and updates the KFileItems from the corresponding entry of the new KIO
directory listing.

2) if KDirWatch (local-files change notification e.g. via inotify) says
something changed for a given file (permissions, size...), KDirLister calls
refresh() on the corresponding item, to update its information directly from
the disk.

In general, there is little reason for the apps themselves to call refresh on
a KFileItem, *if* that fileitem is being used in KDirLister/KDirModel.
On a standalone KFileItem it makes sense, of course.

Re: Prepping KDirModel and KFileItem for QML

By Mark at 11/19/2012 - 13:11

On Mon, Nov 19, 2012 at 12:05 PM, David Faure < ... at kde dot org> wrote:
I guess that gives me the go-ahead to put a patch in reviewboard :)
I will wait with that till there is a 4.11 branch.
Yeah, i get the point. But i can't imagine that this relative simple
change in KDirModel (and KFileItem) should only go in KF5 only. What
i'm proposing doesn't add features to kdelibs, it only makes existing
features usable in QML.
Ahh, i get it. So the actual KFileItem can change. I guess that means
that all properties should also have a onChanged signal to notify QML
of the change.
Now i do have one last issue. If KFileItem itself is not going to
inherit from QObject then it can't be used in QML. So the KDirModel
function itemForIndex: [1] can't be called directly from QML because
the return object isn't QObject derived.

My intention is to use KDirModel directly from QML like so:

KDirModel {
id: dirModel
url: "/some/url"
}

Then you can iterate through it like so:
ListView {
model: dirModel
delegate: Text {
text: index
}
}

However, in this case you can't do:
dirModel.indexForItem(index) because of the return object and the
index parameter.

What's the suggested way to fix these issues? I'd like to fix them in
KDirModel itself so that there is no need to subclass KDirModel just
to add an alternative indexForItem method. But to get there the
KFileItem either has to be derived from QObject or another
indexForItem method has to be introduced that returns a class that QML
can use.

[1] <a href="http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKDirModel.html#a0337f0a2fdd1f6cf9db38abd13de6ca1" title="http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKDirModel.html#a0337f0a2fdd1f6cf9db38abd13de6ca1">http://api.kde.org/4.9-api/kdelibs-apidocs/kio/html/classKDirModel.html#...</a>

Re: Prepping KDirModel and KFileItem for QML

By David Faure at 11/19/2012 - 14:00

On Monday 19 November 2012 18:11:06 Mark wrote:
They shouldn't be :)

You usually don't want to provide the same API as a value class, in something
that is not a value class. You found a perfect example of why: because you
want to emit signals from setters, which the value class doesn't do.

No you don't really get the point.
This was a desperate plea for more people to actually make KDE Frameworks
happen... the only valid answer is "right, I'll check it out and help".

This depends on how intrusive the change ends up being. From the rest of this
discussion, QML integration for KDirModel definitely feels like a large
feature.

Yes.

I would actually consider having a KDirModel subclass for better integration
with QML, if new API has to be added. This will keep the C++ class clean,
rather than having public methods that make no sense in the C++ world.

In addition, the QObject-wrapper for file items and the KDirModel subclass that
returns these wrappers, sound like something for a libkiogui to me, while
KFileItem and KDirLister are kiocore (but ok, KDirModel is kiogui too, since
it handles icons and previews). Still, I'd rather see the QML support
separated from KDirModel, just like Qt has different model classes internally
for the declarative stuff.

Re: Prepping KDirModel and KFileItem for QML

By Mark at 11/19/2012 - 14:39

On Mon, Nov 19, 2012 at 7:00 PM, David Faure <faure+ ... at kde dot org> wrote:
That... is one awesome example :)
Thank you for being so clear.
I think i have a clear picture now of what needs to happen now.

1. Add rolenames to KDirModel. (only change in kdelibs)
2. Add a "org.kde.kio" QML Import to kde-runtime
3. in org.kde.kio, add a "FileItem" which exposes functionality of
KFileItem. Not as a QDeclerativeItem, just as a class inheriting
QObject.
4. in org.kde.kio, add a KDirModel subclass (DirModel) and add a
indexForItem that returns a FileItem object. (this is a
QDeclerativeItem)

The above is about the same as i have right now only nicer :)

@David, is there anything else to further improve this in the frameworks?

Re: Prepping KDirModel and KFileItem for QML

By David Faure at 11/19/2012 - 15:01

On Monday 19 November 2012 19:39:19 Mark wrote:
Right, which enforces my point about making this separate: it comes with a
dependency on a different Qt library than the existing code.

Maybe you don't want to call this indexForItem/itemForIndex though, it will
conflict a little bit with the methods from the base class (especially the
itemForIndex one, which would only differ by its return type).
Maybe KIO::QMLFileItem, and indexForQMLFileItem, or something like that.

Yes, create a "declarative" subdir under staging/kio/src/ (which has core and
will have gui and widgets later), and put the code there, with a lib of its
own (libkiodeclarative). I say declarative, but name it after the qt5 library
that this will depend on...

More precisely:

* if this goes into kdelibs-4.x, then first let it go there, then merge 4.x
into frameworks, and then split out the stuff. Otherwise git merge will be lots
of fun.

* if this only goes into frameworks, then create the lib, and put your code
there.

Re: Prepping KDirModel and KFileItem for QML

By Mark at 11/19/2012 - 15:26

On Mon, Nov 19, 2012 at 8:01 PM, David Faure <faure+ ... at kde dot org> wrote:
I will first do the KDE 4.x stuff along with all the suggestions in that area.
once that is done i will try and have some fun with frameworks :)

Re: Prepping KDirModel and KFileItem for QML

By Kevin Krammer at 11/17/2012 - 11:40

Hi Mark,

It might not be necessary to subclass KFileItem (unless you need access to
protected API), a QObject class holding a KFileItem might do as well.

The latter obviously having the advantage that the contained KFI instance's
setters are not exposed, thus guaranteeing that all changes must go through
the QML adaptor's setters, thus making sure proper change notification signals
being emitted.

I believe that the 4.10 branch of all modules is frozen at this point.

I agree. I think we need to come up with a scheme and policy on how to handle
"QML bindings" across our modules in a consistent way.

Some of those, e.g. extraData(), are marked as deprecated, so it wouldn't make
any sense anyway to expose them in new binding API.

Cheers,
Kevin

Re: Prepping KDirModel and KFileItem for QML

By Mark at 11/17/2012 - 11:57

On Sat, Nov 17, 2012 at 4:40 PM, Kevin Krammer < ... at kde dot org> wrote:
Well, i made a subclass because there are not much other ways to do
the same outside of kdelibs. The intention is obviously to merge my
changes back in KFileItem and not subclass it there.
That's oke. I don't expect this to be done today or this week. Just
"sometime" when 4.10 is open would be fine imho.
"org.kde.libs" sounds very sensible to me :) At least for "kdelibs"
functionality that is exposed to QML.
Cheers,
Mark

Re: Prepping KDirModel and KFileItem for QML

By Kevin Krammer at 11/17/2012 - 12:06

On Saturday, 2012-11-17, Mark wrote:
Merging the changes as in adding Q_PROPERTY to KFileItem is not possible due
to KFileItem not being a QObject and Q_PROPERTY requiring a QObject subclass.

You probably meant 4.11

Actually I would go for a more fine grained namespacing, after all we are
trying to move aware from "libs" as a single entity with the KDE Frameworks 5
effort.
Since both classes discussed here are in kdelibs/kio, maybe something more
along the lines of "org.kde.kio"

Cheers,
Kevin