So, I got my thesis done, updated the Comic Project Management Tools, and had a lot of time left till I got my thesis results(I did not pass >_> sadly). One thing that was sort of bugging me was that after all the work I did on the CPMT, there just wasn’t much movement happening in Peruse, the KDE comic book reader that can read comic books with ACBF files and make use of the extra functionality.
So, it was time to do some moving myself.
Building and running.
Peruse doesn’t have much in way of configuration. All the dependancies were available on Kubuntu 17.10. What however was tricky was that I just could not get my installation running. Peruse, you see, uses QML for it’s GUI. And if you install a program with QML locally(instead of systemwide), for some reason on Ubuntu, at the least, the QML files get placed somewhere else than where the program expects them to be.
I had this problem before with Krita’s QML elements, the touch docker, and before that the Krita Sketch GUI.
Turns out that what needs to be done is that you not only add the regular executable PATH for peruse to the enviroment variables, but also QT_PLUGIN_PATH and QML2_IMPORT_PATH. Peruse makes a handy little bash file with the appropriate paths upon build in the build directory, and I was able to find a similar solution to use to get Krita’s touch docker to work for me. This one is kind of hard to figure out though, and I still don’t know the why and how of this one beyond the obvious ‘paths wrong, point to correct paths manually’.
Starting with an unfamiliar source: Dox, dox, dox.
So, because I was starting with an unfamiliar source I started out with doing function documentation. Usually within KDE function documentation is welcomed (as long as you’re willing to make changes to you patch when you’re wrong, which is not really that controversial :p ), and it is a really good way to get to know the source.
Peruse has two programs it builds: Peruse and Peruse Creator. Both of these use the contents of the ACBF library for reading/writing ACBF files, as well as a qtquick plugin, which provide some objects for handling comic archives and their metadata.
Peruse the comic book reader also uses several files in the qtquick plugin together with another qtquick plugin under content list where the search is handled, to set up its catalogue and making it browsable.
- Docs for the acbf library.
- Adding docs to contentlist and qtquick folders
- Adding descriptions to almost all the qml files.
I also did some really small fixes in between to get to know the code, but soon enough I got to an idea that might be a be a bit frustrating for leinir(the maintainer) to review each and every single commit for, so I started to work in a branch for this…
So the first thing I did was update the ACBF library to ACBF 1.1. This involved getting references, stylesheets and several new keys in. Another thing that got added with this was that according to the official ACBF 1.1 xsd, authors can have multiple emails and homepages, so the class was updated to handle that.
This was largely uneventful, except that I had this weird bug where the parsing would not go right because certain pointers were not initialized. That is not weird the way I describe it, pointers should be initialized! No, the weird thing was that it just made the parsing go awry instead of, you know, crashing.
So, next up was actually making use of the new stuff that could be parsed and written. There were several places this could be done, but the easiest place by far was Peruse Creator.
Peruse Creator could, when I started working on it, update the title, authors, genres, genre match and character names. This felt a bit sparse, and I often had opened Peruse Creator to stare at the metadata entries and wonder why not at the least there was an editor for ‘sequence'(series).
Now it can also handle annotation, keywords, sequence, database references, content rating, reading direction, publisher, publishing date, city, isbn, license, document author, document sources, document history, document version and general page background color.
The most difficult part here was that making lists of objects in QML requires making a library a QML plugin, and leinir had wanted to avoid that for the ACBF library. This was the reason why there were no editors for things like Sequence, Database Reference and Content Rating. So instead we have this pattern where we take a list of objects, write a count function for it and have a ‘countChanged’ signal. From those two we make a read-only property. Then we add a ‘getObjectByIndex’ type of function to get the objects, ‘removeByIndex’ and ‘addObjectAtIndex/createObjectFromStrings’, and make all of these invokable.
This pattern mostly works, except when swapping, because if you assign a QML Repeater to use an integer as model, it just won’t update when the signal for integer update is fired due to items swapping, because, duh, the number of items obviously hasn’t changed! This was something that showed up with the frames, textareas and jumps.
So instead of using integers there, a stringlist was made. As these objects were mostly unique by the points they took up, a string of the points is used to identify the object within a stringlist for similar objects. This will force QML Repeaters and Listviews to update when the stringlist has items swapped, and has the benefit of giving something to debug with when things go awry. I am pretty pleased I got this working in Peruse, because reordering page areas is one place where the Krita Comic Manager plugin is kind of difficult to use.
It ended up being a big exercise in how to use QML, overal. I think my biggest victory was when I got the bounding boxes of the page areas(frames/textareas/jumps) to draw, color coded and all, correctly on the viewport.
That said, Peruse Creator can now besides adding/removing/reordering pages also edit their contents, meaning we can add titles, transitions, set background colors and add page areas such as frames/jumps/textareas. The latter can only do rectangles for now, for the simple reason that with Qt 5.9 the only thing that can be drawn on screen are Rectangles and ellipses(rounded Rectangles). With Qt 5.11 there’s also the Shape object, which would be able to handle more, but I am currently bound to 5.9. Having rectangles is a pretty big deal already. Because being able to access them in Peruse Creator meant work could also be done to get them in Peruse regular…
So, the above patch makes it possible for Peruse regular to use frames to as a guide for zooming in on a page. This seems a bit overly fancy for desktop, but on Mobile it can be super handy. Unfortunately I couldn’t figure out how to get the next/previous to hook up to next frame/previous frame, which would’ve been even cooler, but leinir is gonna look at that :3
On using QML for the first time.
That QML would come across as a very different programming language was to be expected, it is declarative programming after all. The biggest surprise for me was how in QML items and objects are parented to one another, and if not, anchored in some way or another and can be modified by things like animations which get parented to the widget it should animate. This is the biggest difference in looking at how to order a layout in QML compared to regular Qt widgets, where everything is in a layout and you can sort of force it to lay out slightly differently by using the QSizePolicy and Spacers, and if you want to animate you need to modify the paintEvent. That was the primary thing that I had to abandon when using QML.
Once I got past that, the biggest annoyance was trying to find the proper documentation. As hinted before, Qt 5.11 has had quite a few improvements on QML on Qt 5.9, and as the docs point at the latest and greatest by default… Let’s say I had quite a few moments where I was wondering why I could not use this function even though it was obviously in the docs. Qt widgets themselves do not update a lot in functionality between released, so when you’re used to programming with Qt widgets, going to QML the amount of things that change between versions can throw you for a loop.
Other than that, it is indeed very easy to do shiny things in QML, but sometimes I wished there was a document to help my Qt Widgets geared brain to figure out how to do things in QML. Like, ‘this is how you stuff things in a row, this is how you stuff them in a column, or a grid, (there’s seperate layout QML items for this, it turns out), this is how you make a nice date/time editor without spending your whole day figuring this stuff out,’ etc. On top of that, the weird stuff with setting up a local install on Ubuntu as noted above is also a big hurdle, and I wish it would be documented better because it is very hard to find solutions if all you know is that a program with QML is not finding it’s QML files on Ubuntu.
Trying to get translating ACBF files to work.
So, my changes removed the translatable title entries, because it seemed to me these needed a dedicated translation system. In lieu of trying to figure out the appropriate gui for this, I thought it might be nice to just generate POT files and parse PO files, but this was blocked by the KDE translation coordinator on the basis of homebrew code being flakey and easy breaking. He suggested using gettext directly, which would require first getting to know that library and then trying to figure out how to hide all of this functionality when gettext isn’t available because gettext is near impossible to build on Windows because GNU. So I am just going to kind of abandon this idea…
On the plus side, the translation coordinator also set up Peruse to be included into the KDE translation system, so Peruse can be translated now! But not translate ACBF files.
This was a little detour, but also makes use of the ACBF library. I’ve been writing a lot about different comic metadata files before. And I’ve, honestly gotten a little depressed seeing that these other metadata files are under documented and their programs have stopped being maintained, so I’m trying to get as much information for the files documented and thus also wrote a parser so that people who’d been using these formats can now switch to Peruse without losing their tags and notes. The code was debugged by running a zip file of the Killing Joke through ComicTagger, a program that allows you to write a ComicInfo.xml and get the information directly from ComicVine.
I had wanted to get ComicBookInfo done as well, but unfortunately KArchive doesn’t have the functionality to get ZIP comments(it does sort of know about zip comments, but just enough to avoid their existence from messing up the parsing of a zip file).
Editing the book entry system.
So after doing all that, the next section was editing the book entry system, aka, the Catalogue. This system consists of a CategoryModel which can hold subcategories and comic, and each which can hold subcategories and comics themselves.
So, this was done in one big patch, because I was editing those entries anyway, and I really wanted access to the KFileMetaData from Peruse.
Multiple series and authors was something that had been in the tracker for a while, and now Peruse can give you the full list of authors whose work you have and you’d want to, well, ‘Peruse’… as long as the metadata is there.
KFileMetaData::UserMetaData is probably better known to most people as the little stars/tagging/comments system in Dolphin. I believe some other KDE programs make use of it(Amarok?), but Peruse used it mainly to keep track of the last read page. Now, in the dialog where you have finished reading a comic, you can set the rating/tags/user comment for that book, and it’ll be updated directly in Dolphin too. This was something I really really wanted to get in, because if you read a lot of comics, especially indie and amateur work, some of which can be quite forgettable, you’d want to leave a comment to your future self to remember what you thought of it, or, if you stopped reading, why you stopped reading it.
This was basically an open door. There was no publisher category model, so one just needed to be defined and entries needed to be added based on their publisher string.
This one, as you can see from the review, was a little controversial. On one hand, we should not have missing entries visible in Peruse (they look amazingly glitchy, for one), but on the other hand, the whole point of making a database cache was to avoid the slowdown you get when checking for entries, and on the third hand(foot?) QFileInfo caches a little itself too? Either way, we decided to just go for it and if it turns out to slow down start up a lot we’ll know where to start optmizing.
Bugfixes and other stuff.
Between all this I got so significantly comfortable with the code that I got to the point deciding which items need reviewing (unfamilair territory, behaviour changes), and which didn’t (fixes that remove warnings, bug fixes). And I was able to fix some of my own bug reports too!
- Show thumbnails in the search results box.
- Make switching to new books in a series easier.
- Add press indicator to Book tiles in bookshelf.
- Fix Toggling of Global Drawer actions.
- Make sure these i18n tags are i18nc tags.
- BUG:398256 Allow the mouse areas to switch functionality when reading direction is flipped.
- BUG: 398417 Add little buttons on hover for the page mouse areas.
- BUG 398254 Remove call to non-exitent function.
- BUG:398327 Make delete book work.
- Avoid duplicate entries.
- Preserve file suffix when copying files into archive.
So, what’s left?
A lot still, actually. The scariest part is a crash bug with getting the book thumbnails through KIO. This one shows up a lot with moderately sized comic collections(it starts happening at more than 10 entries), and can make it really hard to read series with Peruse. It is on the plus side also the only crash with Peruse I’ve found.
Other than that there’s about a handful of bugs left in the tracker, of a variety. Other things that could be done are making the search more flexible(it can now only search through file names, being able to search through titles, authors, characters and more would be cool too), and coming up with a nice way to look at the leftover metadata, getting text areas and translations to work, making Peruse Creator’s textarea editing nicer, updating the cache after it has been generated, and I could go on for a while.
I myself am working right now on making use of genre, keywords and character names in a rudimentary manner, and there’s still little things left and right I’ll poke at myself 🙂