Skip to content

Thursday, 18 August 2022

In this post I'm recording how I implement creating Spaces via NeoChat.

Creating the UI front was rather easy, since I used the same dialog as that for creating room. We could have both room and space creation in same dialog because of how similarly they're represented in Matrix. (Space is just room with one extra event)

space creation

On the functionality side, I had to set the m.room.type key to m.space upon creating the room. This was done by setting creationContent JSON value to the same.

This was my biggest contribution so far! And it was a bit more involved than I expected, so I wanted to write down what I learned.

Here's a screenshot:

KDE Locale settings in system settings, the ones I added are outlined in red

I added the settings there that are in the red box. I also added the Paper size setting earlier in another contribution, but it was pretty simple.

This was not, since Qt did not have builtin functions for these three settings: LC_ADDRESS, LC_NAME and LC_TELEPHONE. I assume it's because only glibc has these settings.

Before I go any further, you can look at the commit in here: Add LC_ADDRESS, LC_IDENTIFICATION, LC_NAME and LC_TELEPHONE to region settings

The settings part themselves

Most of the settings was actually easy to implement, since I could follow the old parts of the code and just reimplement them separately for the LC_ADDRESS and friends.

What gave me most trouble though, were the examples. My post will be mostly about them.

Figuring out how to parse stuff

To get a nice example to see what the locale you're setting looks like, we have to pull the format string from the locale object/file.

For example, Finnish postal_fmt string is %f%N%d%N%b%N%a%N%s %h%t%e%t%r%N%z %T%N%c%N.

Yeah, fun. This website was REALLY helpful during making this: https://lh.2xlibre.net/locale/fi_FI/

Archive it, cherish it.

I was going to make my own silly regexp parser thing, but luckily KDE has something called KMacroExpander::expandMacros, that takes a hashmap and the format string. I gave the job to that method and it returned a nice parsed string.

However... How to get the correct locale? Now THIS, THIS was pain.

nl_langinfo or nl_langinfo_l

I just wanted to tell the C function that hey, I got this locale, how to get it's format string?

After hours of searching, nl_langinfo_l seemed the obvious choice. Except that you need to give it locale_t struct and I still don't know what could give me that struct. There was only ways to make new locales with newlocale and meanwhile it could duplicate existing locales, it also required locale_t.

I tried to make my own locale_t at first since I couldn't find any getlocale_t functions. It was messy and it didn't work, so I just groaned and tried to just use nl_langinfo. What this does is that it gets the information of the locale that is currently active. Close, but not quite.

Due to being unable to get locale_t anywhere, I decided to do something a bit dirty. I set the locale that the example is for with setlocale. So when the example is being built, the locale is active, and thus nl_langinfo can get it's data, without me having to create a new locale_t by hand.

It is not ideal solution. I got asked about it many times. But when I asked how to get locale_t, it was just nowhere to be found. Nobody knew, and I don't blame them. I quickly learned this locale stuff is pretty much dark wizardry that only few understand.

At least the examples were finally working and I didn't see any weird side-effects.

If you, my dear reader, know how to get locale_t from QLocale, do share and I'll do this the proper way.

What if the locales are not generated

I was told quickly that this will not work, if there's no locales generated and all the locale files are still in the /usr/share/i18n/locales/.

So you gotta parse those files. Have fun!

Well, I did actually. It sounded more difficult than it was, but with simple regex I could get the right value: The locale files in the folder were pretty well formatted, so it was quite easy to regex through it. I had to just look for the name of the format, for example postal_fmt, then whitespace, then match and capture the value.

Of course, I didn't loop through all files, but only the file that matches the locale name. So for fi_FI locale we only look for the fi_FI file.

Getting language code from the locale

After the examples were done, we wanted to localize the examples to the native language of the locale the example is shown for. So Finnish address example actually is in Finnish, and not in English.

This felt a bit silly and I feel like there should've been better way to do this.

I could not figure out how to get the locale language shortcode from the locale name.

So the en part of en_US. I couldn't find anything that does this in Qt libraries, there were methods that return the full name of the language but not the first part.

Regex to rescue again, just a simple regex, right? Wrong: ([a-z]*)($|[\-]).*.

This regex first looks for and captures as many lowercase letters there are, then ends the capture when either meeting end of string or \ or -. I am not sure why I added the \ there but I do remember the locale.bcp47Name() returning locales with \ too. Or I was just sleep deprived.

Anyhow,do share if you have an idea for simpler solution, be it simpler regex or "you should've just used this one hidden function."

Some things I learned

Here's few things I learned thanks to the reviewers:

  • Examples should be easy to understand: Instead of having name example like Jane Belle Doe you should have Firstname Middlename Lastname, at least in this context. This helps the user recognize the name order between locales, since in some locales lastname may be first etc.

  • Using i18nc: This will give the translators context besides just the string to translate for. Example: i18nc("This is a contextual translation", "Hello")

  • const is a friend in C++ (and I assume in C as well). If you have a variable that is initialized once but never modified after, just add const in front of it. This tells the compiler that "hey this variable won't change" and also keeps it from accidentally changing. (Usually.)

  • Instead of returning empty QString "", just return {}. Avoids accidental non-empty strings, since the object is empty. Probably other reasons too.

  • Use QLatin1String when comparing strings, it's usually safer so that the decoding/encoding won't mess things up.

Feel free to tell me if you know better why some things are like this. Most of these are based on my own experiences.

Conclusion

So yeah, it was way more involved than I expected. I was honestly expecting Qt having some premade classes and methods for the locale trio, but nope. So I had to get my hands dirty and do it myself.

I may sound grumpy in text but I legit enjoyed it even it was quite challenging for my tiny brain. I've never really worked with C++ before due to people scaring me that it's a scary spooky hellish language.

Well, it certainly is a bit scary language. But I managed to make something nice with it.

Also there was no need for me to be scared of the review process. It was actually super educational and I learned a lot from it. I am thankful for all the people who helped me work on this!!

All in all, I'm proud of myself. I'm proud that I managed to contribute something small like this. And I am super excited to find more things to contribute to.

Just no locales anymore. Please.

Wednesday, 17 August 2022

KDE Akademy 2022
Happy traveller is back. Happy open source conference guy is ready for another trip. This time my destination is KDE Akademy and Barcelona. It's my first time attending to Akademy and I am soooooo excited. It's also my second time in Barcelona. Thanks to my highschool, I have been to Barcelona participating in the Erasmus + mobility program (article in Greek). According to the legent, maybe me kissing weird things in Girona worked just fine (click to see the picture).

You don't need to be a "KDE expert" to join, I know I am not. If you're interested in KDE you should really attend if you can (in person if possible), and not only the weekend of talks, but the whole week! And you should register today!

For those of you who know me, I used to attend conferences alone. This time we are 3 people from my university, the University of Macedonia. We have a newly formed Open Source Team and I would like to bring more people with me, to join global communities.

I will keep this short. More to come soon.

I would like to thank KDE and the community for the opportunity to join such a big conference. I am so happy that I will meet you in person after those 2 years of COVID-19 era.

Sunday, 14 August 2022

This week, I implemented two ways to store the output text.

The first way is that output text will be recorded and saved as a text file. I implement the method saveTextFile(const QString& filePath, const QString& text) of Ocr Tesseract Engine; this function uses QTextStream’s streaming operators, so we can conveniently write and update text into the file. The text file is located with the same path as the Url image.

figure1

The second way is to save the text in XMP. I implement the method saveXMP(const QString& filePath, const QString& text) to do this task. XMP uses a structured container to host similar metadata. An alternative language string is an entry in the XMP tree (based on XML) which will be an additional property for a title or caption tag. A new language version of a label is appended to XML. There is no limit in size and char encoding. XMP is hosted in the image to a dedicated chunk outside the image data/properties.

figure1

This is precisely where digiKam stores the comment entered by the user in the right sidebar named Captions & Tags from the icon view. The advantage of seeing this place is the capability to set more than one text in different languages if the translation is available. In all cases, the default language must be x-default; variant will be hosted in de-DE for German, fr-FR from French, it-IT for Italian, etc. Furthermore, translating and storing recognized text in the new language is an attractive feature too. My mentor prepared the class QOnlineTranslator to be included in digiKam core. Here an example, translating recognize text from English into French

figure1

These two methods are also encapsulated in slotUpdateText(), a function that is called in response to a particular signal “clicked” on a button “Save” after post-processing text in the text editor.

Main commits

For whatever reason Steam Deck pretty much has two default browsers: Google Chrome in Game Mode and Firefox in Plasma aka. Desktop Mode. Firefox is absolutely unusable in Game Mode. Chrome (probably most other Chromium variants as well, I’ve only tried a handful) work okay-ish – at least they don’t go ballistic on touch events but they are not a truly nice experience either.

Readers of Planet KDE probably already know that some KDE applications have convergent GUIs thanks to Plasma Mobile, including the Angelfish web browser. It took some fiddling but after a while I managed to get it into a shape that’s very usable in Game Mode. Without any tweaks Angelfish defaults to use its desktop GUI and thereby runs just fine in Plasma Desktop, perhaps docked to a monitor.

First step is to enter Desktop Mode and install Angelfish from Flathub via Discover and then add it to Steam.

Then within Steam under Properties of Angelfish add this in the Target line to the beginning of the command to force mobile user interface, loading icons, and enlarging the interface elements:

env QT_QUICK_CONTROLS_MOBILE=1 QT_QPA_PLATFORMTHEME=KDE QT_SCALE_FACTOR=2

The resulting command line looks something like this

Next step is to enter Game Mode and select the Web Browser controller layout:

Web Browser controller layout

Here’s a few screenshots of Angelfish running:

In all fairness, Angelfish is a bit barebones. The Chromium-derived rendering engine is fine but there is no way to sync bookmarks and passwords with other browsers or at least import them. An ad blocker is built in but there’s also no support for WebExtensions or User Scripts, as far as I can tell. Keyboard does not automatically pop up on text inputs, you’ll need to press X every time. Despite all the downsides, it’s miles ahead of using a desktop-focused browser in Game Mode. You can also just launch Angelfish from Plasma Desktop without the above tweaks and just continue to use the same tabs, sessions, etc.

I can’t speak for the Plasma Mobile team but I hope they’ll embrace platforms like Steam Deck to lure in a few new contributors. Many of the other Plasma Mobile apps look potentially useful on handheld PC platforms as well.

Other Plasma Mobile apps may work using the same method but I’ve not tested any of them, yet.

PS: Angelfish also has a tablet UI that you can enable by replacing QT_QUICK_CONTROLS_MOBILE with KDE_KIRIGAMI_TABLET_MODE but I did not find it particularly working well with Game Mode.

Friday, 12 August 2022

Let’s go for my web review for the week 2022-32.


reb00ted | Is this the end of social networking?

Tags: tech, social-media, attention-economy

Interesting point of view… indeed, let’s see what rises from the ashes.

https://reb00ted.org/tech/20220727-end-of-social-networking/


Amazon to acquire maker of Roomba vacuums for roughly $1.7 billion

Tags: tech, amazon, robotic, surveillance

With some of the late moves from iRobot to hoard data from their robots as they are mapping homes during their work, this acquisition is a tad worrying.

https://www.cnbc.com/2022/08/05/amazon-to-acquire-maker-of-roomba-vacuum-for-roughly-1point7-billion.html


Gregory Szorc’s Digital Home | Achieving A Completely Open Source Implementation of Apple Code Signing and Notarization

Tags: tech, apple

Good news for anyone who got to target that evil platform… if you have to make a multiplatform application this might ease your pain.

https://gregoryszorc.com/blog/2022/08/08/achieving-a-completely-open-source-implementation-of-apple-code-signing-and-notarization/


‘The best thing we can do today to JavaScript is to retire it,’ says JSON creator Douglas Crockford • DEVCLASS

Tags: tech, javascript, web, browser

Admittedly I share the sentiment… I don’t think there is any viable solution in sight though.

https://devclass.com/2022/08/04/retire_javascript_says-json-creator-douglas-crockford/


Don’t call it a comeback: Why Java is still champ · GitHub

Tags: tech, java, history

Interesting Java history put in perspective. Indeed it’s been stagnant and have been picking up again… reminds me of another famous language.

https://github.com/readme/featured/java-programming-language


Redis Explained

Tags: tech, caching, databases, redis

Nice primer on how Redis works and the type of deployments you can choose from.

https://architecturenotes.co/redis/


pdf-diff: A tool for visualizing differences between two pdf files.

Tags: tech, tools, pdf

That looks like a nifty and convenient tool.

https://github.com/serhack/pdf-diff


Reduce Friction – Ceejbot’s notes

Tags: tech, processes, organization, business, automation, codereview

Lots of good advices about processes and organizations. It’s nicely points out that friction is not necessarily wrong… if you get something out of it. Also neat reminder in there that code review are here to complete work which is already socialized somehow. If you can’t find reviewers it’s a sign of an organizational problem when the work started.

https://blog.ceejbot.com/posts/reduce-friction/


I assure you, medieval people bathed.

Tags: history

Let’s get the record about medieval time straight, shall we? They weren’t as filthy as we like to pretend, far from it.

https://going-medieval.com/2019/08/02/i-assure-you-medieval-people-bathed/


How to get safe drinkable water for 20$ ? - Ceramic water filter - Tutorial - YouTube

Tags: low-tech, water

Seriously this is an awesome and badly needed technology. Let’s hope it spreads.

https://m.youtube.com/watch?v=_NOZ8zREqkE



Bye for now!

Tobias texted that the SpaceHierarchyCache class worked as expected. So I added that to the open merge requst.

I have also been working on the Space home page.

space home

This currently allows the following

  • viewing all rooms in a space
  • joining rooms
  • opening joined rooms
  • leaving space

@miepee took the time to give me many suggestions relating to user experience. I tried to implement most of the suggestions they shared.

Another minor thing I changed is that SpaceHierarchyCache is now a singleton in QML.

Carl helped me with the long standing issue with layout by sending a patch that brought Space icons to middle of the layout. (Thanks!)

Thursday, 11 August 2022

This week I have published several new versions of my music applications:

The first two applications, kmetronome and kmidimon, are now over fifteen years old and are only available for Linux. These two new versions are simply bug fixes, with no new features. But it is interesting to note that in FlatHub they are already based on Qt6 and supporting both Wayland and X11, although the packages in AppImage format still use Qt5. The chances of finding these applications in the official repositories of Linux distributions are slim. In fact, kmidimon was removed from the official Debian repositories with some lame excuse, and it is unlikely to be included again. I can't do anything about it, so please: direct complaints where they belong. Or use the new available distribution formats or the unofficial repositories, like Debian Multimedia, which includes the three mentioned applications and many others.

The other app, dmidiplayer, is much newer and cross-platform. It is the successor to Kmid2, the KDE karaoke application that I rewrote many years ago. In this new version the most remarkable new feature is the persistent configuration of the songs. This is a feature that was already present in the old Kmid2 and that allows you to store the tempo, general volume, pitch transposition, and MIDI channel settings for each song, which will be applied when it is played again in the future. The other novelty is the individual volume adjustment for each MIDI channel, something that was not possible in Kmid2.

After all these years, it is curious that it is still possible to find Kmid2 in one distribution: Fedora, despite being a Qt4/KDE4 application. So a functional comparison of both applications is not only possible, but easy to do. In my opinion, with this version dmidiplayer has reached parity in terms of functionality with Kmid2. On the other hand, the new architecture has allowed the application to be available on other Unixes (such as FreeBSD) in addition to Linux, macOS, and Windows.

I guess the next app to get updates will be VMPK. There is no forecast yet of the changes it will bring, but there is a recurring request that I will not do: MIDI Jack support. This is not to say that it is not possible to use Jack MIDI with VMPK, because in fact there is an utility called 'a2jmidid' that serves as a translation layer between applications using the ALSA Sequencer and Jack MIDI. On the other hand, for VMPK to use new native backends it is only necessary to implement Drumstick::RT plugins. And this can be done by any interested developer, and then independently distribute the out-of-tree plugins. I've opened a discussion on GitHub about this. Anyone interested, please read and ask your questions there.

Tuesday, 9 August 2022

Purpose

The major purpose of the mid-term evaluation during the Google Summer of Code program is to ensure the contributor’s progress for their committed timeline for both coding and communication.

My progress till mid-term

During the coding period, I started with “ten’s complement,” and after a thorough discussion among the mentors, we decided to divide the activity into three sub-activities. The details for all the sub-activities can be found here.
At the time of mid-term evaluation, all these three sub-activities were half-functional, the improvements were left, but the basic functioning and the dataset for level 1 of all the activities were present. Although, I was one week late to my timeline, which I proposed. I planned to complete “ten’s complement” by mid-term. I’ve added the to-do for this activity under the task. (here)
But one thing I realized, and my mentors told me too, is that the small things require more time. One of the reasons why I was unable to complete the activity before mid-term was the incorrect estimation of time and work. And initially, the college was going to open a month later, but it started in the month of July itself. Due to this, I couldn’t provide much time for a few days.

Improving myself

After the mid-term evaluation, I prepared another timeline consisting of the remaining tasks and time left, as advised by the mentors. An updated timeline would help both of us, mentors and me. Through this, my progress during the remaining weeks can be measured. I try to have daily interaction with the mentors, and I’ll be publishing more blogs to increase communication with the whole community as well.
Also, I am allocating more time to the remaining task and increasing the contributing pace to catch up to the timeline and complete all the tasks before the final evaluation.

Monday, 8 August 2022

Seventh week

In the seventh week, I will implement the OcrTesseract Engine, an internal object, which handles the input scanned document image, get optional tesseract values from the dialog and release the OCR output text and the text file.

figure1

The detailed architecture of this object is shown in the following :

figure1

It implements a function runOcrProcess() that uses Tesseract CLI, a command line program that accepts text input to execute operating system functions. This function returns the type enum state of a process and saves the results are saved in member variables as well :

ValueDescription
PROCESS_COMPLETEAll stages done.
PROCESS_FAILEDA failure happen while processing.
PROCESS_CANCELEDUser has canceled processing.

Eighth week

This week, I started implementing the backend part, an internal multi-thread to manage the batch processing and Data object delivery to send from backend to frontend.

Text Converter Thread Management

This plugin will use an internal multi-thread for OCR processing images. Classes in this part will be implemented based on existing objects to manage and chain threads in digikam. The idea is inspired by using QThreadPool and QRunnable. Existing threads can be reused for new tasks, and QThreadPool is a collection of reusable QThreads.

The part TextConverterActionThread manages the functioning of TextConverterTask. Concretely, TextConverterActionThread manages the instantiations of TextConverterTask.

Each Text Converter Task will initialize one Ocr Tesseract engine object to manage one URL of an image.

The purpose is to allow each OCR image process to run in parallel and stop properly. The run() method of object TextConverterTask is a virtual method that will be reimplemented to facilitate advanced thread management. Here is the architecture of this part:

figure1

Here is a sequence diagram representing the communication between GUI and with backend interface.

figure1

When the user clicks on the button “Start OCR”, the object TextConverterThread instantiates objects TextConverterTask and sets up Tesseract options from the dialog to them. By receiving the signal “clicked” from the dialog button, TextConverterTask creates an OCR engine to control the image’s Url. When the process is finished, all the necessaire outputs are set on the widget list of pictures and text editor.

The most important part is how to deliver the output and set them up on the dialog interface. For this problem, I implement a class Text Converter Data containing the status of a process, the destination path of an output file, and the recognized text extracted from the image. Output data is transferred to the dialog through two signals :

signalStarting(TextConverterActionData), signalFinished(TextConverterActionData)

figure1

In the next few weeks, I will:

  • Implement the functionalities of storing OCR result.
  • Polish and re-implement code if necessary.

Main commits