Fret not dear Kisa user. We have not abandoned you.
I finally managed to find some spare time and decided that this was a good time as any to set up a Subversion repository. More info on how to access the code base here.
A couple of issues where also resolved this weekend and there are a few more left before we version is out. As promised, the next major release is going to be a native KDE plasma based application. However, I'd like to have a sold Qt version to build on for the future as it's one if the best frameworks out there.
Stay tuned!
Sunday, March 7, 2010
Subversion
Posted by Pete Black at 12:14 PM 0 comments
Labels: bugs, issues, release, subversion
Tuesday, February 24, 2009
exit(0)
Say that your application has subclassed QApplication and that you have some evaluation logic in the constructor that needs to exit the application if some condition is not met like so:
int main(int argc, char **argv) {
MyQApplication app(argc, argv);
return app.exec();
}
MyQApplication::MyQApplication(int argc, char** argv) :
QApplication(argc, argv) {
// want to be able to exit here
}
So what's the issue? Well
QCoreApplication::exit() and QCoreApplication::quit()(which is the same as
exit(0)) needs the event loop to be up and running. As the documentation for QCoreApplication::exit() says says: "If the event loop is not running, this function does nothing."Now from a design perspective exiting from the constructor like this is probably not the best way to go about things. But, for the sake of argument say that you really have to. And have to without refactoring the code.
So far the only two options I've come across that let's you keep your old design is
qFatal() and std::exit(). However, they both leave some to be desired. qFatal() will print and "Aborted" at the end and that is no good if you have an internationalized application. std::exit(0) will require reaching outside of Qt, which is fine, but you need to update the compiler include path and that could open up issues when compiling on different (non-standard) systems.Now if you're not to lazy a re-design is in place. I posed the question to the qt-interest mailing list and got a couple of good responses.
Arnold Krille suggested to create a
bool MyQApplication::shouldRun() and then check before calling app.exec() like so:
int main(int argc, char **argv) {
MyQApplication app(argc, argv);
if (app.shouldRun())
return app.exec();
}
Scott Aron Bloom pointed out that throwing an exception is considered better practice then calling
exit() directly.
MyQApplication::MyQApplication(int argc, char** argv) :
QApplication(argc, argv) {
if(errorConditionExisted)
throw ...
}
Posted by Pete Black at 10:06 AM 0 comments
Monday, February 23, 2009
Damn bugs!
Well, bug at least. Had to push a bugfix release out. The super cool -flags option turned out to be broken. QA has been notified and have already updated their testing routines.
Get the source, ebuild, deb and rpm from the usual location.
Posted by Pete Black at 3:20 PM 0 comments
Flags
If you're running in non KDE environment, or just missing the l10n part of KDE localizations module here is an archive containing the flags.
Use the -flags argument to specify the location of the extracted folder if it's not under /usr/share/locale/.
Posted by Pete Black at 1:01 PM 0 comments
Sunday, February 22, 2009
New release
OK, so the idea was that starting from version 0.60 we would have full KDE support. That did not happen, but I'm happy to announce one of the strongest versions ever. Still pure Qt, still live! spell checking.
A lot of effort went into this one and there where plenty of new improvements and issues fixed. Some of the major updates are:
- Updated the way words get entered, should be a lot more flexible now
- Added XKb support to get the keyboard layout on non KDE systems
- Added Ukrainian translations, thanks to Yuri Chornoivan
- Fixed "replace in client", should be stable now
- Fixed issue 1 and issue 5, where some correctly spelled words being treated as misspelled
- Changed
-languagecommand line parameter to set application language
Please see the full Changelog for more information.
There is now a Kubuntu deb and a Fedora RPM as well as the regular Gentoo ebuild.
Enjoy!
Posted by Pete Black at 9:23 PM 0 comments
Thursday, February 19, 2009
Got atoms?

This is a piece of useful code I forgot to save a while back so I had to take some time to research it again. It's for getting Xlib window property information. Change the XA_STRING to fit your needs based on the types in X11/Xatom.h.
Atom* atoms;
int num_prop_return = 0;
atoms = XListProperties(m_display, window, &num_prop_return);
for(int i = 0; i < num_prop_return; i++) {
Atom atom = *atoms;
QString name = XGetAtomName(m_display, atom);
atoms++;
Atom type;
int format;
long offset = 0;
long length = 8192;
unsigned long nitems, after;
unsigned char *data = 0;
XGetWindowProperty(m_display,
window,
atom,
offset,
length,
False,
XA_STRING,
&type,
&format,
&nitems,
&after,
&data);
qDebug() << name << QString::fromLatin1((const char*) data);
}
XFree(atoms);
References:
Xlib Properties and Atoms
qapplication_x11.cpp
Posted by Pete Black at 12:31 PM 0 comments
Wednesday, February 18, 2009
XKb support
Finally done! Took half a day, but time well spent as I've wanted to implement this for months and never figured out a good way. Parsing these long strings is not what I hoped for, but at lease now I have something to build on. Remember what trigged this in the first place is the broken QApplication::keyboardInputLocale().
Posted by Pete Black at 11:53 PM 0 comments
Issues

I'm happy to report that a bunch of issues have been resolved these last few days.
A couple worth to mentioning are issue 1 and issue 5 which are both related to faulty string conversions causing Aspell to think that a word is misspelled when in fact it's not. Be careful if you need a const char * and you're using the QString "to" functions such as QString::toUtf8() and QString::toLocal8Bit(). Apparently the latter is to be preferred.
More issues are being resolved and the word checking and displaying algorithm has been rewritten to be a bit more flexible. There is also a new keyboard layout and language override in place. The next release is just around the corner so stay tuned.
Posted by Pete Black at 2:49 PM 0 comments
Monday, February 16, 2009
Got keyboard layout?

You've probably heard me ranting about this before, especially if you know me in person, but Xlib development and XKb in particular is not the most pleasant think in the world. And this could not be more true when you're coming from a pampered and spoiled Qt environment.
Try getting the current keyboard layout from an X11 session and you'll quickly understand what I'm talking about. Why not just use QApplication::keyboardInputLocale()? Well, true, this is what you would usually do:
QString keyboardLayout = qApp->keyboardInputLocale().name();
Which should give you
en_US if you're running under that locale. However QApplication::keyboardInputLocale() is broken. So now you're on your own.The issue here is that there is no simple way of doing that in Xlib/Xkb. The X server loads the layouts on startup and compiles them from the symbol files usually defined in
/usr/share/X11/xkb/symbols into key syms and key codes, which we'll call key maps. Now I might be wrong about this, but I did spend more then just a few hours trying to figure this out. Surprisingly, the X devs did not think it necessary to know the symbol layout name at runtime. You can get the compiled keymaps and group names, which for the first in the us symbols file is name[Group1]= "USA";. This is how you would go that:
#include <X11/XKBlib.h>
...
XkbDescPtr keyboard = XkbGetKeyboard(display,
XkbAllComponentsMask,
XkbUseCoreKbd);
XkbStateRec state;
XkbGetState(m_display, XkbUseCoreKbd, &state);
unsigned int group = (unsigned int) state.group;
QString symbols = XGetAtomName(display, keyboard->names->symbols);
QString name = XGetAtomName(display, keyboard->names->groups[group]);
qDebug() << "symbols" << symbols;
qDebug() << "name" << name;
...
However, I have little need for a "USA". I want a "us". So what did I discover in my more then a few o hour long research. Basically two ways of doing this. The VirtualBox guys have a list of their own keyboard symbols (key maps) and compare them to the current key maps from the X server. The one that closes resembles the one form the X server will be the best guess. Crazy...
The other approach I found was to parse the symbols list together with the current group index. While this is slightly more intuitive then the VirtualBox approach, it's still insane that one has to go out of their way like this.
This is what
XGetAtomName(display, keyboard->names->symbols) call above returns
pc_us_se_2_il_3_nec_vndr/jp_4_inet(evdev)_group(alt_shift_toggle)
Which is similar to what you can get from the command line using
xkb_symbols { include "pc+us+se:2+inet(evdev)+group(alt_shift_toggle)" };
Now all that's left is to parse that string to get and combine it with the group index to get the current one. I'll let you do the math from here.
Edit: Be careful where you call those XKb functions from as you might get synchronization issues such as
Xlib: unexpected async replyEdit: Looks like
QApplication::keyboardInputLocale() works if there is only one keyboard layout.Edit: Got a task opened by Qt.
Posted by Pete Black at 11:11 PM 0 comments
Debug output is the key

Debuggers are great, but having to step through code is not always ideal. Good strategical debug output can save you a lot of time when trying to track down an issue. Especial if the debugging is being done by a non-developer.
As you probably know, adding a debug trace in Qt is child's play. Just do a
#include <QtDebug>
and then put a
qDebug() << "This is a debug message";
wherever you need it.
To compile Kisa with debug symbols just execute these commands in the extracted source folder;
qmake
make debug
To start the debug enabled version just call
bin/kisa, no need to install it. Some of the paths might not be correct, especially for the country_language_mappings.txt, but now you have debug output to track down the issue.That's it!
Posted by Pete Black at 10:34 PM 0 comments
Sunday, February 15, 2009
Creating custom deb packages is a pain
As a long time Gentoo user and maintainer I sometimes find myself crying at the time it takes to get a package compiled. Especially if you're updating or installing something that is needed super pronto. Now this is nothing unique to Gentoo, it's a problem for any source-based distro. However, today I got reminded (again) why a source-based solution gives users and developers superior control.
Have you ever tried crating an i686 package for a Debain based system? If not then let me spare you the agony and tell you to not waste your time. Now this is not a shortcoming in the package creating system, which by the way is a nightmare of configuration files and scripts, but rather a deficiency in the package distribution and management system that doesn't allow i686 pages to be installed. Yes, that right, you can run a i686 host and you can compile and run i686 applications, but you can't install them. Well, not at least pure i686 packages. This is being discussed now so hopefully things will improve.
If by any chance you would like to try this is what I did:
First make sure the necessary build tools are available by installing these packages:
apt-get install build-essential pbuilder debhelper dh-make
Then follow the packaging guide and make sure that you at least have your control, copyright and rules files in order. This horribly styled page breaks it down pretty well.
Add these lines to the top of the rules file to override the default compiler and compiler flags. Change according to your needs
CC = gcc
CFLAGS = -march=i686 -02 -pip
Also update the build make target in that file as well, so it looks something like this:
build-stamp: configure-stamp
...
$(MAKE) CC="$(CC)" CFLAGS="$(CFLAGS)"
To force a special architecture build, in this case i686, use:
dpkg-buildpackage -ai686 -b -uc -rfakeroot
Remember, you probably won't be able to install the resulting .deb unless you tweak the Architecture tag in the control file.
Good luck!
Edit: The above should work to create i686 optimized i386 packages. If that makes any sense...
Posted by Pete Black at 6:15 PM 0 comments
Saturday, February 14, 2009
Valentine's day release

Consistency? No, not much around here. But I do have a great application that solves a fundamental problem — spell checking. And what gift could be better to give to your loved one on this day.
Finally a new release out. Most changes for version 0.56 are under the hood, making the the code structure cleaner and more manageable. Other noteworthy changes are KDE 4 support turned on as default, better icon integration, improved pop-up handling and an updated default install path ("/usr/local").
All good stuff, but there are two hacks that I would especially like to bring up. The first is Kxkb integration over D-Bus as getKeyboardInputLayout and the accompanying event notifications are broken in Qt. What this means is that Kisa will now poll the keyboard layout whenever a new word is entered instead of waiting for the event notification. Obviously one needs to have Kxkb running. It suprisingly easy to do D-Bus calls, just do a:
QDBusInterface kxkb("org.kde.kxkb", "/kxkb", "org.kde.KXKB");
QDBusReplyreply = kxkb.call("getCurrentLayout");
The other hack makes use of the INSTALL_ROOT variable. Even though it is being deprecated in favor of DISTDIR by the GNU Make crowd, it still shows up everywhere in the qmake generated makfiles. Problem is that Qt forgot to give a easy way to set it in the .pro file. Currently, it has to be passed on the command line when invoking make or set as an environment variable. Well, not anymore if you're using Kisa. Here is one way to do it in the toplevel project file:
isEmpty(INSTALL_ROOT) {
INSTALL_ROOT = /usr/local
}
INSTALL_ROOT = $$replace(INSTALL_ROOT, "/", "\/")
QMAKE = $$[QMAKE]
isEmpty(QMAKE) {
QMAKE = qmake
}
system("cd src/; $$QMAKE src.pro")
system("cd src/lib/; $$QMAKE lib.pro")
CMD = "find -iname '$$MAKEFILE*' | xargs sed -i 's/INSTALL_PROGRAM.*=.*/&\nINSTALL_ROOT = $$INSTALL_ROOT/'"
system($$CMD)
Note though that there are several problems with this approach. It will only work on a project that has a top level .pro file as we are generating makefiles on the lower level project files. It will also not work if passing -recursive to qmake. However, the advantage of having an easy way to set INSTALL_ROOT outweighs these shortcomings by a long shot. Full changelog is here.
Enjoy!
Edit: Got a task opened by Qt.
Posted by Pete Black at 1:49 AM 0 comments
Tuesday, December 25, 2007
Happy Holidays!
Sorry for the lack of updates, but since I started at my new job there has been far too little time over for coding.
I had an unsuccessful attempt at trying to make a full (yes, including system libs) static build. This, obviously, would be extremely useful for debugging on various distributions. However, turns out that linking to static versions of glibc and such is not that trivial. Qt an Aspell turned out to be fairly easy after building static versions of the libraries.
Anyway, stay tuned. There should be a new version coming out soon with some minor updates and fixes.
Posted by Pete Black at 6:05 PM 0 comments
Wednesday, October 17, 2007
The Devil is in the Detail

Added "Treat hyphen as punctuation" option.
Removed the double-clicking on words as it interferes with standard selection procedures.
Note that the command-line options now use a single "-" instead of "--", so make changes accordingly. This is more consistent with Qt standards.
Also, a small, but annoying bugfix. The previous version didn't allow the dictionary to be changed via the tool button whenever the "Change dictionary on keyboard layout change" option was selected.
Changelog is now here.
Enjoy!
Posted by Pete Black at 11:09 AM 0 comments
Tuesday, October 16, 2007
It's all about context

Well almost...
I'm proud and happy to announce a new and improved version of the free-world's leading stand-alone live! spell checker. Get it while it's hot kids!
These are just but a few updates:
- published User Manual
- published API documentation
- better support for non-Latin languages
- automatic handling of text input direction
- ability to add words to personal word list
- misspelled words are now "clickable", which executes the custom command
- many more changes, bugfixes and additions...
Check out the changelog for a full list of changes.
Posted by Pete Black at 11:06 AM 0 comments
Monday, October 1, 2007
Gold code!

Tired of your favorite application not having spell checking support?
Tired of having to continuously switch between languages when spell checking different documents?
Keep writing assasination, when you actually mean assassination?
Relax, your worries are now over.
Kisa provides spell checking as you type under X11 based systems and displays the result in a small window on your Desktop. You can type anywhere, in any window and Kisa will spell check the word for you.
Kisa uses GNU Aspell as it's back-end, so it's easy to manage and install one of the 70+ dictionaries that are available.
These days most major applications already provide live spell checking, or spellcheck-as-you-type as it's also known. Firefox does it now and if you're running KDE, it's been there for a while. However, there are still plenty of cases where one could want this, especially if one feels a sudden case of dyslexia coming up.
Try it out! Let me know what you think.
Posted by Pete Black at 9:37 AM 0 comments
Blog Archive
Kisa — live! spell checker
|
Copyright (C) 2009 Pete Black |
Kisa — live! spell checker