|
This is the first installment of the Non-Programmer's Guide to Participating in KDE series. It is designed to aide those who would like to participate in the KDE project, but for one reason or another can't do so by contributing source code. Fortunately, there are many tasks in KDE that don't involved writing code, and many of them don't require much investment in the way of time, either. Writing WhatsThis help is one quick and easy way to get involved with KDE development. Since no coding skills are required and it takes just minutes to do, it is an effective and simple way for anyone who wishes to help KDE become the best desktop available. |
Table of Contents |
![]() |
| A dialog showing WhatsThis help for one of its widgets |
WhatsThis help is essentially an on-demand, extended tooltip associated with a specific widget1. It tends to be more verbose than a tooltip, but more succinct and specific than a full-blown help manual. To access WhatsThis help, the user clicks on the WhatsThis button in the window's title bar (usually a question mark) or presses the WhatsThis keyboard shortcut (usually Shift-F1) and then clicks on a widget to display it's associated WhatsThis help.
Such a convenient way to get a explanations of specifics part of an interface can be quite a boon to users trying to understand how to use it. Unfortunately, if you go looking for WhatsThis help in KDE, you'll notice that many widgets lack WhatsThis help. This is because developers often tend to overlook the need for documentation due to time constraints, interest and other factors. WhatsThis help is best added when an interface is deemed "finished" since the context-sensitive WhatsThis entries need to change as the interface changes. The good news is that it's fairly trivial to add WhatsThis help, even if you aren't a programmer.
Before we can get started added WhatsThis help to an interface, we first need to do some prep work. In particular, we need the newest, most up-to-date version of the interface in question available. For KDE applications, this means getting the code from SVN2. We won't need a special account, nor do we need to compile the code. We don't even need all of the KDE source just to work on one particular interface. This means we don't need to worry about compilers, dependencies, configuration or using lots of disk space. Huzzah!
Looking through the various utilities that come with KDE, you
may notice that the KDE archiving and compression tool ark
is almost entirely devoid of WhatsThis help. The KDE GnuPG tool,
creatively named kgpg, is also in need of some WhatsThis help. These
two applications look like a good place to start our exploration of
WhatsThis help. So let's start by checking out the kdeutils SVN module,
which is where both of these applications live:
user@locahost:~> svn co svn://anonsvn.kde.org/home/kde/trunk/KDE/kdeutils A kdeutils/kdessh A kdeutils/kdessh/kdessh.cpp A kdeutils/kdessh/sshdlg.cpp A kdeutils/kdessh/Makefile.am
To find where other applications exist in KDE's SVN repository, you can visit the KDE SVN web interface or use the svn ls command locally. For more detailed information on working with SVN and KDE, visit the KDE
anonymous SVN documentation.
KGpg is a new application in the KDE distribution as of version 3.2 and it does have WhatsThis entries for some of its widgets. But unless the WhatsThis support is comprehensive, users won't trust it to be there when they need it and so won't bother trying to use it. For the purpose of this tutorial, we're going to focus on one particular part of the interface: the General tab of the KGpg configuration dialog.
![]() |
| kdeutils/kgpg/conf_ui.ui as displayed in Qt Designer |
Having already checked out the kdeutils module, a quick
directory listing will show that there is a kgpg directory within it.
In that directory are several files ending with the .ui
extension. These are XML files that contain the layouts of various
parts of KGpg's interface. They can be editted by hand if necessary,
but it is usually preferred to use Qt Designer.
Designer is a WYSIWIG user interface designer, sort of like
Photoshop for programmers. Designer is often packaged with the Qt
development packages since it isn't necessary to compile or run Qt or
KDE applications. Opening a UI file in Qt Designer will show what that
interface looks like. When we open up the kdeutils/kgpg/conf_ui.ui
file we see one of the configuration pages in a small window. We can
now edit it directly from here.
![]() |
| Widget properties tool window in Designer |
From here, it's pretty straightforward. We simply type in a message and we're done! We can spruce up the text a bit by using basic HTML tags for bold, italic, unerline, and more. The menus and toolbar in the WhatsThis Edit Text window makes using these tags a breeze.
| Tip | When using HTML tags in
WhatsThis text, wrap the entire thing between <qt>
and </qt> tags. This will
ensure that when Qt shows the WhatsThis help to the user, it will show
it properly as HTML text.
|
Remember to keep the text as clear and succinct as possible. The aim is to help the user rather than confuse them. Don't include references to other widgets in the interface unless they are absolutely linked to each other. To ensure accuracy, try the application out to see exactly what that element of the interface does. Double checking the spelling and grammar is often a good idea, as well. Nobody's perfect, but a little due dilligence can go a long way.
| Tip | When adding WhatsThis help to a widget that also has a descriptive text label next to it, remember to add the exact same WhatsThis help to it. The user may click on the label or the widget, and Qt doesn't automatically sync the WhatsThis help for us. |
Once we've added WhatsThis help to all the items in the
interface, we select Save from the File
menu to save our changes. We then repeat the process for each UI file
in the application's directory and we're done! Easy as pie!
Once we are finished adding WhatsThis help in Designer, it's time to generate a patch. First we make sure that our version of the files are synced with the main SVN repository. This is accomplished by doing a SVN update from the application's directory:
user@localhost:~/kdeutils/kgpg> svn upWe can ignore the files with question marks in front of them: they aren't in SVN. The files with a 'P' (or a 'U') in front of them had changed on the SVN server since we last updated, and SVN has now merged those changes into our local copy. Files with an 'M' in front of them have been changed locally. We want to separate those changes into a "diff" (which is short for "difference") file that can then be used as a patch. We accomplish this by doing:
? dcopiface.kidl
? dcopiface_skel.cpp
? groupedit.cpp
? groupedit.h
P ChangeLog
M conf_ui.ui
P kgpgview.cpp
user@localhost:~/kdeutils/kgpg> svn diff > kgpg.diff
| Tip | In the kdesdk (or KDE Software Developers Kit) package there is a program called cervisia which is a graphical SVN client. Instead of using the command line SVN client, you can use cervisia to do updates, patches and more. Cervisia can be run as a stand-alone application or directly from Konqueror. Consult the cervisia manual for further information on using it. |
If all went well, we now have a file called kgpg.diff.
We can now email this to the maintainer of the application.
You can usually find the maintainer in the About box for the
application, or in the AUTHORS file included with the source code, or
by looking at the license clauses at the top of source files, or by
asking on IRC or a mailing list. If the maintainer doesn't respond
within a reasonable period of time (usually a 7-10 days), they may be
busy or not maintaining the application in SVN anymore. In that case,
send the patch to the KDE development email list (kde-devel at kde dot
org).
| Tip | After a certain point in the KDE release cycle, no changes to user visible text (or "strings", as the developers usually call them) are allowed. This is to ensure that translators have enough time to translate all the strings in KDE, which they can't effectively do when they are still changing in SVN. Consult the onlie KDE release schedule to find out when the string freeze goes into effect. |
Having accomplished our mission with KGpg, we now
turn our eyes to Ark. But when we look in the kdeutils/ark/
directory, to our horror we discover that there are no UI files in
sight! This means we'll have to delve into the source code itself. But
don't worry just yet. While this takes a bit more effort than using
Designer, it's still relatively easy and doesn't require much in the
way of special knowledge. However, if you really don't want to get your
hands too dirty or wish to first master adding WhatsThis via Designer
you can skip right to the end.
You can always come back later. Otherwise, onward into the belly of the
beast...
![]() |
| The Ark Extract Dialog |
The first step is to run the program and check through it's various dialogs and windows for WhatsThis coverage. It's usually easiest to do one dialog or window at a time. Of course, this means we need a relatively recent version of the application to work from. If the application hasn't changed much, we may be able to get away with running the version that shipped with the last stable KDE release. If it's undergoing development, however, we'll most likely need to compile it from the source code we've checked out of SVN3.
Looking through Ark's interface, we come across it's Extract
dialog. There is no WhatsThis help at all in this
dialog! That simply won't do. But where to begin? Our first clues are
the bits of text that are visible: "Extract to:", "Files to be
Extracted", etc. We'll use those strings to find where in the code this
interface is defined. From the kdeutils/ark/
directory, we'll do this4:
user@localhost:~/kdeutils/ark> grep -in "Files to be Extracted" *cppA-ha! The last file that our grep command listed looks to be the winner!
arkwidget.cpp:1500 // list of files to be extracted
arkwidgetpart.cpp:370 // list of files to be extracted
extractdlg.cpp:110 bg->setTitle( i18n( "Files to Be Extracted" ) );
| Tip | To find text that has a keyboard shortuct such as "Extract here (where the letter "x" is the keyboard shortcut), place an ampersand in front of the underlined letter like this: "E&xtract here". If there is an ampersand in the text, substitute it with two ampersands. |
Opening up kdeutils/ark/extractdlg.cpp
in our text editor and going to line 110 we see this:
bg->setTitle( i18n( "Files to Be Extracted" ) );and if we go down a few lines we'll see the radio buttons:
m_radioCurrent = new QRadioButton( bg, "m_radioCurrent" );
m_radioCurrent->setText( i18n( "Current" ) );
Layout2->addWidget( m_radioCurrent );
m_radioAll = new QRadioButton( bg, "m_radioAll" );
m_radioAll->setText( i18n( "All" ) );
Layout2->addWidget( m_radioAll );
m_radioSelected = new QRadioButton( bg, "m_radioSelected" );
m_radioSelected->setText( i18n( "Selected files" ) );
Layout2->addWidget( m_radioSelected );
Now that we have found the code, adding our WhatsThis help is
pretty simple. But first we have to take care of some C++ bookkeeping.
Near the top of the file we'll likely see a bunch of lines starting
with #include. In kdeutils/ark/extractdlg.cpp
we find several such lines, including this series:
#include <qbuttongroup.h>We need to look for one that references
#include <qlabel.h>
#include <qapplication.h>
#include <qlayout.h>
qwhatsthis.h.
If we don't find such a line (and in this case we don't), we'll need to
add it something like this:
#include <qbuttongroup.h>Try and keep the new
#include <qlabel.h>
#include <qapplication.h>
#include <qlayout.h>
#include <qwhatsthis.h>
#include near other
similar lines, preferably with other Qt headers. You can spot the Qt
headers since they all begin with a 'q'.
Back to the code starting on line 110 (now line 111 due to our
#include addition), note the lines that
contain new QRadioButton. Each of those lines
is making a radio button and assigning it to a "variable". In this
case, the variable name of the radio button that says "Current" is
"m_radioCurrent". Not too hard so far. Now to add some WhatsThis:
m_radioCurrent = new QRadioButton( bg, "m_radioCurrent" );
m_radioCurrent->setText( i18n( "Current" ) );
Layout2->addWidget( m_radioCurrent );
QWhatsThis::add( m_radioCurrent,
i18n( "Selecting this option will cause only the last "
"selected file to be extracted." ) );
m_radioCurrent = new QRadioButton( bg, "m_radioCurrent" );
m_radioCurrent->setText( i18n( "Current" ) );
m_radioAll = new QRadioButton( bg, "m_radioAll" );
m_radioAll->setText( i18n( "All" ) );
Layout2->addWidget( m_radioAll );
QWhatsThis::add( m_radioAll,
i18n( "Selecting this option will cause all files in the "
" archive to be extracted." ) );
m_radioCurrent = new QRadioButton( bg, "m_radioCurrent" );
m_radioCurrent->setText( i18n( "Current" ) );
m_radioSelected = new QRadioButton( bg, "m_radioSelected" );
m_radioSelected->setText( i18n( "Selected files" ) );
Layout2->addWidget( m_radioSelected );
QWhatsThis::add( m_radioSelected,
i18n( "Selecting this option will cause all the files "
"you selected in the archive to be extracted." ) );
As you can see, all we added were a few lines of very simple
code. To add a WhatsThis item we use the QWhatsThis::add
method, which has the following syntax:
QWhatsThis::add( widget, i18n( "WhatsThis text") );The
widget is the widget
variable such as m_radioCurrent. The WhatsThis
text is, as you may have already guessed, the
text of the WhatsThis help to be shown for the corresponding widget.
Don't forget the i18n part as that marks the
string for translation. So far, so simple, but there are a few wrinkles
yet ahead.
In the Extract dialog, there is an "Extract to:" label that is
in front of a file location widget. When we search kdeutils/ark/extractdlg.cpp
for "Extract to:" we find the following code:
extractToLabel->setText( i18n( "Extract to:" ) );Even if we aren't familiar with C++ or KDE syntax, using a bit of best-guess-ology we can probably deduce that
Layout3->addWidget( extractToLabel );
m_extractDirCB = new KHistoryCombo( true, mainFrame, "m_extractDirCB" );
extractToLabel
is the visible text and m_extractDirCB is the
text edit. And we'd be right. Our WhatsThis code might end up looking
something like this:
extractToLabel->setText( i18n( "Extract to:" ) );Note that we added the WhatsThis help to both the text label as well as the file location widget. We also used a bit of a trick to make it so that we didn't have to enter the WhatsThis twice in the code: we created a
Layout3->addWidget( extractToLabel );
QString whatsThis = i18n( "<qt>Enter the location you wish to extract the "
"files to in the provided text area. You can click on "
"the file button to bring up a file dialog.<p>"
"<Tip:> In addition to local file paths, you may "
"use any URL that allows saving of files, such as "
"ftp and fish (ssh file transfer) URLs.</qt>" );
QWhatsThis::add( extractToLabel, whatsThis );
m_extractDirCB = new KHistoryCombo( true, mainFrame, "m_extractDirCB" );
QWhatsThis::add( m_extractDirCB, whatsThis );
QString. A QString
is simply a way to store text in a KDE application. Note we simply said
QString whatsThis and then assigned to it
(using the equals sign) the familiar-looking i18n-wrapped
text. We could reuse the whatsThis QString
again later on in the same block of source code if we want. If we do
this, we don't need to say QString whatsThis =
again, just whatsThis =. A "block" of code is
any section of code that is enclosed in "curly braces": { and }. Also
note that all variables must have unique names, so we couldn't use the
name "whatsThis" if it was already used. We don't need to worry too
much about it here, since the name "whatsThis" is probably unique if
the code doesn't use WhatsThis help, and if it is a problem the
compiler will tell us about it soon enough.
Besides the details of actually inserting new WhatsThis into the code, it's important to remember the wants and needs of the person(s) who maintain this code. Most developers don't like overly long lines, with many even preferring the lines to be kept to under 80 characters long. So make sure to keep your lines short, wrapping long WhatsThis text on several lines. However, in C and C++ string can't span multiple lines. For instance this is illegal:
QWhatsThis::add(m_radioCurrent,while this is perfectly fine:
i18n( "Selecting this option will cause only the last
selected file to be extracted." ) );
QWhatsThis::add(m_radioCurrent,Notice how the there is an opening and closing quotation mark on each line. It is also required that you use double quotes (") rather than single quotes (') or tick marks (`). Don't forget to end the statement with a semicolon (;). If the use of a quotation mark within the WhatsThis help is desired, preface it with a backslash like this:
i18n( "Selecting this option will cause only the last "
"selected file to be extracted." ) );
i18n(
"Here we will use a \"quotation mark or two\"" )
Also pay attention to the formatting style used in the source code. Most developers are very picky about this, but there is no single agreed upon standard formatting style. Some use tabs, some use space; some indent 2 spaces, some 4, some 8. The permutations are nearly endless. Just try and make the lines you add look as similar as the surrounding code as possible.
The last step is to try and compile the application to ensure we haven't introduced any compile errors. Once we've confirmed it compiles and have run it to see our new WhatsThis in action, we can create a diff to email to the maintainer just as we did when editting UI files.
| Tip | When compiling, you may
get errors about i18n being undefined. If you
do get this error, add the following line with the other #include
lines at the top of the file:
#include <klocale.h> |
Congratulations! You've made it all the way through to the end! If you have questions, please join us on IRC on the freenode.net network (#kde-devel on irc.kde.org:6667 or irc.freenode.net:6667) or email a development list or (as a last resort only, please) the author. If you have any comments on the tutorial itself (e.g. you find an error, or if you feel it could be made clearer in some specific way) please email the author without delay.
Have a great time adding WhatsThis support all over KDE, and we'll meet up again in the next tutorial on the exciting topic of Bug Triage!
svn command on your system, consult your
operating system manuals on how to install new software.*cpp as
files ending in cpp are C++ source files. Sometimes the source files
will end in .cc instead, so watch out for
that. Usually we don't need or want to search through header files (*.h)
or binary files such as object code, libraries, READMEs and icons so
just searching the source files is usually good enough.
|
About the Author... Aaron J. Seigo is a
KDE developer located in Calgary, Alberta, Canada. In addition to
hacking on KDE, he works as a contact software developer and leads a
relatively active life (for a hacker, anyways) with his family and
friends. He welcomes Qt/KDE development work as well as chocolate, beer
and other signs of appreciation. But no chocolate beer, please, as that
stuff's just plain wrong. Or greeting cards; he's allergic to them.
|