Older Newer
Mon, 06 Dec 2004 05:02:01 . . . . 82-32-168-69.cable.ubr02.newt.blueyonder.co.uk


Changes by last author:

Added:
= Graphical Scripting with Kommander =

Kommander is a simplified and modified version of Qt Designer which lets you add scripting abilities to the dialogues it makes. It saves the result as a designer UI file which can be run with Kommander Executer. It is the easiest way to make simple programmes, I like to think of it as graphical shell scripting.

Konstuct is a program to download and install KDE from sources. This tutorial takes us through using Kommander to make a graphical program to configure and run Konstruct.

Final Kommander file: http://www.kde.me.uk/kommander-tutorial/konstruct.kmdr

final-programme.png
The final programme made in Kommander

kommander-editor.png
Kommander's editor is where you will create the programme

We are using Kommander 1.1 which is currently in development but includes many more features than previous versions. Download it from
http://kent.dl.sourceforge.net/sourceforge/kommander/kommander-1.1devel2.tar.bz2

Run Kommander Editor from K-menu -> Development or as kmdr-editor on the command line. Click File->New and choose a dialogue. Our dialogue is going to have 3 parts to it, the first which will make the configuration file, the second will run Konstruct to compile KDE and the third will choose a language to install. We want to start by adding a tab widget which is the green icon A widget with tabs on the toolbar. You could also select it from the menu Tools->Kommander->TabWidget.

tabwidget-button.png

Click and drag on your empty dialogue form to create a tab widget covering all of the form.

Now we want to make our form for the configuration file. The first thing we want to know is the directory to write the file to. Click on the first button on the widget toolbar which is the Text Label button. Click on the form inside the tab widget. Now right click on the label and choose Edit Text. Change the text to Kommander Directory. You will probably have to resize the label widget.

Click on the button for the file selector widget between the Konsole and tickbox buttons. Click and drag on the canvas to put a file selector widget on your form next to the label. In the Properties box at the bottom left rename the widget you just created from FileSelector1 to outputDir. Further down in the properties box is selectionType, set this to directory.

Click on the ExecButton icon in the toolbar, the icon is a button with OK on it. Place the button to the bottom of the form, but still inside the tab widget. Double click on the button and set the widget text to Make Config File.

We are now ready to add some scripting power to our form. When we load the form we want the Konstruct directory selector widget to be set to the present working directory. We want the value of this outputDir widget that other widgets can see to be set to it's contents plus the name of the configuration file we want to write to. Finally we want the ExecButton to contain a shell script which will create our configuration file.

Outside the tab widget but still inside your form right click on the form and select Edit Kommander Text. In the Text for drop down box select initialisation. Set this text to @outputDir.setText(@exec("pwd")). When we run the Kommander script it will set the outputDir widget to contain the output from the command `pwd` which gives us the present working directory. Now right click and Edit Kommander Text on the outputDir widget. Set it's default text to @widgetText. When other widgets ask for the value of outputDir they will now be given whatever text is written in the widget. Don't put any new line at the end of the Kommander text as that new line will be included in the value of the widget.

Finally Edit Kommander Text on the Make Config File button. The default Kommander text on an ExecButton such as this is a bash shell script which will be run when the button is clicked. Set it to this script:

OUTFILE="@outputDir/gar.conf.mk"
echo "testing" > $OUTFILE

This defines a variable $OUTFILE and sets it to the value of the outputDir widget plus the name of the configuration file we will be writing to. Then it writes some testing text out to that file.

Now save your dialogue as konstruct.kmdr and run it either through the menu Run->Run Dialogue or on the command line as kmdr-executer konstruct.kmdr or by clicking on it in Konqueror. You should be able to select a directory and when you click the button it will create a file called gar.conf.mk with the text "testing". Take a look at the .kmdr file, it's an XML file which contains the dialogue layout and the Kommander scripting.

We need to add widgets which will let the user select what options they want in the configuration file. First add a directory widget and label choose the value of where the sources will be downloaded. Set the text of the label to Downloaded Sources directory and the name property of the file selector widget to downloadDir. Set the default Kommander text on downloadDir to GARCHIVEDIR = @widgetText then set this to be written out to the configuration file by setting the Make Config File button's Kommander text script to be

OUTFILE="@outputDir/OUTPUT"
echo "@downloadDir" > $OUTFILE

Add to the initialisation Kommander text for the form @downloadDir.setText("~/kde-sources/").

Next add three tickboxes to the form (note that in US English a tickbox is called a checkbox), set their labels to Have Qt Installed, Compile for 64 bit machines and Clean up sources after install. Give them name properties of HAVEQT, HAVE64 and BUILDCLEAN. Tickboxes can have different Kommander text values depending on whether they are ticked or not. Set the Kommander text for HAVEQT when ticked to be HAVE_QT_3_3_INSTALLED = true and when unticked to be HAVE_QT_3_3_INSTALLED = false. For HAVE64 set it's Kommander text to be HAVE_64BIT_TARGET = true when true and HAVE_64BIT_TARGET = false when false. Finally the BUILDCLEAN tickbox should be BUILD_CLEAN = true when ticked and BUILD_CLEAN = false when unticked.

Edit the Kommander Text of the Make Config File button and add this to the end of it's script.

echo "@HAVEQT" >> $OUTFILE
echo "@BUILDCLEAN" >> $OUTFILE
echo "@HAVE64" >> $OUTFILE

which will output the correct configuration options to the file.

Run your Kommander program to make sure it correctly outputs to the file.

Now we have to add widgets for selecting where the Konstruct KDE build will be installed. Add a button group

buttongroup-button.png

and put inside it two radio buttons and another directory selector widget. Set the label of the the first radio button to "/usr" and it's name property to usrDirButton, label the second radio button "other" and name it otherDirButton. name the directory selector to installDir. Set the Kommander text on installDir to be @widgetText. Add to the initlisation Kommander text of the Form @installDir.setText("$(HOME)/kde-konstruct"). Name the button group for the radio buttons to installDirGroup and set it's ticked text to @widgetText which will be the value of the currrently selected radio button.

The configuration file needs quite a few installation directory related values. Set the Kommander text of the "/usr" radio button to be

prefix ?= /usr
exec_prefix = \$(prefix)
bindir = \$(exec_prefix)/bin
sbindir = \$(exec_prefix)/sbin
libexecdir = \$(exec_prefix)/libexec
datadir = \$(prefix)/share
sysconfdir = /etc
sharedstatedir = \$(prefix)/share
localstatedir = /var
libdir = \$(exec_prefix)/\$(TARGET_LIBNAME)
infodir = \$(BUILD_PREFIX)/info
lispdir = \$(prefix)/share/emacs/site-lisp
includedir = \$(BUILD_PREFIX)/include
mandir = \$(BUILD_PREFIX)/man
docdir = \$(BUILD_PREFIX)/share/doc
sourcedir = \$(BUILD_PREFIX)/src

All the dollar signs are preceded by a backslash. This stops them being treated as (empty) variables when written to the file by the Make Config File button.

For the Kommander text of the "other" button set that to

prefix ?= @installDir
exec_prefix = \$(prefix)
bindir = \$(exec_prefix)/bin
sbindir = \$(exec_prefix)/sbin
libexecdir = \$(exec_prefix)/libexec
datadir = \$(prefix)/share
sysconfdir = \$(prefix)/etc
sharedstatedir = \$(prefix)/share
localstatedir = \$(prefix)/var
libdir = \$(exec_prefix)/\$(TARGET_LIBNAME)
infodir = \$(BUILD_PREFIX)/info
lispdir = \$(prefix)/share/emacs/site-lisp
includedir = \$(BUILD_PREFIX)/include
mandir = \$(BUILD_PREFIX)/man
docdir = \$(BUILD_PREFIX)/share/doc
sourcedir = \$(BUILD_PREFIX)/src

At the bottom of the Make Config File script add this to make the directory values be written to the configuration file.

echo "@installDirGroup" >> $OUTFILE

Finally there's a bunch of other bits that need to be in the configuration file, we can just output them as a big cat command in the Make Config File button script.

cat >> $OUTFILE << ENDOUT
ifdef HAVE_64BIT_TARGET
ENABLE_LIBSUFFIX="--enable-libsuffix=64"
TARGET_LIBNAME = lib64
TARGET_PLATFORM = linux-g++-64
TARGET_X11_LIB = /usr/X11R6/lib64
TARGET_PKG_CONFIG_PATH = /usr/lib64/pkgconfig:/usr/local/lib64/pkgconfig

# *Mandatory* compiler options on x86_64
OWN_CFLAGS = -m64 -fPIC

# Compiler options (optional)
OWN_CFLAGS += -O2 -pipe

# Optional compiler options for gcc >= 3.4.0
# OWN_CFLAGS += -march=opteron -O3 -pipe

else
ENABLE_LIBSUFFIX=
TARGET_LIBNAME = lib
TARGET_PLATFORM = linux-g++
TARGET_X11_LIB = /usr/X11R6/lib
TARGET_PKG_CONFIG_PATH = /usr/lib/pkgconfig:/usr/local/lib/pkgconfig

# Compiler options (optional)
OWN_CFLAGS = -O2 -pipe

endif
DESTDIR ?=
BUILD_PREFIX ?= \$(prefix)
#BUILD_PREFIX ?= \$(ROOTFROMDEST)/tmp/build

ifdef HAVE_QT_3_3_INSTALLED
# allow us to link to libraries we installed
CPPFLAGS := -I\$(DESTDIR)\$(includedir) -I\$(QTDIR)/include -I\$(DESTDIR)/usr/X11R6/include \$(CPPFLAGS)
CFLAGS := -I\$(DESTDIR)\$(includedir) -I\$(QTDIR)/include -I\$(DESTDIR)/usr/X11R6/include -L\$(DESTDIR)\$(libdir) -L\$(QTDIR)/\$(TARGET_LIBNAME) -L\$(DESTDIR)\$(TARGET_X11_LIB) \$(CFLAGS)
LDFLAGS := -L\$(DESTDIR)\$(libdir) -L\$(DESTDIR)\$(TARGET_X11_LIB) -L\$(QTDIR)/\$(TARGET_LIBNAME) \$(LDFLAGS)
# allow us to use programs we just built
PATH := \$(DESTDIR)\$(bindir):\$(DESTDIR)\$(sbindir):\$(DESTDIR)\$(BUILD_PREFIX)/bin:\$(DESTDIR)\$(BUILD_PREFIX)/sbin:\$(QTDIR)/bin:\$(PATH)
LD_LIBRARY_PATH := \$(DESTDIR)\$(libdir):\$(DESTDIR)\$(BUILD_PREFIX)/\$(TARGET_LIBNAME):\$(QTDIR)/\$(TARGET_LIBNAME):\$(LD_LIBRARY_PATH)
else
# allow us to link to libraries we installed
CPPFLAGS += -I\$(DESTDIR)\$(includedir) -I\$(DESTDIR)/usr/X11R6/include
CFLAGS += -I\$(DESTDIR)\$(includedir) -I\$(DESTDIR)/usr/X11R6/include -L\$(DESTDIR)\$(libdir) -L\$(DESTDIR)\$(TARGET_X11_LIB)
LDFLAGS += -L\$(DESTDIR)\$(libdir) -L\$(DESTDIR)\$(TARGET_X11_LIB)
# allow us to use programs we just built
PATH := \$(DESTDIR)\$(bindir):\$(DESTDIR)\$(sbindir):\$(DESTDIR)\$(BUILD_PREFIX)/bin:\$(DESTDIR)\$(BUILD_PREFIX)/sbin:\$(PATH)
LD_LIBRARY_PATH := \$(DESTDIR)\$(libdir):\$(DESTDIR)\$(BUILD_PREFIX)/\$(TARGET_LIBNAME):\$(LD_LIBRARY_PATH)
endif

# This is for foo-config chaos
PKG_CONFIG_PATH:=\$(DESTDIR)\$(libdir)/pkgconfig:\$(TARGET_PKG_CONFIG_PATH):\$(PKG_CONFIG_PATH)

# Now add own flags to CFLAGS and keep OWN_CFLAGS for qt-x11-free's Makefile.
CFLAGS += \$(OWN_CFLAGS)

# Equalise CFLAGS and CXXFLAGS
CXXFLAGS := \$(CFLAGS)

# If you have no following GNU tools installed change these lines
TAR = tar
MD5 = md5sum

# make these variables available to configure and build scripts
# outside of make's realm.
export DESTDIR prefix exec_prefix bindir sbindir libexecdir datadir sysconfdir
export sharedstatedir localstatedir libdir infodir lispdir includedir mandir
export docdir sourcedir
export CC CXX
export CPPFLAGS CFLAGS CXXFLAGS LDFLAGS PATH LD_LIBRARY_PATH LD_PRELOAD
export PKG_CONFIG_PATH BUILD_CLEAN

# prepend the local file listing
FILE_SITES = file://\$(FILEDIR)/ file://\$(GARCHIVEDIR)/
ENDOUT

We have finished the first part of the Kommander programme. Run it to make sure it correctly outputs the gar.conf.mk file.

== Compile ==

Our second tab will let the user compile and install KDE. It needs to contain some radio buttons with the value of different part of KDE that can be installed. It needs a button to run the install and it needs to display the output of the install. Here is the final thing:

compile-tab.png

Create a button group and add four radio buttons to it. Label them as above. Set the value of the button group to @widgetText and set its name property to installType. The value of the radio buttons from top to bottom should be kde/kdebase, meta/kdepim-crypto, meta/kde and meta/kde.

Add an execButton and label it Install KDE. Now add a Konsole widget ("a listbox showing output from a script"). The Kommander text for the Konsole widget should be the shell script required to run Konstruct:

export TERM=dumb
echo cd @outputDir/@installType
cd @outputDir/@installType 2>&1
echo make install
make install 2>&1
echo done

Unlike with the script on the previous tab which was directly associated with the button, here we have to tell the button to signal that the Konsole script should be run. Click on the Connect Signal/Slot button at the left of the second row of toolbars. [image connect-button.png] Then click on the "Install KDE" button and drag the mouse to the Konsole. It will open up the Connections dialogue. Choose the clicked() signal from the button and the execute() signal from the Konsole the click Connect.

Run your dialogue. When you click on "Install KDE" it should do just that.

== Languages ==

Most people do not speak US English with its "checkboxes" and "braces" so Konstruct gives you the option of many languges that can be downloaded and installed for KDE. Our third tab will let you do just that.

language-tab.png

I'll let you fill in the details here, we have an ExecButton labelled "Get Languages", a List Box widget which has a populate Kommander Text of @exec("ls -1d @outputDir/i18n/kde*"). Connect the button clicked() signal to the list box's populate() slot.

Finally we need a button labelled "Install Selected Language" and a Konsole with this script.

export TERM=dumb
echo cd @languagesList
cd @languagesList 2>&1
echo make install
make install 2>&1
echo done

Connect the button to the Konsole's execute() slot and you're finished.

== Tidying up ==

There is some tidying up to be done before our Kommander programme is ready to be let loose on the world. Rename the tabs to something sensible by right clicking on each one Settings, Compile && Install, Language. The double '&' there is needed because ampersands are used to indicate that the next letter is a keyboard accelarator. You may want to add keyboard accelarators to the widgets in the form by adding an '&' before the desired letter in the widget's label.

The widgets on the form are sat wherever you told them to go. This is a fixed width layout and won't work if the user's font size is to big or screen is too small for example. To layout the widgest properly you can group them horizontally and vertically. On the first tab shift-click the "Kommander directory" label and it's directory widget next to it. Then click on Lay Out Horizontally in the toolbar. Do the same for the downloaded label and selector widget. Select and group the three tickboxes vertically. Do the same for the install directory widgets and finally lay out all the grouped widgets into one big vertical layout. To lay out the items in the tab widget just click on the tab widget then click on the "Gid Layout" button in the toolbar. Do the same for the form itself.

final-programme.png

If the user is installing into /usr that will require root to install. Add a tickbox under the "other" radio button and label it Requires root to install Set its ticked value to be kdesu and unticked to be kdesu -u $USER? In the two install scripts for the Konsoles change "make install" into @installAsRoot make install.

That's all there is to creating a programme in Kommander - graphical scripting. You can find out more by looking at the examples which come with the Kommander sources or docs at http://www.kde.me.uk/kommander-tutorial/kommander-docs-html/

== Future of Kommander ==

Thanks to some hard work and generous sponsorship Kommander is under heavy development. There are a lot of features planned for the near future. Most important of these is an improved parser which will allow for local variables, nesting logic and integration with scripting languages other than bash.

There are also plans to allow for wizard style programmes and main windows (which means including a menubar and statusbar). More user friendly scripting integration so it is similar to actions and making the Kommander editor itself more extendable.

Hopefully it should also get a website soon. This may be extended to support KNewStuff (downloading and uploading people's Kommander programmes) and setting up a mini sourceforge site.

Finally, Kommander needs an icon, please send suggestions to kde-artists @kde.org

Copyleft (GNU FDL) Jonathan Riddell 2004

-
(note from mpathy: There is a Kommander Icon Contest going to start at kde-look.org - i would prefer a cat with a kommanders cap ;o)