But where to put you?
I’ve been writing programs with Qt since the Qt 3 era, and when I made my first Qt 4 programs available for general use I added cross platform support. One thing that entails is storing user data files in different locations on different platforms. At the time, I couldn’t find any way in Qt to do that, so I ended up writing this in CuteMaze:
QString homeDataPath()
{
#if defined(Q_OS_MAC)
QString path = QDir::homePath() +
"/Library/Application Support/GottCode/CuteMaze";
#elif defined(Q_OS_UNIX)
QString path = qgetenv("XDG_DATA_HOME");
if (path.isEmpty()) {
path = QDir::homePath() + "/.local/share";
}
path += "/games/cutemaze";
#elif defined(Q_OS_WIN32)
QString path = QDir::homePath() +
"/Application Data/GottCode/CuteMaze";
#endif
return path;
}
I’ve never been happy with that code. For one thing, it uses platform specific code in a platform independent codebase, which limits the number of supported platforms to those I can easily test myself. Thankfully, I will notice any bugs I introduce in one platform but not the rest, since I build my programs on those platforms.
However, I was recently made aware of the fact that CuteMaze would not compile on less common platforms, and that piece of code was one of the reasons. I figured that this was a chance to improve said code, so I went looking to see if there is a better way to write… and there is! After I released CuteMaze, a new class for desktop integration was added to Qt. The above code would be better written like this:
QString homeDataPath()
{
return QDesktopServices::storageLocation(QDesktopServices::DataLocation) + "/CuteMaze";
}
The above functionality was added in Qt 4.4. Instead of using it, I have been dragging the messy and inferior code from project to project. Obviously I don’t re-solve every problem I come to, I remember what I have done or what I have read about. It’s only natural I will miss things when reading about new versions of Qt.
Now that I know about this, I am going to use the new code for the platforms not already supported. In future projects I will use only the new code, but I don’t want to go through the headache of moving all of the user data files for all of my current projects.
A new CuteMaze release!
It has been over a year since I last updated CuteMaze. I have worked on it since then, but my other projects distracted me so much I didn’t think about it. A few months ago I added zooming support, but moving was pretty slow when zoomed out. I finally got around to looking at it a few days ago, and I discovered that I could noticeably speed up rendering by caching the background. I don’t know why I didn’t do that from the start, actually.
Once I had done that, I decided that it was time to polish up CuteMaze and make a release. I don’t want the new features to sit for too long without people getting to use them, and a year is pretty long! Along with zooming, I also added support for hints. Other than that it is mostly code cleanup. I had intended to rewrite the maze generation algorithms, but I lost interest in that and I have pushed that off to a future release.
For anybody who has made themes, this new release changes the format from being a collection of SVG files to being a single SVG file. You need to put a transparent rectangle behind smaller elements to make them render at the appropriate sizes. It is a fairly easy change to make, and you can look at the provided themes for examples.
Bugfix release for Connectagram
No matter how hard you try, a few bugs always slip through. The first bug I fixed was minor, and it was merely that I had overlooked what happens when you use more than one mouse button to drag the letters (answer: bad things).
The second bug I fixed was a slightly larger oversight on my part. Originally the game was single threaded, but I moved most of the game creation into a second thread shortly before making the first public release. When I did that I forgot about the fact that it is not safe to call rand() and srand() in two threads, which was causing the saved games to be loaded incorrectly. I replaced those calls with calls to qrand() and qsrand(), and now it has no problems loading the current game on start.
New Kapow release
I have made a new release of Kapow that changes the interface somewhat, while also adding the ability to make printed reports of your data that can also be used as invoices.
A fun new project
I recently thought up an idea for a simple game, and because I couldn’t get it out of my head I took a short break from my current projects to finish it. The game is called Connectagram, and the goal is to unscramble a group of words as fast as possible. You get to choose how long the words are, and how many words there are, so you can choose how hard you want it to be. Enjoy!
New Kapow release
I have made some improvements to the interface of Kapow. The largest visual change is that the projects are now listed in a sidebar. Because of this, you can now group related projects by dragging and dropping them on top of each other. I have also made adding and removing sessions and projects a lot more obvious by adding buttons for those purposes. Also, you can run two or more timers at the same time if necessary.
New FocusWriter release
I have released a new version of FocusWriter that has all of the new features I’ve been talking about recently: spell checking, document tabs, more statistics, and general interface improvements. Go forth and enjoy! Please let me know if you have any problems.
Choose your own statistics
After adding statistics to FocusWriter, I decided to make it more configurable than simply choosing which of them to show. I don’t like hardcoding values into any program, and the 350 words per page number was bugging me. It’s not the industry standard of 250, but it is closer to the number of words on in an actual book instead of a double-spaced manuscript.
To fix that I added the ability to select the number of words per page. Then I figured, since I’d done that much, I might as well allow the user to choose between characters per page, paragraphs per page, or words per page. And once I had done that, I figured I might as well allow the user to choose between an accurate word count based on whitespace and punctuation, and an estimated wordcount based on the total number of characters divided by 6 to match the industry standard. At that point, I decided that that was enough selection for the statistics.
Interface changes to FocusWriter
A few weeks ago I decided to add spell checking to FocusWriter. When I got that finished, I still found myself thinking about FocusWriter so I completed a large overhaul to the user interface that I had been planning for awhile now. I wasn’t intending to get so distracted by FocusWriter, but I am glad that I did.
The first change to the interface is the way files are created and saved. It now behaves like other word processors in that you have to choose a filename for each file when save them the first time. When I started work on FocusWriter it was intended to feel like its own little world, in the same way that many people don’t interact with their emails outside of their chosen email client. However, because it uses plain text files it has become apparent that many users expect it to act like other word processors in the way it saves files.
Another interface change is the addition of a menubar. As a side effect of this, it means that you can turn off the toolbar, or change what icons are on the toolbar. I have modified the default list of icons to help with text editing, and not be a list of every function of the program.
The final planned change to the interface is the addition of a tab bar of open documents. Instead of opening files in a new window that obscures whatever other files you have open, they are now opened in a new tab. This makes it clear what files a user has open, and makes it very easy for them to switch the files, without forcing them to drop out of fullscreen mode and use their desktop environment’s method for changing windows.
Normally I would have made these changes as several smaller commits, but because of the way I developed them they interact with each other too much to easily split them apart, so I just made them one large commit.
Additionally, I added more document statistics after a request from a user. It now can track paragraphs, pages (based on an average of 350 words per page), and characters (both spaces and non-spaces), as well as word count. Any or all of these statistics can be turned off if the user desires.
Spell checking in FocusWriter
I have added spell checking to the FocusWriter repository, but there are more things I plan on changing before making a release. I decided to use Hunspell as the spell checking engine so that I could use the same engine on all platforms. It turned out that the act of checking the spelling of a word was very easy (the functions spell() and suggest() in Hunspell do the actual work), but the integration was a pain and it took me a lot longer to write than I was expecting. FocusWriter now has “as you type” spell checking and a spell checking dialog.
Leave a Comment
Leave a Comment
Leave a Comment