Archive for May, 2012

Development version numbers

Now that I am switching to release branches I am finally going to also tackle something that has always bothered me but I’ve never taken the time to solve: the development source code has the same version number as the most recent release. I have always wanted it to be some sort of automated number, but I wasn’t sure what I wanted it to be. And I didn’t want to have to update it myself with every single commit.

At first I had wondered about a number that gets incremented every time you compile the project, but I quickly realized that was a pointless thing to track. I may build a project 5,000 times and have a huge build number, but someone else might download the source and compile it only twice. Same source code, different version number. That’s frankly pretty silly.

Instead, I got inspired by the idea of using the git revision ID. It is obviously unique for each commit, and it identifies the specific source code for everyone. Of course, you can’t embed the revision ID because it is a hash that is created of the source code that you’re trying to embed it in. A hash that contains itself? Impossible! Of course, all you have to do instead is simply ask git for the revision ID, and pass that as a definition to the compiler:

VERSION = $$system(git rev-parse --short HEAD)
DEFINES += VERSIONSTR=\\\"git.$${VERSION}\\\"

The source code also needs to make use of the new compiler definition:

QCoreApplication::setApplicationVersion(VERSIONSTR);

This means that I finally have an automated version number for the development source code. I’ve only updated Kapow so far, but I am going to make this change to all of my projects.

Minor Kapow release

I just made a bugfix release of Kapow, version 1.3.5, that fixes some minor bugs as well as a potentially serious data loss bug: it was not fully checking to make sure that it could actually read or write its data file. I have thankfully only heard of a single user that this bug may have affected. A Danish translation was also added by Rasmus Blomqvist.

With this release I am moving to a new release process for all of my projects that is similar to how larger projects work. From now on patch releases (1.3.5, 1.3.6, etc) will only contain bug fixes or translation updates, and no new features. I was not doing this before because of the overhead of maintaining more than one branch, but I think that it is better way to do things despite the headaches it may cause me. For the sake of my sanity I will only be maintaining a single stable release line at a time for each project.

Minor Tetzle release

I just released Tetzle 2.0.1, a small bugfix release. Primarily this release fixes a crash for users with older OpenGL hardware, as well as a few other minor bugs. Thanks go to Markus Enzenberger for a German translation, and Artem Krosheninnikov for a Russian translation. Enjoy!

Line spacing and focused text

Yesterday I added the single most requested feature to FocusWriter: users can now set the line spacing per theme (and paragraph spacing, and indent the first line of each paragraph). However, there is one caveat: because I couldn’t find any way to override or merge QTextBlockFormats without modifying documents users will need to reload their files to get the different spacings for each theme. I spent a good deal of time looking around in the source code of Qt trying to find a way to do it, but please let me know if there is something I’ve overlooked! I figured out to directly change the QTextBlockFormats without modifying the documents, so now the different spacings take effect immediately.

I also added another popular request, the ability to choose what text is “focused”. Users can now choose between having one line focused, three lines focused, the current paragraph focused, or (the default) all of the text focused. It was actually quite a bit easier to add than I was expecting it to be because I was able to make use of QTextEdit’s “extra selections” (designed primarily for things like highlighting the current line in a text editor) to set the focused text to opaque, and leave the unfocused text translucent.

FocusWriter narrow focusFocusWriter broad focusFocusWriter paragraph focusFocusWriter all focus

The end of PowerPC support

I should have announced this sooner, but better late than never I suppose. I will no longer be creating new PowerPC builds of my programs. There are many reasons, but the biggest two are that my iBook G3 finally gave up the ghost, and that Qt has dropped support for PowerPC. I know that this is an inconvenience for some of my users, and I am sorry about that. Still, I hung in there as long as I could, but Apple has moved on.

The quest for better spell-checking

When I was first adding spell-checking to FocusWriter I tried using enchant, but I had some problems that stopped me. The biggest was that I couldn’t get it working on the Mac. I also couldn’t figure out how to support user installed dictionaries. Because of those issues I decided to instead use hunspell.

Over time users have requested support for languages not supported by hunspell, such as Finnish. I was recently contacted again for that very reason and I decided this time to tackle it. My first approach was just to switch the source code to using enchant on all platforms, which was easy. I solved handling user installed dictionaries by using enchant’s C API and telling the plugin where to look (enchant’s C++ API doesn’t expose setting parameters for plugins as far as I can tell). The tricky part was getting it to work on the Mac. I spent almost a week trying to compile glib and enchant, trying to get them properly linked into a framework, and then getting enchant to detect its plugins. I’m not confident in the end result and not sure it would work on other people’s computers.

Undeterred, I came up with a slightly different approach. I now use enchant on Linux or Windows and use NSSpellChecker on the mac. That only took me a couple of hours to whip together, which made me wonder why I put myself through the pain of trying to get enchant working there in the first place. NSSpellChecker handles finding the words along with checking their spelling, so Mac users should now have inline spell-checking that matches their other programs!

There are still a few rough spots. I can’t find any way to control whether or not NSSpellChecker ignores words with numbers or words all in uppercase. I also can’t find any way to tell it to look in places other than ~/Library/Spelling for user installed dictionaries which is obviously non-portable. And finally it seems NSSpellChecker only scans the list of user installed dictionaries when it is first created, so to use a dictionary after it is installed requires a restart of FocusWriter.

There was only one rough spot on Windows, and that was that I couldn’t get the enchant plugin to find the data files for Voikko (kind of important, since adding Finnish support was what started all of this). I fixed that by modifying the plugin source and adding support for a dictionary path. Just for fun I also changed it to use the thread-safe API of Voikko.

Along the way I took the time to dramatically clean up the internal dictionary API inside of FocusWriter. I had originally written it in a way to hide the fact that there was a shared database of dictionaries, but that made the code kind of awkward and unclear. I think it is a much cleaner design now.

The new code also makes it very easy for me to add the ability to change what language to use for checking the spelling of each document. I have not yet exposed this through the program interface, because I can’t decide how it should be stored. RTF and ODT (I think) both allow you to specify the spell-checking language for a document, but obviously there is no way to embed that in a plain text file. I could just store what language a document is in inside of the session, but that wouldn’t help with file exchange with other word processors.

Despite the headaches and unsolved issues, I have had a lot of fun working on this.

Follow

Get every new post delivered to your Inbox.