<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://techbase.kde.org/skins/common/feed.css?0.2"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>http://techbase.kde.org/api.php?action=feedcontributions&amp;user=CuCullin&amp;feedformat=atom</id>
		<title>KDE TechBase - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="http://techbase.kde.org/api.php?action=feedcontributions&amp;user=CuCullin&amp;feedformat=atom"/>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Special:Contributions/CuCullin"/>
		<updated>2013-05-23T19:55:31Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.20.2</generator>

	<entry>
		<id>http://techbase.kde.org/Schedules/KDE4/4.1_Release_Goals</id>
		<title>Schedules/KDE4/4.1 Release Goals</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Schedules/KDE4/4.1_Release_Goals"/>
				<updated>2008-01-20T22:15:49Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: KDE on Windows Link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Goals for the 4.1 Release:&lt;br /&gt;
&lt;br /&gt;
* [[Projects/KDE_on_Windows|Windows port]] (Framworks and Applications)&lt;br /&gt;
* [[Projects/KDE_on_Mac_OS_X|Mac port]] (Frameworks and Applications)&lt;br /&gt;
* OpenSolaris port&lt;br /&gt;
* Plasma with widgets on canvas, makes things like layouting much easier, and generally integrating widgets into Plasmoids&lt;br /&gt;
* Webkit in Plasma&lt;br /&gt;
* GStreamer, Quicktime, DirectShow9 Phonon backends&lt;br /&gt;
* Apple dashboard widgets support in Plasma&lt;br /&gt;
* Decibel VOIP and real-time communication framework&lt;br /&gt;
* Dragon Player multimedia player&lt;br /&gt;
* Kaider computer-aided translation system&lt;br /&gt;
* More polished Kopete&lt;br /&gt;
* KDevelop and KDevplatform modules&lt;br /&gt;
* KDE-PIM module, with some Akonadi functionality&lt;br /&gt;
* Move Akonadi library into the kdepimlibs module&lt;br /&gt;
* GetHotNewStuff2 / DXS&lt;br /&gt;
* Plasmagik plasma packages and add-on creator&lt;br /&gt;
* Lots of smaller features&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Perl</id>
		<title>Development/Languages/Perl</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Perl"/>
				<updated>2007-07-03T17:15:16Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Created page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Perl is a powerful and versatile high-level programming language. You can find out more about the language itself on the [http://www.perl.org/ Perl Mongers website].&lt;br /&gt;
&lt;br /&gt;
Complete object-oriented bindings for Qt based on [[Development/Languages/Smoke|SMOKE]] are available on the [http://perlqt.sourceforge.net/ PerlQt project page].&lt;br /&gt;
&lt;br /&gt;
Those bindings provide virtual functions overloading, custom slots and signals, and Rapid Application Development (RAD) through puic, a Qt Designer compatible user interface compiler.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-31T19:40:16Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  System Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Startup ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Shutdown ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Hibernate ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Standby ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Logon ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Logoff ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Logon error ||  ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Desktop UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Minimize ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Minimize to Tray ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Maximize ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore from Tray ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Up ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Down ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Hover ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Select ||  ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Communication Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| New Email || A new email message is received || new-email&lt;br /&gt;
|-&lt;br /&gt;
| New IM || a new instant message is received || new-message&lt;br /&gt;
|-&lt;br /&gt;
| New alert ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Name mentioned in chat room? ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Connected to messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Disconnected from messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Joins ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Leaves ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Call ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Request to Join ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Contact Online ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Hardware Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Battery Charging ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Running on AC ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Low Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Critical Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Connected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Disconnected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Failed to Connect ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print sent to Queue ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print Complete ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-30T15:32:08Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Hardware Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Desktop UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Minimize ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Minimize to Tray ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Maximize ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore from Tray ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Up ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Down ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Hover ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Select ||  ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Communication Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| New Email || A new email message is received || new-email&lt;br /&gt;
|-&lt;br /&gt;
| New IM || a new instant message is received || new-message&lt;br /&gt;
|-&lt;br /&gt;
| New alert ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Name mentioned in chat room? ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Connected to messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Disconnected from messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Joins ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Leaves ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Call ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Request to Join ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Contact Online ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Hardware Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Battery Charging ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Running on AC ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Low Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Critical Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Connected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Disconnected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Failed to Connect ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print sent to Queue ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print Complete ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-30T15:31:44Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Communication Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Desktop UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Minimize ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Minimize to Tray ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Maximize ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore from Tray ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Up ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Down ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Hover ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Select ||  ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Communication Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| New Email || A new email message is received || new-email&lt;br /&gt;
|-&lt;br /&gt;
| New IM || a new instant message is received || new-message&lt;br /&gt;
|-&lt;br /&gt;
| New alert ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Name mentioned in chat room? ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Connected to messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Disconnected from messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Joins ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Leaves ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Call ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Request to Join ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Contact Online ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Hardware Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Battery Charging ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Running on AC ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Low Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Critical Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Connected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Disconnected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Failed to Connect ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print sent to Queue ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print Complete ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-30T15:31:23Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Hardware Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Desktop UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Minimize ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Minimize to Tray ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Maximize ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore from Tray ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Up ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Down ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Hover ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Select ||  ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Communication Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| New Email || A new email message is received || new-email&lt;br /&gt;
|-&lt;br /&gt;
| New IM || a new instant message is received || new-message&lt;br /&gt;
|-&lt;br /&gt;
| New alert ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Name mentioned in chat room? ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Connected to messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Disconnected from messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Joins ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Leaves ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Call ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Request to Join ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Contact Online ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Hardware Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Battery Charging ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Running on AC ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Low Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Critical Battery Alarm ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Connected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Disconnected ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Device Failed to Connect ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print sent to Queue ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Print Complete ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-30T15:29:17Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Communication Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Desktop UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Minimize ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Minimize to Tray ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Maximize ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore from Tray ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Up ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Down ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Hover ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Select ||  ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Communication Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| New Email || A new email message is received || new-email&lt;br /&gt;
|-&lt;br /&gt;
| New IM || a new instant message is received || new-message&lt;br /&gt;
|-&lt;br /&gt;
| New alert ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Name mentioned in chat room? ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Connected to messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Disconnected from messaging service ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Joins ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Person Leaves ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Call ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Receive Request to Join ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Contact Online ||  || &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-30T15:22:36Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* IRC Channels */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Web Sites ==&lt;br /&gt;
* [http://www.KDE.org KDE Home]&lt;br /&gt;
* [http://dot.kde.org KDE Dot News]&lt;br /&gt;
* [http://www.planetkde.org Planet KDE]&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;br /&gt;
&lt;br /&gt;
== IRC Channels ==&lt;br /&gt;
In general, IRC channels mentioned here are available on FreeNode. Connect to irc.kde.org, and check these channels out for further information.&lt;br /&gt;
&lt;br /&gt;
*KDE 4 Development - [irc://irc.kde.org:6667/kde4-devel #kde4-devel]&lt;br /&gt;
*KDE Development - [irc://irc.kde.org:6667/kde-devel #kde-devel]&lt;br /&gt;
*KDevelop - [irc://irc.kde.org:6667/kdevelop #kdevelop]&lt;br /&gt;
*Phonon - [irc://irc.kde.org:6667/phonon #phonon]&lt;br /&gt;
*Decibel - [irc://irc.kde.org:6667/decibel #decibel]&lt;br /&gt;
*Solid - [irc://irc.kde.org:6667/solid #solid]&lt;br /&gt;
&lt;br /&gt;
== Newsgroups ==&lt;br /&gt;
== Forums ==&lt;br /&gt;
== Events ==&lt;br /&gt;
== Courses and Certifications ==&lt;br /&gt;
== Audio and Video Casts ==&lt;br /&gt;
== Source Code Repositories ==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-30T15:20:48Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Desktop UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Desktop UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Minimize ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Minimize to Tray ||  || &lt;br /&gt;
|-&lt;br /&gt;
| Maximize ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Restore from Tray ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Up ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Shade Down ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Hover ||  ||&lt;br /&gt;
|-&lt;br /&gt;
| Icon Select ||  ||&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Communication Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| New Email || A new email message is received || new-email&lt;br /&gt;
|-&lt;br /&gt;
| New IM || a new instant message is received || new-message&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-29T18:18:08Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Communication Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Icon Hover?&lt;br /&gt;
* Icon Select?&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Communication Events&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| New Email || A new email message is received || new-email&lt;br /&gt;
|-&lt;br /&gt;
| New IM || a new instant message is received || new-message&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Partners</id>
		<title>Projects/Partners</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Partners"/>
				<updated>2007-01-29T18:14:23Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Current/Immediate Initiatives (Target: March) */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page is a collection area for thoughts on how to construct a strategy for partnerships with independant software vendors (ISVs) and system integrators (SIs) as well as implementation notes for same. Other partners are surely on the map as well, but right now we are focussing on the ISV/SI issue.&lt;br /&gt;
&lt;br /&gt;
The immediate game plan is:&lt;br /&gt;
* define what we will be doing with and for each of these groups&lt;br /&gt;
* turn that into a releasable communique for the press channel&lt;br /&gt;
* garner feedback and registrations of interest from people in both groups&lt;br /&gt;
* world domination.&lt;br /&gt;
&lt;br /&gt;
As this plan is fleshed out and we achieve points one and two, the results will be taken to the MWG, e.V. and then the general community. This will allow a staged introduction with peer review at each point.&lt;br /&gt;
&lt;br /&gt;
== ISVs ==&lt;br /&gt;
&lt;br /&gt;
The challenges we hear from ISVs tend to fall into a few common categories:&lt;br /&gt;
* binary compat across distributions&lt;br /&gt;
* clear desktop integration strategies for third party software&lt;br /&gt;
* lack of documentation (MSDN is often brought up)&lt;br /&gt;
* lack of relationship / partnership points with the community that are recognizable / make sense to them&lt;br /&gt;
* traditional tech support options&lt;br /&gt;
&lt;br /&gt;
The first two are out of scope of KDE itself, but we need to stress in our communications that we are involved in significant ways with both the LSB and Portland.&lt;br /&gt;
&lt;br /&gt;
== System Integrators (SIs) ==&lt;br /&gt;
&lt;br /&gt;
The initial target SIs will be regional companies with 5-500 employees. Obviously these are not the &amp;quot;big boys&amp;quot; but they are probably more accessible targets. The goal is to raise the number of companies that provide service and support for KDE based installations.&lt;br /&gt;
&lt;br /&gt;
== Sys Admins (SAs) ==&lt;br /&gt;
&lt;br /&gt;
There is obvious appeal to SAs and companies built around their professional services  given the information on the wiki. There is overlap here with SIs, but it may be worthwhile to look at the implications unique to SAs.&lt;br /&gt;
&lt;br /&gt;
== KDE e.V. Supporting Members Program (SMP) ==&lt;br /&gt;
&lt;br /&gt;
The SMP relies on parties with vested interests in KDE. While there are many such entities today, this partner program will be used to widen the top of the prospects funnel by creating vested interests and identifying existing ones. It should be a natural consequence for those most involved with this program will become interested over time in the SMP.&lt;br /&gt;
&lt;br /&gt;
In one sense, this program and the SMP work in opposite directions: this program gives information and interface to the outside world and the SMP is a means for the beneficiaries of the program to give back to KDE.&lt;br /&gt;
&lt;br /&gt;
== The Plan ==&lt;br /&gt;
&lt;br /&gt;
=== Current/Immediate Initiatives (Target: March) ===&lt;br /&gt;
* kdelibs.com&lt;br /&gt;
** repositioned as an isv site&lt;br /&gt;
** rebranded to match devnew&lt;br /&gt;
** win32 build system settles down and the tutorials are then moved to devnew&lt;br /&gt;
** isv.kde.org is registered and points to kdelibs.com&lt;br /&gt;
** the isv section on devnew moves to isv.kde.org as its main page content&lt;br /&gt;
*** the tools and libraries link there point to devnew&lt;br /&gt;
&lt;br /&gt;
* devnew&lt;br /&gt;
** becomes [[Projects/NamingTheWiki|${SOMETHING}.k.o]] and will be launched with KDE4 as our answer to MSDN and the Apple Developer Connection&lt;br /&gt;
** isv entry points to isv.kde.org&lt;br /&gt;
&lt;br /&gt;
* online registration and survey form to be referenced from announcement&lt;br /&gt;
&lt;br /&gt;
=== Mid-term ===&lt;br /&gt;
&lt;br /&gt;
* create membership programs for ISVs and SIs&lt;br /&gt;
** online registry where they can be found by possible clients, list their titles, etc&lt;br /&gt;
** mail-out packages for each group&lt;br /&gt;
*** glossy version of our isv.kde.org info&lt;br /&gt;
*** pointers to online information sources&lt;br /&gt;
*** information they can pass on to potential clients&lt;br /&gt;
&lt;br /&gt;
* organize an ISV/SI conference&lt;br /&gt;
&lt;br /&gt;
* an ISV issue tracker (Staniek)&lt;br /&gt;
&lt;br /&gt;
=== Blue Sky Thinking ===&lt;br /&gt;
&lt;br /&gt;
* build the online registry in a social B2B networking system?&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-22T19:31:05Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Menu UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Icon Hover?&lt;br /&gt;
* Icon Select?&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 3.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-22T18:54:48Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Menu UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Icon Hover?&lt;br /&gt;
* Icon Select?&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Menu UI&lt;br /&gt;
! Name !! Description !! Filename&lt;br /&gt;
|-&lt;br /&gt;
| Menu Button Select || Selecting the K Menu || menu-button-select&lt;br /&gt;
|-&lt;br /&gt;
| Menu Browse || Browsing through the menu, on a new menu item hover || menu-browse&lt;br /&gt;
|-&lt;br /&gt;
| Menu Item Select || Selecting a menu item || menu-item-select&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-22T18:41:13Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Desktop UI */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Icon Hover?&lt;br /&gt;
* Icon Select?&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
* Menu Browse&lt;br /&gt;
* Menu Select&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-22T18:40:42Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Exit&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
=== Desktop UI ===&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
&lt;br /&gt;
=== Menu UI ===&lt;br /&gt;
* Menu Browse&lt;br /&gt;
* Menu Select&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== Hardware Events ==&lt;br /&gt;
&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* '''Print Complete?'''&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-22T18:33:54Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Overview */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
Sound is an important element used to communicate with users.  It is important, then, that there be a unified and simplified way of organizing sounds.&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
 1.5 INFORMATION DIALOG&lt;br /&gt;
&lt;br /&gt;
 1.6 WARNING DIALOG&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Exit&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Print Complete&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* Start&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Menu Browse&lt;br /&gt;
* Menu Select&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-22T18:20:36Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* System Events */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
 1.5 INFORMATION DIALOG&lt;br /&gt;
&lt;br /&gt;
 1.6 WARNING DIALOG&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
* Critical Battery Alarm&lt;br /&gt;
* Critical Stop&lt;br /&gt;
* Default Beep&lt;br /&gt;
* Device Connect&lt;br /&gt;
* Device Disconnect&lt;br /&gt;
* Device Failed to Connect&lt;br /&gt;
* Exit&lt;br /&gt;
* Low Battery Alarm&lt;br /&gt;
* Menu Popup&lt;br /&gt;
* Open Program&lt;br /&gt;
* Print Complete&lt;br /&gt;
* Program Error&lt;br /&gt;
* Question&lt;br /&gt;
* Restore Down&lt;br /&gt;
* Restore Up&lt;br /&gt;
* Select&lt;br /&gt;
* Show Toolbar&lt;br /&gt;
* Start&lt;br /&gt;
* System Notification&lt;br /&gt;
* Logoff&lt;br /&gt;
* Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Menu Browse&lt;br /&gt;
* Menu Select&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-22T18:19:23Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* References */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
Critical Battery Alarm&lt;br /&gt;
Critical Stop&lt;br /&gt;
Default Beep&lt;br /&gt;
Device Connect&lt;br /&gt;
Device Disconnect&lt;br /&gt;
Device Failed to Connect&lt;br /&gt;
Exclamation&lt;br /&gt;
Exit&lt;br /&gt;
Low Battery Alarm&lt;br /&gt;
Menu Popup&lt;br /&gt;
Open Program&lt;br /&gt;
Print Complete&lt;br /&gt;
Program Error&lt;br /&gt;
Question&lt;br /&gt;
Restore Down&lt;br /&gt;
Restore Up&lt;br /&gt;
Select&lt;br /&gt;
Show Toolbar&lt;br /&gt;
Start&lt;br /&gt;
System Notification&lt;br /&gt;
Logoff&lt;br /&gt;
Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Menu Browse&lt;br /&gt;
* Menu Select&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== File/Web Browser ==&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Projects/NamingTheWiki</id>
		<title>Talk:Projects/NamingTheWiki</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Projects/NamingTheWiki"/>
				<updated>2007-01-19T18:49:44Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Name Suggestions */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Name Suggestions =&lt;br /&gt;
&lt;br /&gt;
: '''TechZone''': I like this name for several reasons: They give a clue on the pages purpose, are not biased towards either devs or system integrators, and leave room to brand them (Question to Promo team: is that a good idea). Please note that we will redirect developer.kde.org to this domain, so people who are looking for this domain straight will still end up in the right place. The word ''Base'' in '''Tech''Base''''' was criticized as being meaningless plus there is already a domain called devbase.com, and I want to stay out of tm issues. --[[User:Danimo|Danimo]] 01:42, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
::I agree with these ideas.  Regarding not biasing articles, that imho is a particularly important idea.  While the major apps/suites (KOffice, Kontact, Kolab, Kopete, etc) are taken care of, there is an incredibly vast set of vertical markets untouched by KDE.  These markets are not often discussed, yet make up a rather significant developer market.  Examples would be software to manage a dental office, consulting firm, accounting firm, millwork companies, etc.  Those working on this won't necessarily fall into a neat and clean category, so I'd consider this advantageous. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechBase''': I like this name because we already call the site that elsewhere, so there's some continuity. It also is representative of the fact that this site (as i understand it) is meant to be the base of technical information for and about KDE on the interwebs. There is a company called TechBase International&amp;quot;KDE Technical Reference&amp;quot; which does things completely unrelated to KDE so maybe there's some tm issues, but I doubt it. Perhaps we might want to have a thing where the full name of the site is ''KDE Technical Base'' and we just call it ''TechBase'' for short --[[User:Mattr|Mattr]] 02:22, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechCenter''': Similar to TechZone and TechBase. Maybe also similar to the [http://www.qtcentre.org/ qt-centre].&lt;br /&gt;
&lt;br /&gt;
: '''TechZone and TechBase ''': I feel that &amp;quot;tech[base|zone]&amp;quot;is a poor choice of name - it's a made up word and as such will age rapidly.  It's a lowest common denominator, meaningless choice. The KDE project is bigger than that and would be better served by clean, functional terms such as &amp;quot;KDE Technical Reference&amp;quot;, &amp;quot;KDE Technical Resource&amp;quot;. If it has to be one word, &amp;quot;Learn&amp;quot; or &amp;quot;Platform&amp;quot;. --[[User:Bille|Bille]] 23:18, 17 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''KDE Wiki''': ''Wiki'' is now a noun just like a ''web page''. Many of us are used to talking ''KDevelop wiki'', ''SUSE wiki'', and even below, Daniel used ''Kolab Wiki'' for Kolab. After all ''it's easy to remember'' and compatible with KISS principles... --[[User:Jstaniek|jstaniek]] 16:10, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: The thing I don't like about this is that it ''is'' just a noun like &amp;quot;web page&amp;quot;.  This site has a purpose, and I think the name should promote that purpose - otherwise, there would be no limitation on any KDE content going on here.  Users might add application manuals, or e.V. info could go on here, whatever.  That would only create confusion imho. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: Isn't the ''KDE wiki'' wiki.kde.org? That's already taken. Besides, we still need a name on the right of the KDE logo. &amp;quot;KDE Technical Reference&amp;quot; or similar titles are better than &amp;quot;KDE wiki&amp;quot;. --[[User:Dhaumann|Dhaumann]] 16:56, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
::: I thought the old wiki.kde.org, now '''redundant''' (look at its TOC), is pretty much a history now when the new ''developernew'' wiki appeared, and as Mediawiki not only contains predictable hyperlinks and good interwiki and templates support, but its engine is far superior to the old one and constantly improved. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;At least I consider moving all of my content out of it elsewhere. There's no day when I did not have problems with its tikiwiki's configuration, html layout and speed. &amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Application manuals? The old wiki.kde.org does not contain this kind of stuff, so history shows it's not a problem. Every larger KDE apps can host its own wiki, as we know in case of KOffice, Kexi, KDevelop,  KDEWebDev family, etc. &amp;lt;u&amp;gt;So ''Wiki'' is still my favourite term.&amp;lt;/u&amp;gt;&amp;lt;br/&amp;gt;&amp;lt;br/&amp;gt;Regarding &amp;quot;KDE Technical Reference&amp;quot;, it sounds a bit serious. There's similar very popular (100x more according to google) term: '''&amp;quot;Knowledge Base&amp;quot;'''. Personally I have no problem with having wiki.kde.org (because it's as short as possible) and &amp;quot;Knowledge Base&amp;quot; title. --[[User:Jstaniek|jstaniek]] 18:54, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:::: Part of that, imho, is that wiki.kde.org (and TikiWiki) isn't as friendly as MediaWiki.  Perhaps it should be wiki.kde.org, and simply have a nice listing somewhere on this site discussing what does and does not belong on here, just to direct content that may be more appropriate elsewhere.  Personally, I like a more descriptive name because I think it separates this wiki from others.  --[[User:CuCullin|CuCullin]] 19:49, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: Do you also mean platform.kde.org or reference.kde.org then? We are searching for both a readable name and a subdomain name. --[[User:Dhaumann|Dhaumann]] 16:56, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
Hi! First time ever helping this community(I hope it's not the last time either)&lt;br /&gt;
&lt;br /&gt;
The name should reflect the whole KDE project as (the way I see it) it tries to group everything KDE will be doing in the future to one wiki.&lt;br /&gt;
&lt;br /&gt;
My name: '''Conquer KDE''' or '''Konquer KDE''' depending if you like to replace the &amp;quot;C&amp;quot; by a &amp;quot;K&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
As I read on the mailing list, we are trying to promote KDE to the OSV and to the system admins as well so the Slogan would be a nice way to name the wiki.--[[User:Imagine|Imagine]] 19:11, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Scope of This Wiki =&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Target Audiences =&lt;br /&gt;
&lt;br /&gt;
:Perhaps someone could clarify what is meant by &amp;quot;system administrators&amp;quot;. At the extreme this term could apply to everyone from those with root on their local desktop install to people managing a network of thousands of PCs. I suspect the first of these includes the vast majority of KDE users. I assume this is not what is intended as this is a separate site to wiki.kde.org. -- TheoSpears&lt;br /&gt;
&lt;br /&gt;
::We're talking about people that administer a multitude of PCs, probably they are doing this professionally most of the time. We want to provide resources for them (howtos, scripts, pittfalls and workarounds). The wiki also gives us the unique chance that they can contribute their knowledge back (works fine e.g. on the [http://wiki.kolab.org Kolab Wiki]. --[[User:Danimo|Danimo]] 02:12, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:::Also, do we need to put this up on this site? The question being, does Sys Admin information belong? Or should it remain at http://www.kde.org/areas/sysadmin/ ? --[[User:CuCullin|CuCullin]] 18:22, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:::This is also a place where sys admins can find out more about the whole KDE community. This Wiki should be more like the very first place for anyone who wants to know what is KDE. Screenshot, announcement, the best apps(amarok, k3b, koffice, konqueror, etc.), so that the user will WANT to try this out.--[[User:Imagine|Imagine]] 19:16, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:With such an international audience, presumably we need to think about how the name carries around the world. I know that this can sink any discussion with concerns from every country, but I wonder how well (for example) 'zone' and 'base' are understood in this context, particularly since both have more than one meaning in English. [[User:Tomchance|Tomchance]] 08:24, 19 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Projects/NamingTheWiki</id>
		<title>Talk:Projects/NamingTheWiki</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Projects/NamingTheWiki"/>
				<updated>2007-01-19T17:22:24Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Thoughts on the Target Audiences */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Name Suggestions =&lt;br /&gt;
&lt;br /&gt;
: '''TechZone''': I like this name for several reasons: They give a clue on the pages purpose, are not biased towards either devs or system integrators, and leave room to brand them (Question to Promo team: is that a good idea). Please note that we will redirect developer.kde.org to this domain, so people who are looking for this domain straight will still end up in the right place. The word ''Base'' in '''Tech''Base''''' was criticized as being meaningless plus there is already a domain called devbase.com, and I want to stay out of tm issues. --[[User:Danimo|Danimo]] 01:42, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
::I agree with these ideas.  Regarding not biasing articles, that imho is a particularly important idea.  While the major apps/suites (KOffice, Kontact, Kolab, Kopete, etc) are taken care of, there is an incredibly vast set of vertical markets untouched by KDE.  These markets are not often discussed, yet make up a rather significant developer market.  Examples would be software to manage a dental office, consulting firm, accounting firm, millwork companies, etc.  Those working on this won't necessarily fall into a neat and clean category, so I'd consider this advantageous. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechBase''': I like this name because we already call the site that elsewhere, so there's some continuity. It also is representative of the fact that this site (as i understand it) is meant to be the base of technical information for and about KDE on the interwebs. There is a company called TechBase International which does things completely unrelated to KDE so maybe there's some tm issues, but I doubt it. Perhaps we might want to have a thing where the full name of the site is ''KDE Technical Base'' and we just call it ''TechBase'' for short --[[User:Mattr|Mattr]] 02:22, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechCenter''': Similar to TechZone and TechBase. Maybe also similar to the [http://www.qtcentre.org/ qt-centre].&lt;br /&gt;
&lt;br /&gt;
: '''TechZone and TechBase ''': I feel that &amp;quot;tech[base|zone]&amp;quot;is a poor choice of name - it's a made up word and as such will age rapidly.  It's a lowest common denominator, meaningless choice. The KDE project is bigger than that and would be better served by clean, functional terms such as &amp;quot;KDE Technical Reference&amp;quot;, &amp;quot;KDE Technical Resource&amp;quot;. If it has to be one word, &amp;quot;Learn&amp;quot; or &amp;quot;Platform&amp;quot;. --[[User:Bille|Bille]] 23:18, 17 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''KDE Wiki''': ''Wiki'' is now a noun just like a ''web page''. Many of us are used to talking ''KDevelop wiki'', ''SUSE wiki'', and even below, Daniel used ''Kolab Wiki'' for Kolab. After all ''it's easy to remember'' and compatible with KISS principles... --[[User:Jstaniek|jstaniek]] 16:10, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: The thing I don't like about this is that it ''is'' just a noun like &amp;quot;web page&amp;quot;.  This site has a purpose, and I think the name should promote that purpose - otherwise, there would be no limitation on any KDE content going on here.  Users might add application manuals, or e.V. info could go on here, whatever.  That would only create confusion imho. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: Isn't the ''KDE wiki'' wiki.kde.org? That's already taken. Besides, we still need a name on the right of the KDE logo. &amp;quot;KDE Technical Reference&amp;quot; or similar titles are better than &amp;quot;KDE wiki&amp;quot;. --[[User:Dhaumann|Dhaumann]] 16:56, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: Do you also mean platform.kde.org or reference.kde.org then? We are searching for both a readable name and a subdomain name. --[[User:Dhaumann|Dhaumann]] 16:56, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Discussion format == &lt;br /&gt;
&lt;br /&gt;
: '''name''': explanation&lt;br /&gt;
:: reply to this naming suggestion&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Scope of This Wiki =&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Target Audiences =&lt;br /&gt;
&lt;br /&gt;
:Perhaps someone could clarify what is meant by &amp;quot;system administrators&amp;quot;. At the extreme this term could apply to everyone from those with root on their local desktop install to people managing a network of thousands of PCs. I suspect the first of these includes the vast majority of KDE users. I assume this is not what is intended as this is a separate site to wiki.kde.org. -- TheoSpears&lt;br /&gt;
&lt;br /&gt;
::We're talking about people that administer a multitude of PCs, probably they are doing this professionally most of the time. We want to provide resources for them (howtos, scripts, pittfalls and workarounds). The wiki also gives us the unique chance that they can contribute their knowledge back (works fine e.g. on the [http://wiki.kolab.org Kolab Wiki]. --[[User:Danimo|Danimo]] 02:12, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:::Also, do we need to put this up on this site? The question being, does Sys Admin information belong? Or should it remain at http://www.kde.org/areas/sysadmin/ ? --[[User:CuCullin|CuCullin]] 18:22, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:With such an international audience, presumably we need to think about how the name carries around the world. I know that this can sink any discussion with concerns from every country, but I wonder how well (for example) 'zone' and 'base' are understood in this context, particularly since both have more than one meaning in English. [[User:Tomchance|Tomchance]] 08:24, 19 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Projects/NamingTheWiki</id>
		<title>Talk:Projects/NamingTheWiki</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Projects/NamingTheWiki"/>
				<updated>2007-01-19T17:22:08Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Thoughts on the Target Audiences */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Name Suggestions =&lt;br /&gt;
&lt;br /&gt;
: '''TechZone''': I like this name for several reasons: They give a clue on the pages purpose, are not biased towards either devs or system integrators, and leave room to brand them (Question to Promo team: is that a good idea). Please note that we will redirect developer.kde.org to this domain, so people who are looking for this domain straight will still end up in the right place. The word ''Base'' in '''Tech''Base''''' was criticized as being meaningless plus there is already a domain called devbase.com, and I want to stay out of tm issues. --[[User:Danimo|Danimo]] 01:42, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
::I agree with these ideas.  Regarding not biasing articles, that imho is a particularly important idea.  While the major apps/suites (KOffice, Kontact, Kolab, Kopete, etc) are taken care of, there is an incredibly vast set of vertical markets untouched by KDE.  These markets are not often discussed, yet make up a rather significant developer market.  Examples would be software to manage a dental office, consulting firm, accounting firm, millwork companies, etc.  Those working on this won't necessarily fall into a neat and clean category, so I'd consider this advantageous. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechBase''': I like this name because we already call the site that elsewhere, so there's some continuity. It also is representative of the fact that this site (as i understand it) is meant to be the base of technical information for and about KDE on the interwebs. There is a company called TechBase International which does things completely unrelated to KDE so maybe there's some tm issues, but I doubt it. Perhaps we might want to have a thing where the full name of the site is ''KDE Technical Base'' and we just call it ''TechBase'' for short --[[User:Mattr|Mattr]] 02:22, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechCenter''': Similar to TechZone and TechBase. Maybe also similar to the [http://www.qtcentre.org/ qt-centre].&lt;br /&gt;
&lt;br /&gt;
: '''TechZone and TechBase ''': I feel that &amp;quot;tech[base|zone]&amp;quot;is a poor choice of name - it's a made up word and as such will age rapidly.  It's a lowest common denominator, meaningless choice. The KDE project is bigger than that and would be better served by clean, functional terms such as &amp;quot;KDE Technical Reference&amp;quot;, &amp;quot;KDE Technical Resource&amp;quot;. If it has to be one word, &amp;quot;Learn&amp;quot; or &amp;quot;Platform&amp;quot;. --[[User:Bille|Bille]] 23:18, 17 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''KDE Wiki''': ''Wiki'' is now a noun just like a ''web page''. Many of us are used to talking ''KDevelop wiki'', ''SUSE wiki'', and even below, Daniel used ''Kolab Wiki'' for Kolab. After all ''it's easy to remember'' and compatible with KISS principles... --[[User:Jstaniek|jstaniek]] 16:10, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: The thing I don't like about this is that it ''is'' just a noun like &amp;quot;web page&amp;quot;.  This site has a purpose, and I think the name should promote that purpose - otherwise, there would be no limitation on any KDE content going on here.  Users might add application manuals, or e.V. info could go on here, whatever.  That would only create confusion imho. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: Isn't the ''KDE wiki'' wiki.kde.org? That's already taken. Besides, we still need a name on the right of the KDE logo. &amp;quot;KDE Technical Reference&amp;quot; or similar titles are better than &amp;quot;KDE wiki&amp;quot;. --[[User:Dhaumann|Dhaumann]] 16:56, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: Do you also mean platform.kde.org or reference.kde.org then? We are searching for both a readable name and a subdomain name. --[[User:Dhaumann|Dhaumann]] 16:56, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Discussion format == &lt;br /&gt;
&lt;br /&gt;
: '''name''': explanation&lt;br /&gt;
:: reply to this naming suggestion&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Scope of This Wiki =&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Target Audiences =&lt;br /&gt;
&lt;br /&gt;
:Perhaps someone could clarify what is meant by &amp;quot;system administrators&amp;quot;. At the extreme this term could apply to everyone from those with root on their local desktop install to people managing a network of thousands of PCs. I suspect the first of these includes the vast majority of KDE users. I assume this is not what is intended as this is a separate site to wiki.kde.org. -- TheoSpears&lt;br /&gt;
&lt;br /&gt;
::We're talking about people that administer a multitude of PCs, probably they are doing this professionally most of the time. We want to provide resources for them (howtos, scripts, pittfalls and workarounds). The wiki also gives us the unique chance that they can contribute their knowledge back (works fine e.g. on the [http://wiki.kolab.org Kolab Wiki]. --[[User:Danimo|Danimo]] 02:12, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:::Also, do we need to put this up on this site? The question being, does Sys Admin information belong? Or should it remain at http://www.kde.org/areas/sysadmin/ ?&lt;br /&gt;
&lt;br /&gt;
:With such an international audience, presumably we need to think about how the name carries around the world. I know that this can sink any discussion with concerns from every country, but I wonder how well (for example) 'zone' and 'base' are understood in this context, particularly since both have more than one meaning in English. [[User:Tomchance|Tomchance]] 08:24, 19 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-19T17:12:56Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* IRC Channels */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Web Sites ==&lt;br /&gt;
* [http://www.KDE.org KDE Home]&lt;br /&gt;
* [http://dot.kde.org KDE Dot News]&lt;br /&gt;
* [http://www.planetkde.org Planet KDE]&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;br /&gt;
&lt;br /&gt;
== IRC Channels ==&lt;br /&gt;
In general, IRC channels mentioned here are available on FreeNode. Connect to irc.kde.org, and check these channels out for further information.&lt;br /&gt;
&lt;br /&gt;
*KDE 4 Development - #kde4-devel&lt;br /&gt;
*KDE Development - #kde-devel&lt;br /&gt;
*KDevelop - #kdevelop&lt;br /&gt;
*Phonon - #phonon&lt;br /&gt;
*Decibel - #decibel&lt;br /&gt;
*Solid - #solid&lt;br /&gt;
&lt;br /&gt;
== Newsgroups ==&lt;br /&gt;
== Forums ==&lt;br /&gt;
== Events ==&lt;br /&gt;
== Courses and Certifications ==&lt;br /&gt;
== Audio and Video Casts ==&lt;br /&gt;
== Source Code Repositories ==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-19T17:12:39Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* IRC Channels */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Web Sites ==&lt;br /&gt;
* [http://www.KDE.org KDE Home]&lt;br /&gt;
* [http://dot.kde.org KDE Dot News]&lt;br /&gt;
* [http://www.planetkde.org Planet KDE]&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;br /&gt;
&lt;br /&gt;
== IRC Channels ==&lt;br /&gt;
In general, IRC channels mentioned here are available on FreeNode. Connect to irc.kde.org, and check these channels out for further information.&lt;br /&gt;
&lt;br /&gt;
KDE 4 Development - #kde4-devel&lt;br /&gt;
KDE Development - #kde-devel&lt;br /&gt;
KDevelop - #kdevelop&lt;br /&gt;
Phonon - #phonon&lt;br /&gt;
Decibel - #decibel&lt;br /&gt;
Solid - #solid&lt;br /&gt;
&lt;br /&gt;
== Newsgroups ==&lt;br /&gt;
== Forums ==&lt;br /&gt;
== Events ==&lt;br /&gt;
== Courses and Certifications ==&lt;br /&gt;
== Audio and Video Casts ==&lt;br /&gt;
== Source Code Repositories ==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-19T17:10:33Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Web Sites */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Web Sites ==&lt;br /&gt;
* [http://www.KDE.org KDE Home]&lt;br /&gt;
* [http://dot.kde.org KDE Dot News]&lt;br /&gt;
* [http://www.planetkde.org Planet KDE]&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;br /&gt;
&lt;br /&gt;
== IRC Channels ==&lt;br /&gt;
== Newsgroups ==&lt;br /&gt;
== Forums ==&lt;br /&gt;
== Events ==&lt;br /&gt;
== Courses and Certifications ==&lt;br /&gt;
== Audio and Video Casts ==&lt;br /&gt;
== Source Code Repositories ==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-19T16:16:02Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Web Sites ==&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;br /&gt;
&lt;br /&gt;
== IRC Channels ==&lt;br /&gt;
== Newsgroups ==&lt;br /&gt;
== Forums ==&lt;br /&gt;
== Events ==&lt;br /&gt;
== Courses and Certifications ==&lt;br /&gt;
== Audio and Video Casts ==&lt;br /&gt;
== Source Code Repositories ==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-19T16:15:31Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt; Places to put your code &lt;br /&gt;
 irc channels &lt;br /&gt;
 Newsgroups &lt;br /&gt;
 Forums &lt;br /&gt;
 Events &lt;br /&gt;
 Could also house sections designated to vertical markets such as medical, education, government, etc. &lt;br /&gt;
 Applicable courses and certifications &lt;br /&gt;
 Audio and Video casts&lt;br /&gt;
&lt;br /&gt;
== Web Sites ==&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;br /&gt;
&lt;br /&gt;
== IRC Channels ==&lt;br /&gt;
== Newsgroups ==&lt;br /&gt;
== Forums ==&lt;br /&gt;
== Events ==&lt;br /&gt;
== Courses and Certifications ==&lt;br /&gt;
== Audio and Video Casts ==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-19T16:12:15Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Development/Further Reading moved to Development/Further Information: Wrong name by accident...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Web Sites ==&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Further_Information</id>
		<title>Development/Further Information</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Further_Information"/>
				<updated>2007-01-19T16:10:17Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Web Sites ==&lt;br /&gt;
&lt;br /&gt;
==Blogs==&lt;br /&gt;
&lt;br /&gt;
== Books ==&lt;br /&gt;
Below are a list of books associated with KDE 4 development.  These may be specific to applications, using the Qt Toolkit, or specifically KDE 4 books.&lt;br /&gt;
&lt;br /&gt;
===KDE 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Qt 4 Development Books===&lt;br /&gt;
&lt;br /&gt;
==== English ====&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131879057&amp;amp;rl=1|The Book of Qt 4: The Art of Building Qt Applications By Alan Ezust, Paul Ezust.]&lt;br /&gt;
&lt;br /&gt;
[http://www.phptr.com/bookstore/product.asp?isbn=0131872494&amp;amp;rl=1|C++ GUI Programming with Qt 4 By Jasmin Blanchette, Mark Summerfield.]&lt;br /&gt;
&lt;br /&gt;
==== German ====&lt;br /&gt;
&lt;br /&gt;
[https://www.opensourcepress.de/index.php?26&amp;amp;backPID=15&amp;amp;tt_products=23 Qt 4: Einführung in die Applikationsentwicklung von Daniel Molkentin]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Projects/NamingTheWiki</id>
		<title>Talk:Projects/NamingTheWiki</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Projects/NamingTheWiki"/>
				<updated>2007-01-19T15:21:09Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Name Suggestions */  TechZone (and proofreading qt-centre)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;= Name Suggestions =&lt;br /&gt;
&lt;br /&gt;
: '''TechZone''': I like this name for several reasons: They give a clue on the pages purpose, are not biased towards either devs or system integrators, and leave room to brand them (Question to Promo team: is that a good idea). Please note that we will redirect developer.kde.org to this domain, so people who are looking for this domain straight will still end up in the right place. The word ''Base'' in '''Tech''Base''''' was criticized as being meaningless plus there is already a domain called devbase.com, and I want to stay out of tm issues. --[[User:Danimo|Danimo]] 01:42, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
::I agree with these ideas.  Regarding not biasing articles, that imho is a particularly important idea.  While the major apps/suites (KOffice, Kontact, Kolab, Kopete, etc) are taken care of, there is an incredibly vast set of vertical markets untouched by KDE.  These markets are not often discussed, yet make up a rather significant developer market.  Examples would be software to manage a dental office, consulting firm, accounting firm, millwork companies, etc.  Those working on this won't necessarily fall into a neat and clean category, so I'd consider this advantageous. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechBase''': I like this name because we already call the site that elsewhere, so there's some continuity. It also is representative of the fact that this site (as i understand it) is meant to be the base of technical information for and about KDE on the interwebs. There is a company called TechBase International which does things completely unrelated to KDE so maybe there's some tm issues, but I doubt it. Perhaps we might want to have a thing where the full name of the site is ''KDE Technical Base'' and we just call it ''TechBase'' for short --[[User:Mattr|Mattr]] 02:22, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''TechCenter''': Similar to TechZone and TechBase. Maybe also similar to the [http://www.qtcentre.org/ qt-centre].&lt;br /&gt;
&lt;br /&gt;
: '''TechZone and TechBase ''': I feel that &amp;quot;tech[base|zone]&amp;quot;is a poor choice of name - it's a made up word and as such will age rapidly.  It's a lowest common denominator, meaningless choice. The KDE project is bigger than that and would be better served by clean, functional terms such as &amp;quot;KDE Technical Reference&amp;quot;, &amp;quot;KDE Technical Resource&amp;quot;. If it has to be one word, &amp;quot;Learn&amp;quot; or &amp;quot;Platform&amp;quot;. --[[User:Bille|Bille]] 23:18, 17 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: '''KDE Wiki''': ''Wiki'' is now a noun just like a ''web page''. Many of us are used to talking ''KDevelop wiki'', ''SUSE wiki'', and even below, Daniel used ''Kolab Wiki'' for Kolab. After all ''it's easy to remember'' and compatible with KISS principles... --[[User:Jstaniek|jstaniek]] 16:10, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: The thing I don't like about this is that it ''is'' just a noun like &amp;quot;web page&amp;quot;.  This site has a purpose, and I think the name should promote that purpose - otherwise, there would be no limitation on any KDE content going on here.  Users might add application manuals, or e.V. info could go on here, whatever.  That would only create confusion imho. --[[User:CuCullin|CuCullin]] 16:21, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Discussion format == &lt;br /&gt;
&lt;br /&gt;
: '''name''': explanation&lt;br /&gt;
:: reply to this naming suggestion&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Scope of This Wiki =&lt;br /&gt;
&lt;br /&gt;
= Thoughts on the Target Audiences =&lt;br /&gt;
&lt;br /&gt;
:Perhaps someone could clarify what is meant by &amp;quot;system administrators&amp;quot;. At the extreme this term could apply to everyone from those with root on their local desktop install to people managing a network of thousands of PCs. I suspect the first of these includes the vast majority of KDE users. I assume this is not what is intended as this is a separate site to wiki.kde.org. -- TheoSpears&lt;br /&gt;
&lt;br /&gt;
::We're talking about people that administer a multitude of PCs, probably they are doing this professionally most of the time. We want to provide resources for them (howtos, scripts, pittfalls and workarounds). The wiki also gives us the unique chance that they can contribute their knowledge back (works fine e.g. on the [http://wiki.kolab.org Kolab Wiki]. --[[User:Danimo|Danimo]] 02:12, 19 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:With such an international audience, presumably we need to think about how the name carries around the world. I know that this can sink any discussion with concerns from every country, but I wonder how well (for example) 'zone' and 'base' are understood in this context, particularly since both have more than one meaning in English. [[User:Tomchance|Tomchance]] 08:24, 19 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/TechBase</id>
		<title>Projects/TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/TechBase"/>
				<updated>2007-01-18T19:53:53Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Developer Forums */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Tutorials Wanted/Needed ==&lt;br /&gt;
Ordered based on priority.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
* Techniques and available software&lt;br /&gt;
* Privacy concerns&lt;br /&gt;
* Regulatory compliance&lt;br /&gt;
* For network-oriented applications (see further down the task list)&lt;br /&gt;
* Important points of note for each OS (Linux, Solaris, Windows, Mac OS, etc)&lt;br /&gt;
&lt;br /&gt;
=== Further Information ===&lt;br /&gt;
The &amp;quot;Further Information section replaces &amp;quot;Recommended Books&amp;quot; under the Development section.  It should include:&lt;br /&gt;
&lt;br /&gt;
* Books&lt;br /&gt;
* Blogs&lt;br /&gt;
* Places to put your code&lt;br /&gt;
* irc channels&lt;br /&gt;
* Newsgroups&lt;br /&gt;
* Forums&lt;br /&gt;
* Events&lt;br /&gt;
* Could also house sections designated to vertical markets such as medical, education, government, etc.&lt;br /&gt;
* Applicable courses and certifications&lt;br /&gt;
* Audio and Video casts&lt;br /&gt;
&lt;br /&gt;
=== Web Development ===&lt;br /&gt;
&lt;br /&gt;
With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE is a premier web testing environment.  It is beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, etc), setting up such testing environments, etc.&lt;br /&gt;
&lt;br /&gt;
=== Rapid Application Development ===&lt;br /&gt;
* Ruby/Python/Perl/etc&lt;br /&gt;
* Need to get communities on board and contributing.&lt;br /&gt;
&lt;br /&gt;
=== KDevelop ===&lt;br /&gt;
* Learning the languages&lt;br /&gt;
* Tutorials using KDevelop; such as a tutorial in Getting Started&lt;br /&gt;
* kde edu people have done some tutorials in this area, contact and bring those tutorials here.&lt;br /&gt;
* Contact KDevelop developers to get their involvement on the wiki in this regard.&lt;br /&gt;
&lt;br /&gt;
=== Networked Services ===&lt;br /&gt;
* Web/Internet services&lt;br /&gt;
* How ISV's can make use of such things as ghns, kdepim/kode...&lt;br /&gt;
&lt;br /&gt;
=== KOffice as a Software Design Platform ===&lt;br /&gt;
* For collaboration and communication&lt;br /&gt;
* Get KOffice team on the wiki&lt;br /&gt;
&lt;br /&gt;
=== Portable Devices ===&lt;br /&gt;
*Working with them and KDE&lt;br /&gt;
*Creating a KDE app that makes use of OpenSync&lt;br /&gt;
*Links to Qtopia with info on interoperability&lt;br /&gt;
*ie: Konqueror Embedded&lt;br /&gt;
&lt;br /&gt;
=== Error Reporting Functionality ===&lt;br /&gt;
An ISV's ability to use a bug management system in place, by taking the app and setting up their own server as well, so that there is a reporting system in place already.  They could automate bug information like if desired, like grabbing logs, etc. &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns ===&lt;br /&gt;
* KDE specific elements should come first.  Low on the priority list.&lt;br /&gt;
&lt;br /&gt;
== Further Discussion Required ==&lt;br /&gt;
=== SysAdmin Tools ===&lt;br /&gt;
* http://kde.org/areas/sysadmin&lt;br /&gt;
&lt;br /&gt;
*'''Held off for further discussion'''.  May or may not belong, as this site will not be developer.kde.org, but TechBase.KDE.org.&lt;br /&gt;
&lt;br /&gt;
=== Developer Forums ===&lt;br /&gt;
* Forum admins should be subscribed to the MLs&lt;br /&gt;
* Forum is more for application developers than core developers&lt;br /&gt;
* Forum could have a gateway to the MLs, or the Admins and Moderators would act as the communications link when the need arises.&lt;br /&gt;
* Could be a subforum of a greater official KDE forum&lt;br /&gt;
&lt;br /&gt;
*'''May have manpower issues'''.&lt;br /&gt;
&lt;br /&gt;
== Sidelined ==&lt;br /&gt;
=== Business Communications Flow ===&lt;br /&gt;
&lt;br /&gt;
Developing software for the flow of enterprise communications has become an extremely wide are of software development as of late. Nepomuk/Akonadi may be part of this.&lt;br /&gt;
&lt;br /&gt;
* '''Sidelined until Akonadi can be further developed.'''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Welcome_to_KDE_TechBase</id>
		<title>Talk:Welcome to KDE TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Welcome_to_KDE_TechBase"/>
				<updated>2007-01-16T21:28:02Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &amp;quot;Develop&amp;quot; section....&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__ __NOEDITSECTION__&lt;br /&gt;
&lt;br /&gt;
==License==&lt;br /&gt;
I suggest we move to [http://creativecommons.org/licenses/by-sa/2.5/ cc-by-sa] right from the beginning. Please see the [http://people.debian.org/~srivasta/Position_Statement.xhtml Draft Debian Position Statement About The GNU Free Documentation License(GFDL)]. [[User:Logixoul|Logixoul]] 14:10, 8 September 2006 (CEST)&lt;br /&gt;
&lt;br /&gt;
:Or dual license, keep GFDL and use CC. (There was some discussion about this on Wikipedia iirc) [[User:CuCullin|CuCullin]] 19:31, 9 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Oxygen theme ==&lt;br /&gt;
&lt;br /&gt;
I really like the Oxygen theme on this wiki, but might we reconsider the fixed width bit?  It makes some of the pages (e.g. recent changes) not work as well, wrapping lines and making them difficult to read. --[[User:Axiom|Axiom]] 20:50, 14 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: We have had this discussion over and over again but at the same time we got very positive feedback (e.g. on the kde-www mailing list). Changing the layout is very unlikely. I agree that due to our use of subpages the urls get long and a bit unreadable, but that's hardly a reason to change the layout of all *kde.org pages. --[[User:Dhaumann|Dhaumann]] 23:49, 14 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
== Develop ==&lt;br /&gt;
&lt;br /&gt;
&amp;quot;Develop: Development wikis of various KDE projects&amp;quot;  No longer seems an appropriate title considering the links inside it.  Perhaps &amp;quot;Develop: KDE Projects&amp;quot; and then the description &amp;quot;Various KDE Projects, including links to development wikis, task lists, etc&amp;quot; or some such. --[[User:CuCullin|CuCullin]] 22:28, 16 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/MediaWiki_talk:Sidebar</id>
		<title>MediaWiki talk:Sidebar</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/MediaWiki_talk:Sidebar"/>
				<updated>2007-01-16T21:24:37Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I feel that the sidebar links are not really appropriate. The sidebar should be used to enable quick navigation of the site. The links should be to the top level pages like it is at [http://developer.kde.org/ http://developer.kde.org/]. Furthermore I propose removing &amp;quot;Random page&amp;quot; and maybe even &amp;quot;Recent changes&amp;quot; since they're not really useful to the reader (that is a developer who comes to this site looking for documentation etc.). --[[User:Milliams|milliams]] 16:28, 8 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
: yes, i have to say i'm not sure what real value &amp;quot;Recent changes&amp;quot; has for the average reader given the prominence of its location. i like that we have the sections there now, but i can't help but think that we could collapse &amp;quot;Navigation&amp;quot; and &amp;quot;Sections&amp;quot; into one group since they are essentially both the same thing.&lt;br /&gt;
&lt;br /&gt;
: &amp;quot;Donations&amp;quot; is under the &amp;quot;Interact&amp;quot; area on the main page. i'm uncertain it really belongs as a top-level item on every page's navigation though (feels a bit pushy?) the page it points to is also completely inappropriate and outdated content-wise. that page should simply be deleted and point to the support page on kde.org&lt;br /&gt;
&lt;br /&gt;
: finally, 'contribute' is &amp;quot;out of order&amp;quot; compared to the main page listings and i don't know if we need a link to projects in the sidebar since those aren't really &amp;quot;techbase&amp;quot; per say as much as a convenient place for individual projects and therefore not generally useful.&lt;br /&gt;
&lt;br /&gt;
: this would leave us with main page, help, getting started, development, policies, contribute, schedules under one heading. this would shorten the sidebar up to be only slightly longer than the &amp;quot;sections&amp;quot; section is on its own now. --[[User:Aseigo|Aseigo]] 18:05, 16 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: I agree on all counts, but it would be nice to keep Recent Changes (perhaps under personal tools?) for Wiki watching. --[[User:CuCullin|CuCullin]] 22:24, 16 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/TechBase</id>
		<title>Projects/TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/TechBase"/>
				<updated>2007-01-16T20:43:36Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Networked Services */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Tutorials Wanted/Needed ==&lt;br /&gt;
Ordered based on priority.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
* Techniques and available software&lt;br /&gt;
* Privacy concerns&lt;br /&gt;
* Regulatory compliance&lt;br /&gt;
* For network-oriented applications (see further down the task list)&lt;br /&gt;
* Important points of note for each OS (Linux, Solaris, Windows, Mac OS, etc)&lt;br /&gt;
&lt;br /&gt;
=== Further Information ===&lt;br /&gt;
The &amp;quot;Further Information section replaces &amp;quot;Recommended Books&amp;quot; under the Development section.  It should include:&lt;br /&gt;
&lt;br /&gt;
* Books&lt;br /&gt;
* Blogs&lt;br /&gt;
* Places to put your code&lt;br /&gt;
* irc channels&lt;br /&gt;
* Newsgroups&lt;br /&gt;
* Forums&lt;br /&gt;
* Events&lt;br /&gt;
* Could also house sections designated to vertical markets such as medical, education, government, etc.&lt;br /&gt;
* Applicable courses and certifications&lt;br /&gt;
* Audio and Video casts&lt;br /&gt;
&lt;br /&gt;
=== Web Development ===&lt;br /&gt;
&lt;br /&gt;
With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE is a premier web testing environment.  It is beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, etc), setting up such testing environments, etc.&lt;br /&gt;
&lt;br /&gt;
=== Rapid Application Development ===&lt;br /&gt;
* Ruby/Python/Perl/etc&lt;br /&gt;
* Need to get communities on board and contributing.&lt;br /&gt;
&lt;br /&gt;
=== KDevelop ===&lt;br /&gt;
* Learning the languages&lt;br /&gt;
* Tutorials using KDevelop; such as a tutorial in Getting Started&lt;br /&gt;
* kde edu people have done some tutorials in this area, contact and bring those tutorials here.&lt;br /&gt;
* Contact KDevelop developers to get their involvement on the wiki in this regard.&lt;br /&gt;
&lt;br /&gt;
=== Networked Services ===&lt;br /&gt;
* Web/Internet services&lt;br /&gt;
* How ISV's can make use of such things as ghns, kdepim/kode...&lt;br /&gt;
&lt;br /&gt;
=== KOffice as a Software Design Platform ===&lt;br /&gt;
* For collaboration and communication&lt;br /&gt;
* Get KOffice team on the wiki&lt;br /&gt;
&lt;br /&gt;
=== Portable Devices ===&lt;br /&gt;
*Working with them and KDE&lt;br /&gt;
*Creating a KDE app that makes use of OpenSync&lt;br /&gt;
*Links to Qtopia with info on interoperability&lt;br /&gt;
*ie: Konqueror Embedded&lt;br /&gt;
&lt;br /&gt;
=== Error Reporting Functionality ===&lt;br /&gt;
An ISV's ability to use a bug management system in place, by taking the app and setting up their own server as well, so that there is a reporting system in place already.  They could automate bug information like if desired, like grabbing logs, etc. &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns ===&lt;br /&gt;
* KDE specific elements should come first.  Low on the priority list.&lt;br /&gt;
&lt;br /&gt;
== Further Discussion Required ==&lt;br /&gt;
=== SysAdmin Tools ===&lt;br /&gt;
* http://kde.org/areas/sysadmin&lt;br /&gt;
&lt;br /&gt;
*'''Held off for further discussion'''.  May or may not belong, as this site will not be developer.kde.org, but TechBase.KDE.org.&lt;br /&gt;
&lt;br /&gt;
=== Developer Forums ===&lt;br /&gt;
* Forum admins should be subscribed to the MLs&lt;br /&gt;
* Forum is more for application developers than core developers&lt;br /&gt;
* Forum could have a gateway to the MLs, or the Admins and Moderators would act as the communications link when the need arises.&lt;br /&gt;
* Could be a subforum of a greater official KDE forum&lt;br /&gt;
&lt;br /&gt;
**'''May have manpower issues'''.&lt;br /&gt;
&lt;br /&gt;
== Sidelined ==&lt;br /&gt;
=== Business Communications Flow ===&lt;br /&gt;
&lt;br /&gt;
Developing software for the flow of enterprise communications has become an extremely wide are of software development as of late. Nepomuk/Akonadi may be part of this.&lt;br /&gt;
&lt;br /&gt;
* '''Sidelined until Akonadi can be further developed.'''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/TechBase</id>
		<title>Projects/TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/TechBase"/>
				<updated>2007-01-16T19:47:52Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Security */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Tutorials Wanted/Needed ==&lt;br /&gt;
Ordered based on priority.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
* Techniques and available software&lt;br /&gt;
* Privacy concerns&lt;br /&gt;
* Regulatory compliance&lt;br /&gt;
* For network-oriented applications (see further down the task list)&lt;br /&gt;
* Important points of note for each OS (Linux, Solaris, Windows, Mac OS, etc)&lt;br /&gt;
&lt;br /&gt;
=== Further Information ===&lt;br /&gt;
The &amp;quot;Further Information section replaces &amp;quot;Recommended Books&amp;quot; under the Development section.  It should include:&lt;br /&gt;
&lt;br /&gt;
* Books&lt;br /&gt;
* Blogs&lt;br /&gt;
* Places to put your code&lt;br /&gt;
* irc channels&lt;br /&gt;
* Newsgroups&lt;br /&gt;
* Forums&lt;br /&gt;
* Events&lt;br /&gt;
* Could also house sections designated to vertical markets such as medical, education, government, etc.&lt;br /&gt;
* Applicable courses and certifications&lt;br /&gt;
* Audio and Video casts&lt;br /&gt;
&lt;br /&gt;
=== Web Development ===&lt;br /&gt;
&lt;br /&gt;
With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE is a premier web testing environment.  It is beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, etc), setting up such testing environments, etc.&lt;br /&gt;
&lt;br /&gt;
=== Rapid Application Development ===&lt;br /&gt;
* Ruby/Python/Perl/etc&lt;br /&gt;
* Need to get communities on board and contributing.&lt;br /&gt;
&lt;br /&gt;
=== KDevelop ===&lt;br /&gt;
* Learning the languages&lt;br /&gt;
* Tutorials using KDevelop; such as a tutorial in Getting Started&lt;br /&gt;
* kde edu people have done some tutorials in this area, contact and bring those tutorials here.&lt;br /&gt;
* Contact KDevelop developers to get their involvement on the wiki in this regard.&lt;br /&gt;
&lt;br /&gt;
=== Networked Services ===&lt;br /&gt;
* Web/Internet services&lt;br /&gt;
* How ISV's can make use of such things as ghns, kdepim/kode...&lt;br /&gt;
&lt;br /&gt;
=== KOffice as a Software Design Platform&lt;br /&gt;
* For collaboration and communication&lt;br /&gt;
* Get KOffice team on the wiki&lt;br /&gt;
&lt;br /&gt;
=== Portable Devices ===&lt;br /&gt;
*Working with them and KDE&lt;br /&gt;
*Creating a KDE app that makes use of OpenSync&lt;br /&gt;
*Links to Qtopia with info on interoperability&lt;br /&gt;
*ie: Konqueror Embedded&lt;br /&gt;
&lt;br /&gt;
=== Error Reporting Functionality ===&lt;br /&gt;
An ISV's ability to use a bug management system in place, by taking the app and setting up their own server as well, so that there is a reporting system in place already.  They could automate bug information like if desired, like grabbing logs, etc. &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns ===&lt;br /&gt;
* KDE specific elements should come first.  Low on the priority list.&lt;br /&gt;
&lt;br /&gt;
== Further Discussion Required ==&lt;br /&gt;
=== SysAdmin Tools ===&lt;br /&gt;
* http://kde.org/areas/sysadmin&lt;br /&gt;
&lt;br /&gt;
*'''Held off for further discussion'''.  May or may not belong, as this site will not be developer.kde.org, but TechBase.KDE.org.&lt;br /&gt;
&lt;br /&gt;
=== Developer Forums ===&lt;br /&gt;
* Forum admins should be subscribed to the MLs&lt;br /&gt;
* Forum is more for application developers than core developers&lt;br /&gt;
* Forum could have a gateway to the MLs, or the Admins and Moderators would act as the communications link when the need arises.&lt;br /&gt;
* Could be a subforum of a greater official KDE forum&lt;br /&gt;
&lt;br /&gt;
**'''May have manpower issues'''.&lt;br /&gt;
&lt;br /&gt;
== Sidelined ==&lt;br /&gt;
=== Business Communications Flow ===&lt;br /&gt;
&lt;br /&gt;
Developing software for the flow of enterprise communications has become an extremely wide are of software development as of late. Nepomuk/Akonadi may be part of this.&lt;br /&gt;
&lt;br /&gt;
* '''Sidelined until Akonadi can be further developed.'''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Projects/TechBase</id>
		<title>Talk:Projects/TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Projects/TechBase"/>
				<updated>2007-01-16T19:40:42Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Any issues with the write up, or can this be linked to through Projects, and begin discussions where applicable? --[[User:CuCullin|CuCullin]] 20:40, 16 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/TechBase</id>
		<title>Projects/TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/TechBase"/>
				<updated>2007-01-16T02:52:37Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* KDevelop */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Tutorials Wanted/Needed ==&lt;br /&gt;
Ordered based on priority.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
* Techniques and available software&lt;br /&gt;
&lt;br /&gt;
=== Further Information ===&lt;br /&gt;
The &amp;quot;Further Information section replaces &amp;quot;Recommended Books&amp;quot; under the Development section.  It should include:&lt;br /&gt;
&lt;br /&gt;
* Books&lt;br /&gt;
* Blogs&lt;br /&gt;
* Places to put your code&lt;br /&gt;
* irc channels&lt;br /&gt;
* Newsgroups&lt;br /&gt;
* Forums&lt;br /&gt;
* Events&lt;br /&gt;
* Could also house sections designated to vertical markets such as medical, education, government, etc.&lt;br /&gt;
* Applicable courses and certifications&lt;br /&gt;
* Audio and Video casts&lt;br /&gt;
&lt;br /&gt;
=== Web Development ===&lt;br /&gt;
&lt;br /&gt;
With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE is a premier web testing environment.  It is beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, etc), setting up such testing environments, etc.&lt;br /&gt;
&lt;br /&gt;
=== Rapid Application Development ===&lt;br /&gt;
* Ruby/Python/Perl/etc&lt;br /&gt;
* Need to get communities on board and contributing.&lt;br /&gt;
&lt;br /&gt;
=== KDevelop ===&lt;br /&gt;
* Learning the languages&lt;br /&gt;
* Tutorials using KDevelop; such as a tutorial in Getting Started&lt;br /&gt;
* kde edu people have done some tutorials in this area, contact and bring those tutorials here.&lt;br /&gt;
* Contact KDevelop developers to get their involvement on the wiki in this regard.&lt;br /&gt;
&lt;br /&gt;
=== Networked Services ===&lt;br /&gt;
* Web/Internet services&lt;br /&gt;
* How ISV's can make use of such things as ghns, kdepim/kode...&lt;br /&gt;
&lt;br /&gt;
=== KOffice as a Software Design Platform&lt;br /&gt;
* For collaboration and communication&lt;br /&gt;
* Get KOffice team on the wiki&lt;br /&gt;
&lt;br /&gt;
=== Portable Devices ===&lt;br /&gt;
*Working with them and KDE&lt;br /&gt;
*Creating a KDE app that makes use of OpenSync&lt;br /&gt;
*Links to Qtopia with info on interoperability&lt;br /&gt;
*ie: Konqueror Embedded&lt;br /&gt;
&lt;br /&gt;
=== Error Reporting Functionality ===&lt;br /&gt;
An ISV's ability to use a bug management system in place, by taking the app and setting up their own server as well, so that there is a reporting system in place already.  They could automate bug information like if desired, like grabbing logs, etc. &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns ===&lt;br /&gt;
* KDE specific elements should come first.  Low on the priority list.&lt;br /&gt;
&lt;br /&gt;
== Further Discussion Required ==&lt;br /&gt;
=== SysAdmin Tools ===&lt;br /&gt;
* http://kde.org/areas/sysadmin&lt;br /&gt;
&lt;br /&gt;
*'''Held off for further discussion'''.  May or may not belong, as this site will not be developer.kde.org, but TechBase.KDE.org.&lt;br /&gt;
&lt;br /&gt;
=== Developer Forums ===&lt;br /&gt;
* Forum admins should be subscribed to the MLs&lt;br /&gt;
* Forum is more for application developers than core developers&lt;br /&gt;
* Forum could have a gateway to the MLs, or the Admins and Moderators would act as the communications link when the need arises.&lt;br /&gt;
* Could be a subforum of a greater official KDE forum&lt;br /&gt;
&lt;br /&gt;
**'''May have manpower issues'''.&lt;br /&gt;
&lt;br /&gt;
== Sidelined ==&lt;br /&gt;
=== Business Communications Flow ===&lt;br /&gt;
&lt;br /&gt;
Developing software for the flow of enterprise communications has become an extremely wide are of software development as of late. Nepomuk/Akonadi may be part of this.&lt;br /&gt;
&lt;br /&gt;
* '''Sidelined until Akonadi can be further developed.'''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:CuCullin</id>
		<title>User talk:CuCullin</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:CuCullin"/>
				<updated>2007-01-16T02:49:20Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Discussion bits moved to Projects/TechBase&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Moved to [[Projects/TechBase|TechBase]].  Keeping this up as a reference for a bit...&lt;br /&gt;
&lt;br /&gt;
-----&lt;br /&gt;
&lt;br /&gt;
I've noticed the following things that may have a place on devnew...&lt;br /&gt;
&lt;br /&gt;
# Forums - ISV's have regular public communication on MSDN, while KDE has a single forum KDE-Forum.org, which, iirc, is not KDE eV (or other) owned.  There should be a developer specific forum, with subforums aligned with the wiki.  This will also ease the addition of information to the wiki as specific incidents are encountered during the ongoing development cycle.&lt;br /&gt;
# Architecture&lt;br /&gt;
## Software as a Service&lt;br /&gt;
## Service oriented architecture&lt;br /&gt;
## Service oriented infrastructure&lt;br /&gt;
## Security&lt;br /&gt;
## Rapid development, case studies, etc.&lt;br /&gt;
## KOffice as a software design platform, in terms of collaboration and communication&lt;br /&gt;
# Web development - Its obvious that this is a KDE site, but one thing included in sites such as MSDN is the inclusion of information relative to web development.  With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE could be called a premier web testing environment.  It may be beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, whatever the case may be), setting up such testing environments, etc.&lt;br /&gt;
# Server Tools - specifically any KDE tools that manage, create, extend sql servers, apache, whatever&lt;br /&gt;
# Business communications flow - Developing software for the flow of enterprise communications has become an extremely wide area of software development as of late.  I believe in part this is nepomuk, but I don't have a full understanding of nepomuk to go on.  This may be another point of note.&lt;br /&gt;
# Error reporting functionality. -Right now, for error reporting there is bugs.kde.org.  Is there any interface out there to ease error reporting for users? This may be considered separate from development, but perhaps some sort of reporting software, and configuration information for a bug server that would be bugs.kde.org compatible (to keep changes to a bug reporting app to a minimum) would be something ISV's would hold a specific interest in.&lt;br /&gt;
# KOffice - Kross is included on devnew - are there other ways ISV's can add onto KOffice? This would probably tie in well with #5 Business Communications Flow.  Also, additional projects that maintain the same style as KOffice would be good to note specifically here.&lt;br /&gt;
# Design Patterns?&lt;br /&gt;
# KDevelop&lt;br /&gt;
## Learning the languages&lt;br /&gt;
## Tutorials using KDevelop&lt;br /&gt;
# Portable devices - Zaurus, Palm, etc, working with them and KDE, how to create a KDE app using opensync (im guessing here), links to qtopia and interoperability here, etc?&lt;br /&gt;
# More info - blogs, places to put code, irc channels, newsgroups, events, etc.  Could also house sections designated to education, government, corporate, or even perhaps medical and other specific types.  Courses and certifications, if applicable.&lt;br /&gt;
# Audio &amp;amp; Video casts?&lt;br /&gt;
&lt;br /&gt;
Just some random thoughts... Opinions?&lt;br /&gt;
&lt;br /&gt;
: Especially video casts could be interesting. Blender once had some videos. KDevelop could benefit here, as well as Quanta. Besides, this are quite some ideas we definitely should think about. This discussion could also go to the discussion of [[Projects/Partners]] =) --[[User:Dhaumann|Dhaumann]] 21:30, 15 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: True, I didn't want to clutter the Projects page with too much stuff.  I'll reformat it for easier reading/more coherent thoughts later, and add it then. --[[User:CuCullin|CuCullin]] 21:42, 15 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:1. Forums - I really think that KDE would benefit from an official user forum. But for core development issues, I think that the mailing lists are preferred. You'd never manage to convince everyone to switch to using a forum anyway. A forum.kde.org could only be a benefit as far as I'm concerned. Just as long as we have people willing to devote time to it.&amp;lt;br /&amp;gt;6. Error reporting functionality - The problems with any sort of non-bugzilla interface were brought up when ''LikeBack'' was discussed on the mailing lists. Having more than one place where bugs are stored will cause unnecessary work. But I do agree, a simpler entry point wouldn't go amiss.&amp;lt;br /&amp;gt;7. KOffice - I guess it depends on what the KOffice devs want (since they'd be the best ones to maintain something like that).&amp;lt;br /&amp;gt;8. Design Patterns - These definitely should be located on devnew. Most likely in the Tutorials section.&lt;br /&gt;
&lt;br /&gt;
::6. Error reporting - I was thinking more of an application-type interface such as KBugBuster, but I believe that just scrapes bugs.kde.org.  Something that could interface more directly would probably be a big benefit.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/TechBase</id>
		<title>Projects/TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/TechBase"/>
				<updated>2007-01-16T02:47:40Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Ok, reflowed.  Please keep orphaned for the moment until it has a chance to be reviewed.  In the meantime, review and discuss, or take on tasks as desired.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Tutorials Wanted/Needed ==&lt;br /&gt;
Ordered based on priority.&lt;br /&gt;
&lt;br /&gt;
=== Security ===&lt;br /&gt;
* Techniques and available software&lt;br /&gt;
&lt;br /&gt;
=== Further Information ===&lt;br /&gt;
The &amp;quot;Further Information section replaces &amp;quot;Recommended Books&amp;quot; under the Development section.  It should include:&lt;br /&gt;
&lt;br /&gt;
* Books&lt;br /&gt;
* Blogs&lt;br /&gt;
* Places to put your code&lt;br /&gt;
* irc channels&lt;br /&gt;
* Newsgroups&lt;br /&gt;
* Forums&lt;br /&gt;
* Events&lt;br /&gt;
* Could also house sections designated to vertical markets such as medical, education, government, etc.&lt;br /&gt;
* Applicable courses and certifications&lt;br /&gt;
* Audio and Video casts&lt;br /&gt;
&lt;br /&gt;
=== Web Development ===&lt;br /&gt;
&lt;br /&gt;
With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE is a premier web testing environment.  It is beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, etc), setting up such testing environments, etc.&lt;br /&gt;
&lt;br /&gt;
=== Rapid Application Development ===&lt;br /&gt;
* Ruby/Python/Perl/etc&lt;br /&gt;
* Need to get communities on board and contributing.&lt;br /&gt;
&lt;br /&gt;
=== KDevelop ===&lt;br /&gt;
* Learning the languages&lt;br /&gt;
* Tutorials using KDevelop; such as a tutorial in Getting Started&lt;br /&gt;
* kde edu people have done some tutorials in this area, contact and bring those tutorials here.&lt;br /&gt;
&lt;br /&gt;
=== Networked Services ===&lt;br /&gt;
* Web/Internet services&lt;br /&gt;
* How ISV's can make use of such things as ghns, kdepim/kode...&lt;br /&gt;
&lt;br /&gt;
=== KOffice as a Software Design Platform&lt;br /&gt;
* For collaboration and communication&lt;br /&gt;
* Get KOffice team on the wiki&lt;br /&gt;
&lt;br /&gt;
=== Portable Devices ===&lt;br /&gt;
*Working with them and KDE&lt;br /&gt;
*Creating a KDE app that makes use of OpenSync&lt;br /&gt;
*Links to Qtopia with info on interoperability&lt;br /&gt;
*ie: Konqueror Embedded&lt;br /&gt;
&lt;br /&gt;
=== Error Reporting Functionality ===&lt;br /&gt;
An ISV's ability to use a bug management system in place, by taking the app and setting up their own server as well, so that there is a reporting system in place already.  They could automate bug information like if desired, like grabbing logs, etc. &lt;br /&gt;
&lt;br /&gt;
=== Design Patterns ===&lt;br /&gt;
* KDE specific elements should come first.  Low on the priority list.&lt;br /&gt;
&lt;br /&gt;
== Further Discussion Required ==&lt;br /&gt;
=== SysAdmin Tools ===&lt;br /&gt;
* http://kde.org/areas/sysadmin&lt;br /&gt;
&lt;br /&gt;
*'''Held off for further discussion'''.  May or may not belong, as this site will not be developer.kde.org, but TechBase.KDE.org.&lt;br /&gt;
&lt;br /&gt;
=== Developer Forums ===&lt;br /&gt;
* Forum admins should be subscribed to the MLs&lt;br /&gt;
* Forum is more for application developers than core developers&lt;br /&gt;
* Forum could have a gateway to the MLs, or the Admins and Moderators would act as the communications link when the need arises.&lt;br /&gt;
* Could be a subforum of a greater official KDE forum&lt;br /&gt;
&lt;br /&gt;
**'''May have manpower issues'''.&lt;br /&gt;
&lt;br /&gt;
== Sidelined ==&lt;br /&gt;
=== Business Communications Flow ===&lt;br /&gt;
&lt;br /&gt;
Developing software for the flow of enterprise communications has become an extremely wide are of software development as of late. Nepomuk/Akonadi may be part of this.&lt;br /&gt;
&lt;br /&gt;
* '''Sidelined until Akonadi can be further developed.'''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/TechBase</id>
		<title>Projects/TechBase</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/TechBase"/>
				<updated>2007-01-16T02:31:52Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Being updated - keep orphaned&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
Being edited.... saving changes so its not lost....&lt;br /&gt;
&lt;br /&gt;
Keep orphaned.&lt;br /&gt;
&lt;br /&gt;
== To Do ==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Tutorials Wanted/Needed ===&lt;br /&gt;
=== Security ===&lt;br /&gt;
&lt;br /&gt;
=== Further Information ===&lt;br /&gt;
The &amp;quot;Further Information section replaces &amp;quot;Recommended Books&amp;quot; under the Development section.  It should include:&lt;br /&gt;
&lt;br /&gt;
* Books&lt;br /&gt;
* Blogs&lt;br /&gt;
* Places to put your code&lt;br /&gt;
* irc channels&lt;br /&gt;
* Newsgroups&lt;br /&gt;
* Forums&lt;br /&gt;
* Events&lt;br /&gt;
* Could also house sections designated to vertical markets such as medical, education, government, etc.&lt;br /&gt;
* Applicable courses and certifications&lt;br /&gt;
* Audio and Video casts&lt;br /&gt;
&lt;br /&gt;
=== Web Development ===&lt;br /&gt;
&lt;br /&gt;
With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE is a premier web testing environment.  It is beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, etc), setting up such testing environments, etc.&lt;br /&gt;
&lt;br /&gt;
=== RAPID DEVELOPMENT &amp;amp; CASE STUDIES ===&lt;br /&gt;
&lt;br /&gt;
Ruby/Python/Perl/etc&lt;br /&gt;
 Need to get communities on board and contributing.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
6 KDEVELOP&lt;br /&gt;
&lt;br /&gt;
Learning the languages&lt;br /&gt;
Tutorials using KDevelop&lt;br /&gt;
e.g. a tutorial in Getting Started/ woudl be awsome.. i believe the kde edu people have done some tutorials here as well&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
7 NETWORKED SERVICES&lt;br /&gt;
&lt;br /&gt;
16:53:38)  aseigo:  sure... web services &amp;lt;-&amp;gt; internet services, at some point those things got confused... so that would be things like gethotnewstuff for us&lt;br /&gt;
&lt;br /&gt;
(16:56:11)  aseigo:  yes ... &amp;quot;networked services&amp;quot; ... would include ghns, kdepim/kode ...&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
8 KOFFICE AS A SOFTWARE DESIGN PLATFORM&lt;br /&gt;
&lt;br /&gt;
For collaboration and communication&lt;br /&gt;
Get KOffice team on the wiki&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
9 PORTABLE DEVICES&lt;br /&gt;
&lt;br /&gt;
Working with them and KDE&lt;br /&gt;
Creating a KDE app using OpenSync&lt;br /&gt;
Links to Qtopia with info on interoperability&lt;br /&gt;
Konqueror Embedded&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
10 ERROR REPORTING FUNCTIONALITY&lt;br /&gt;
&lt;br /&gt;
my thought was on an ISV's ability to use a bug management system in place, by taking the app and setting up their own server as well, so that there is a reporting system in place already.  They could automate bug information like MS if desired, like grabbing logs, etc. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
11 DEVELOPER FORUMS&lt;br /&gt;
&lt;br /&gt;
Forum admins should be subscribed to the MLs&lt;br /&gt;
Forum is more for application developers than core developers&lt;br /&gt;
May have manpower issues&lt;br /&gt;
Could be a subforum of a greater official KDE forum&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
12 DESIGN PATTERNS&lt;br /&gt;
&lt;br /&gt;
KDE specific should come first.  Low on the priority list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
13 SIDELINED&lt;br /&gt;
&lt;br /&gt;
 13.1 BUSINESS COMMUNICATIONS FLOW&lt;br /&gt;
&lt;br /&gt;
Developing software for the flow of enterprise communications has become an extremely wide are of software development as of late. nepomuk/Akonadi may be part of this.&lt;br /&gt;
Sidelined until technologies catch up.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
14 FURTHER DISCUSSION REQUIRED&lt;br /&gt;
&lt;br /&gt;
 14.1 SYSADMIN TOOLS&lt;br /&gt;
&lt;br /&gt;
http://kde.org/areas/sysadmin&lt;br /&gt;
held off for further discussion&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-15T21:08:31Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Projects/Oxygen/Sound Scheme Naming Specification moved to Projects/Oxygen/Sound Theme Naming Specification: Should be Theme, really.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
Critical Battery Alarm&lt;br /&gt;
Critical Stop&lt;br /&gt;
Default Beep&lt;br /&gt;
Device Connect&lt;br /&gt;
Device Disconnect&lt;br /&gt;
Device Failed to Connect&lt;br /&gt;
Exclamation&lt;br /&gt;
Exit&lt;br /&gt;
Low Battery Alarm&lt;br /&gt;
Menu Popup&lt;br /&gt;
Open Program&lt;br /&gt;
Print Complete&lt;br /&gt;
Program Error&lt;br /&gt;
Question&lt;br /&gt;
Restore Down&lt;br /&gt;
Restore Up&lt;br /&gt;
Select&lt;br /&gt;
Show Toolbar&lt;br /&gt;
Start&lt;br /&gt;
System Notification&lt;br /&gt;
Logoff&lt;br /&gt;
Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Menu Browse&lt;br /&gt;
* Menu Select&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----File/Web Browser----&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:CuCullin</id>
		<title>User talk:CuCullin</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:CuCullin"/>
				<updated>2007-01-15T21:07:32Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I've noticed the following things that may have a place on devnew...&lt;br /&gt;
&lt;br /&gt;
# Forums - ISV's have regular public communication on MSDN, while KDE has a single forum KDE-Forum.org, which, iirc, is not KDE eV (or other) owned.  There should be a developer specific forum, with subforums aligned with the wiki.  This will also ease the addition of information to the wiki as specific incidents are encountered during the ongoing development cycle.&lt;br /&gt;
# Architecture&lt;br /&gt;
## Software as a Service&lt;br /&gt;
## Service oriented architecture&lt;br /&gt;
## Service oriented infrastructure&lt;br /&gt;
## Security&lt;br /&gt;
## Rapid development, case studies, etc.&lt;br /&gt;
## KOffice as a software design platform, in terms of collaboration and communication&lt;br /&gt;
# Web development - Its obvious that this is a KDE site, but one thing included in sites such as MSDN is the inclusion of information relative to web development.  With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE could be called a premier web testing environment.  It may be beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, whatever the case may be), setting up such testing environments, etc.&lt;br /&gt;
# Server Tools - specifically any KDE tools that manage, create, extend sql servers, apache, whatever&lt;br /&gt;
# Business communications flow - Developing software for the flow of enterprise communications has become an extremely wide area of software development as of late.  I believe in part this is nepomuk, but I don't have a full understanding of nepomuk to go on.  This may be another point of note.&lt;br /&gt;
# Error reporting functionality. -Right now, for error reporting there is bugs.kde.org.  Is there any interface out there to ease error reporting for users? This may be considered separate from development, but perhaps some sort of reporting software, and configuration information for a bug server that would be bugs.kde.org compatible (to keep changes to a bug reporting app to a minimum) would be something ISV's would hold a specific interest in.&lt;br /&gt;
# KOffice - Kross is included on devnew - are there other ways ISV's can add onto KOffice? This would probably tie in well with #5 Business Communications Flow.  Also, additional projects that maintain the same style as KOffice would be good to note specifically here.&lt;br /&gt;
# Design Patterns?&lt;br /&gt;
# KDevelop&lt;br /&gt;
## Learning the languages&lt;br /&gt;
## Tutorials using KDevelop&lt;br /&gt;
# Portable devices - Zaurus, Palm, etc, working with them and KDE, how to create a KDE app using opensync (im guessing here), links to qtopia and interoperability here, etc?&lt;br /&gt;
# More info - blogs, places to put code, irc channels, newsgroups, events, etc.  Could also house sections designated to education, government, corporate, or even perhaps medical and other specific types.  Courses and certifications, if applicable.&lt;br /&gt;
# Audio &amp;amp; Video casts?&lt;br /&gt;
&lt;br /&gt;
Just some random thoughts... Opinions?&lt;br /&gt;
&lt;br /&gt;
: Especially video casts could be interesting. Blender once had some videos. KDevelop could benefit here, as well as Quanta. Besides, this are quite some ideas we definitely should think about. This discussion could also go to the discussion of [[Projects/Partners]] =) --[[User:Dhaumann|Dhaumann]] 21:30, 15 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: True, I didn't want to clutter the Projects page with too much stuff.  I'll reformat it for easier reading/more coherent thoughts later, and add it then. --[[User:CuCullin|CuCullin]] 21:42, 15 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:1. Forums - I really think that KDE would benefit from an official user forum. But for core development issues, I think that the mailing lists are preferred. You'd never manage to convince everyone to switch to using a forum anyway. A forum.kde.org could only be a benefit as far as I'm concerned. Just as long as we have people willing to devote time to it.&amp;lt;br /&amp;gt;6. Error reporting functionality - The problems with any sort of non-bugzilla interface were brought up when ''LikeBack'' was discussed on the mailing lists. Having more than one place where bugs are stored will cause unnecessary work. But I do agree, a simpler entry point wouldn't go amiss.&amp;lt;br /&amp;gt;7. KOffice - I guess it depends on what the KOffice devs want (since they'd be the best ones to maintain something like that).&amp;lt;br /&amp;gt;8. Design Patterns - These definitely should be located on devnew. Most likely in the Tutorials section.&lt;br /&gt;
&lt;br /&gt;
::6. Error reporting - I was thinking more of an application-type interface such as KBugBuster, but I believe that just scrapes bugs.kde.org.  Something that could interface more directly would probably be a big benefit.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:CuCullin</id>
		<title>User talk:CuCullin</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:CuCullin"/>
				<updated>2007-01-15T20:42:06Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I've noticed the following things that may have a place on devnew...&lt;br /&gt;
&lt;br /&gt;
# Forums - ISV's have regular public communication on MSDN, while KDE has a single forum KDE-Forum.org, which, iirc, is not KDE eV (or other) owned.  There should be a developer specific forum, with subforums aligned with the wiki.  This will also ease the addition of information to the wiki as specific incidents are encountered during the ongoing development cycle.&lt;br /&gt;
# Architecture&lt;br /&gt;
## Software as a Service&lt;br /&gt;
## Service oriented architecture&lt;br /&gt;
## Service oriented infrastructure&lt;br /&gt;
## Security&lt;br /&gt;
## Rapid development, case studies, etc.&lt;br /&gt;
## KOffice as a software design platform, in terms of collaboration and communication&lt;br /&gt;
# Web development - Its obvious that this is a KDE site, but one thing included in sites such as MSDN is the inclusion of information relative to web development.  With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE could be called a premier web testing environment.  It may be beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, whatever the case may be), setting up such testing environments, etc.&lt;br /&gt;
# Server Tools - specifically any KDE tools that manage, create, extend sql servers, apache, whatever&lt;br /&gt;
# Business communications flow - Developing software for the flow of enterprise communications has become an extremely wide area of software development as of late.  I believe in part this is nepomuk, but I don't have a full understanding of nepomuk to go on.  This may be another point of note.&lt;br /&gt;
# Error reporting functionality. -Right now, for error reporting there is bugs.kde.org.  Is there any interface out there to ease error reporting for users? This may be considered separate from development, but perhaps some sort of reporting software, and configuration information for a bug server that would be bugs.kde.org compatible (to keep changes to a bug reporting app to a minimum) would be something ISV's would hold a specific interest in.&lt;br /&gt;
# KOffice - Kross is included on devnew - are there other ways ISV's can add onto KOffice? This would probably tie in well with #5 Business Communications Flow.  Also, additional projects that maintain the same style as KOffice would be good to note specifically here.&lt;br /&gt;
# Design Patterns?&lt;br /&gt;
# KDevelop&lt;br /&gt;
## Learning the languages&lt;br /&gt;
## Tutorials using KDevelop&lt;br /&gt;
# Portable devices - Zaurus, Palm, etc, working with them and KDE, how to create a KDE app using opensync (im guessing here), links to qtopia and interoperability here, etc?&lt;br /&gt;
# More info - blogs, places to put code, irc channels, newsgroups, events, etc.  Could also house sections designated to education, government, corporate, or even perhaps medical and other specific types.  Courses and certifications, if applicable.&lt;br /&gt;
# Audio &amp;amp; Video casts?&lt;br /&gt;
&lt;br /&gt;
Just some random thoughts... Opinions?&lt;br /&gt;
&lt;br /&gt;
: Especially video casts could be interesting. Blender once had some videos. KDevelop could benefit here, as well as Quanta. Besides, this are quite some ideas we definitely should think about. This discussion could also go to the discussion of [[Projects/Partners]] =) --[[User:Dhaumann|Dhaumann]] 21:30, 15 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:: True, I didn't want to clutter the Projects page with too much stuff.  I'll reformat it for easier reading/more coherent thoughts later, and add it then. --[[User:CuCullin|CuCullin]] 21:42, 15 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification</id>
		<title>Projects/Oxygen/Sound Theme Naming Specification</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Oxygen/Sound_Theme_Naming_Specification"/>
				<updated>2007-01-15T19:30:00Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;*NOTE - '''This section is under HEAVY development.  Keep it as an orphaned page for the time being.'''&lt;br /&gt;
&lt;br /&gt;
== Overview ==&lt;br /&gt;
&lt;br /&gt;
== Context ==&lt;br /&gt;
&lt;br /&gt;
The contexts for a sound theme are (these are more or less placeholders as this schema is sorted out):&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ Table 1.  Sound Theme Contexts&lt;br /&gt;
! Name !! Description !! Directory&lt;br /&gt;
|-&lt;br /&gt;
| System Events || Sounds which are generally used to notify the user of events relating to the system, ie: startup, warning dialogs, etc || system&lt;br /&gt;
|-&lt;br /&gt;
| User Interface Events || Sounds associated with the desktop environment, such as minimize, shade, or kicker events || ui&lt;br /&gt;
|-&lt;br /&gt;
| Misc. Application Events || Sounds associated with application events, such as a successful cd burn, which don't fit within other categories || application&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== System Events ==&lt;br /&gt;
A list for now&lt;br /&gt;
&lt;br /&gt;
* Network events&lt;br /&gt;
* Startup&lt;br /&gt;
* Shutdown&lt;br /&gt;
* Hibernate&lt;br /&gt;
* Standby&lt;br /&gt;
* Close Program&lt;br /&gt;
Critical Battery Alarm&lt;br /&gt;
Critical Stop&lt;br /&gt;
Default Beep&lt;br /&gt;
Device Connect&lt;br /&gt;
Device Disconnect&lt;br /&gt;
Device Failed to Connect&lt;br /&gt;
Exclamation&lt;br /&gt;
Exit&lt;br /&gt;
Low Battery Alarm&lt;br /&gt;
Menu Popup&lt;br /&gt;
Open Program&lt;br /&gt;
Print Complete&lt;br /&gt;
Program Error&lt;br /&gt;
Question&lt;br /&gt;
Restore Down&lt;br /&gt;
Restore Up&lt;br /&gt;
Select&lt;br /&gt;
Show Toolbar&lt;br /&gt;
Start&lt;br /&gt;
System Notification&lt;br /&gt;
Logoff&lt;br /&gt;
Logon&lt;br /&gt;
&lt;br /&gt;
== User Interface Events ==&lt;br /&gt;
* Minimize&lt;br /&gt;
* Minimize to Tray&lt;br /&gt;
* Maximize&lt;br /&gt;
* Restore&lt;br /&gt;
* Restore from Tray&lt;br /&gt;
* Shade Up&lt;br /&gt;
* Shade Down&lt;br /&gt;
* Menu Browse&lt;br /&gt;
* Menu Select&lt;br /&gt;
&lt;br /&gt;
== Application Level Events ==&lt;br /&gt;
&lt;br /&gt;
=== Communication Events ===&lt;br /&gt;
* New Email&lt;br /&gt;
* New IM&lt;br /&gt;
* Name mentioned in chat room&lt;br /&gt;
* Connected to messaging server&lt;br /&gt;
* Disconnected from messaging server&lt;br /&gt;
* Person Joins&lt;br /&gt;
* Person Leaves&lt;br /&gt;
* Receive Call&lt;br /&gt;
* Receive Request to Join&lt;br /&gt;
* Contact Online&lt;br /&gt;
* New Alert&lt;br /&gt;
* New Message&lt;br /&gt;
* New Mail&lt;br /&gt;
&lt;br /&gt;
=== Miscellaneous and Cross-Category Events ===&lt;br /&gt;
* Successful (cd burn, file transfer, etc. Possibly separate these)&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
* [http://tango.freedesktop.org/Standard_Icon_Naming_Specification Tango Icon Specification]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----File/Web Browser----&lt;br /&gt;
Blocked Pop up&lt;br /&gt;
Empty Trash&lt;br /&gt;
Information Bar&lt;br /&gt;
Move Menu Item&lt;br /&gt;
Main Menu Navigation&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:CuCullin</id>
		<title>User talk:CuCullin</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:CuCullin"/>
				<updated>2007-01-15T16:26:44Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;I've noticed the following things that may have a place on devnew...&lt;br /&gt;
&lt;br /&gt;
# Forums - ISV's have regular public communication on MSDN, while KDE has a single forum KDE-Forum.org, which, iirc, is not KDE eV (or other) owned.  There should be a developer specific forum, with subforums aligned with the wiki.  This will also ease the addition of information to the wiki as specific incidents are encountered during the ongoing development cycle.&lt;br /&gt;
# Architecture&lt;br /&gt;
## Software as a Service&lt;br /&gt;
## Service oriented architecture&lt;br /&gt;
## Service oriented infrastructure&lt;br /&gt;
## Security&lt;br /&gt;
## Rapid development, case studies, etc.&lt;br /&gt;
## KOffice as a software design platform, in terms of collaboration and communication&lt;br /&gt;
# Web development - Its obvious that this is a KDE site, but one thing included in sites such as MSDN is the inclusion of information relative to web development.  With khtml, webkit, firefox, opera, ie6 via wine - and now the ie7 rendering engine via wine - KDE could be called a premier web testing environment.  It may be beneficial to cover such topics on the site, along with tools used to develop sites (Quanta, KImageMapEditor, KLinkStatus, whatever the case may be), setting up such testing environments, etc.&lt;br /&gt;
# Server Tools - specifically any KDE tools that manage, create, extend sql servers, apache, whatever&lt;br /&gt;
# Business communications flow - Developing software for the flow of enterprise communications has become an extremely wide area of software development as of late.  I believe in part this is nepomuk, but I don't have a full understanding of nepomuk to go on.  This may be another point of note.&lt;br /&gt;
# Error reporting functionality. -Right now, for error reporting there is bugs.kde.org.  Is there any interface out there to ease error reporting for users? This may be considered separate from development, but perhaps some sort of reporting software, and configuration information for a bug server that would be bugs.kde.org compatible (to keep changes to a bug reporting app to a minimum) would be something ISV's would hold a specific interest in.&lt;br /&gt;
# KOffice - Kross is included on devnew - are there other ways ISV's can add onto KOffice? This would probably tie in well with #5 Business Communications Flow.  Also, additional projects that maintain the same style as KOffice would be good to note specifically here.&lt;br /&gt;
# Design Patterns?&lt;br /&gt;
# KDevelop&lt;br /&gt;
## Learning the languages&lt;br /&gt;
## Tutorials using KDevelop&lt;br /&gt;
# Portable devices - Zaurus, Palm, etc, working with them and KDE, how to create a KDE app using opensync (im guessing here), links to qtopia and interoperability here, etc?&lt;br /&gt;
# More info - blogs, places to put code, irc channels, newsgroups, events, etc.  Could also house sections designated to education, government, corporate, or even perhaps medical and other specific types.  Courses and certifications, if applicable.&lt;br /&gt;
# Audio &amp;amp; Video casts?&lt;br /&gt;
&lt;br /&gt;
Just some random thoughts... Opinions?&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/ISV/KDE_Community</id>
		<title>ISV/KDE Community</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/ISV/KDE_Community"/>
				<updated>2007-01-14T18:04:14Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Got the page started....&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
&lt;br /&gt;
KDE attracts many people with different backgrounds. As such, the day-by-day growing KDE community includes many '''developers''', '''translators''', '''artists''' as well as '''usability and accessibility experts''' and - of course - '''lots of users'''. For several years now all those people are welcome to meet at the '''annual KDE Conference [http://akademy.kde.org/ aKademy]''' to discuss KDE related topics and shape the ''roadmap'' for future development.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/ISV/Why_use_KDE</id>
		<title>ISV/Why use KDE</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/ISV/Why_use_KDE"/>
				<updated>2007-01-14T18:01:50Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Sub-Projects */  Reworded sub-project text&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page intends to help '''Independent Software Vendors (ISVs)''' getting into KDE related topics. This includes companies developing commercial applications as well as other Open Source Projects.&lt;br /&gt;
&lt;br /&gt;
== The KDE Community ==&lt;br /&gt;
The KDE project attracts many people with different backgrounds. As such, the day-by-day growing KDE community includes many '''developers''', '''translators''', '''artists''' as well as '''usability and accessibility experts''' and - of course - '''lots of users'''. For several years now all those people are welcome to meet at the '''annual KDE Conference [http://akademy.kde.org/ aKademy]''' to discuss KDE related topics and shape the ''roadmap'' for future development.&lt;br /&gt;
&lt;br /&gt;
== KDE e.V. ==&lt;br /&gt;
The non-profit organization [http://ev.kde.org KDE e.V.] helps in creating and distributing KDE by securing cash, hardware, and other donations, then using donations to aid KDE development and promotion. All its members are part of the KDE community which means the KDE e.V. plays an important role in the KDE project. Members of the KDE e.V. form several '''working groups''' like the [http://www.spreadkde.org/handbook/mwg/charter Marketing Working Group (MWG)] and the Human-Computer Interaction (HCI) Working Group to help realize KDE's vision.&lt;br /&gt;
&lt;br /&gt;
== Adoption of KDE ==&lt;br /&gt;
KDE is one of the biggest Open Source projects making the Linux/UNIX desktop's experience much more user friendly. As such, distributions strongly support KDE by actively taking part in its development process and ship KDE as their default desktop environment. Many companies use KDE for production use.&lt;br /&gt;
&lt;br /&gt;
== Development ==&lt;br /&gt;
The KDE development process takes place in steady release cycles. '''[http://developer.kde.org/development-versions/release.html Release schedules]''' and '''feature plans''' help the KDE project coordinating a KDE release by introducing several ''phases'' like ''feature freeze'' and ''message freeze''. This phases make sure that developers concentrate on polishing the release and the translation teams have time enough to translate all the KDE software into many different languages. Further information about KDE development tools can be found on the [[Development|development pages]].&lt;br /&gt;
&lt;br /&gt;
=== Documentation ===&lt;br /&gt;
The KDE project provides excellent documentation about its API and its technologies, such as KParts or KXmlGui. There are many '''Tutorials and HOWTOs''' which help getting into KDE development. An overview can be found at the [[Development|development pages]].&lt;br /&gt;
&lt;br /&gt;
=== Technologies ===&lt;br /&gt;
KDE provides a wide range of '''powerful technologies''' such as [http://khtml.info KHTML and KJS] which are adopted by other companies like Apple (Safari browsers) and Nokia. Additionally there are several '''development frameworks''' like KParts (KDE's component technology), KIO (network/protocol architecture) or KXmlGui (build GUIs based on XML definitions).&lt;br /&gt;
&lt;br /&gt;
KDE uses '''well-known standards''' like DCOP in KDE 3 or [http://hal.freedesktop.org HAL (Hardware Abstraction Layer)] and [http://dbus.freedesktop.org D-Bus] (interprocess communication) in upcoming KDE 4.&lt;br /&gt;
&lt;br /&gt;
=== Compatibility &amp;amp; Integration ===&lt;br /&gt;
The last major KDE release was KDE 3. All KDE 3.x versions are '''binary compatible''', i.e. software written five years ago is compatible to the latest stable release KDE 3.5. As KDE is based on standards it is for instance easy to integrate applications with plain [http://todo-link-to-howto .desktop files].&lt;br /&gt;
&lt;br /&gt;
==== Freedesktop.org &amp;amp; Portland ====&lt;br /&gt;
As an ISV, your target is probably not only KDE but all Linux/UNIX desktops. This is made possible due to '''strong collaboration between KDE and other projects''' like [http://freedesktop.org freedesktop.org] which defines standards and software that helps integrating applications in all standard conform desktop environments.&lt;br /&gt;
&lt;br /&gt;
One of those projects is the [http://developer.kde.org/portland/ Portland project], which intends to develop a common set of Linux Desktop Programming Interfaces and Tools to allow applications to '''easily integrate''' with the free desktop configuration an end user has chosen to work with.&lt;br /&gt;
&lt;br /&gt;
=== Sub-Projects ===&lt;br /&gt;
KDE has many sub-projects to more specifically coordinate unique project goals of major supporting applications.  Several of these significant projects are noted below:&lt;br /&gt;
&lt;br /&gt;
; KDE Pim&lt;br /&gt;
: The goal of [http://pim.kde.org KDE Pim] (Personal information management) is to provide an application suite to manage personal information. This includes applications like an email client, a calender etc. The main result is '''KDE Kontact''', our personal information manager.&lt;br /&gt;
&lt;br /&gt;
; KOffice&lt;br /&gt;
: [http://koffice.kde.org KOffice] is an '''integrated office suite''' using KDE-technology and features a full set of applications which work together seamlessly to provide the best user experience possible. The office suite contains applications like KWord, KSpread, KPresenter, Krita and many more.&lt;br /&gt;
&lt;br /&gt;
; KDevelop&lt;br /&gt;
: [http://kdevelop.kde.org KDevelop] is an '''Integrated Development Environment''' (IDE) for KDE. It supports language like C/C++ and Java and helps with rapid application development.&lt;br /&gt;
&lt;br /&gt;
=== Licensing ===&lt;br /&gt;
An often arising question is: ''Can I use KDE to develop commercial applications?'' - '''Yes, you can develop commercial applications for KDE'''. KDE's foundation libraries {{path|kdelibs}} and {{path|kdepimlibs}} but also KOffice libraries and several of its major apps are licensed under the LGPL, which means you can link closed source applications against those libraries. A valid Qt developer license is required for closed source development, however.&lt;br /&gt;
&lt;br /&gt;
== Roadmap ==&lt;br /&gt;
KDE development follows a release schedule in order to coordinate releases. These usually cover for minor releases the last 10 weeks and for major releases the last 20 weeks before the official release. The features planned for a release are usually published at the same time as the schedule.&lt;br /&gt;
&lt;br /&gt;
Further details can be found in the [[../Roadmap|roadmap page]].&lt;br /&gt;
&lt;br /&gt;
[[Category:ISV]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/ISV/Licensing</id>
		<title>ISV/Licensing</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/ISV/Licensing"/>
				<updated>2007-01-14T17:59:14Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Licensing */  - rewording.....&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Licensing ===&lt;br /&gt;
An often arising question is: ''Can I use KDE to develop commercial applications?'' - '''Yes, you can develop commercial applications for KDE'''. KDE's foundation libraries {{path|kdelibs}} and {{path|kdepimlibs}}, as well as KOffice libraries and other major supporting applications, are licensed under the [http://www.gnu.org/copyleft/lesser.html LGPL].  The [http://www.gnu.org/copyleft/lesser.html LGPL] allows the linking of closed source applications against those libraries.  Though, a [http://www.trolltech.com/products/qt/licenses Qt developer license] is required for closed source development.&lt;br /&gt;
&lt;br /&gt;
[[Category:ISV]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/ISV/Roadmap</id>
		<title>ISV/Roadmap</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/ISV/Roadmap"/>
				<updated>2007-01-14T17:53:42Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Sub-projects */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page intends to help '''Independent Software Vendors''' (ISVs) understanding the background of the KDE Roadmap.&lt;br /&gt;
&lt;br /&gt;
== KDE stable releases ==&lt;br /&gt;
&lt;br /&gt;
The current KDE release is KDE version 3.5.5. Based on the knowledge and experiences of the first KDE 3.x releases the KDE 3.5 series is a well matured and stable platform to rely on.&lt;br /&gt;
&lt;br /&gt;
The development of the KDE 3.5.x series will continue to improve this platform without breaking any compatibility, ensuring that every developer can rely on it. Different from previous KDE release, however, the KDE 3.5.x series will include selected new features to include new technologies and provide new possibilities while the long KDE 4 development cycle takes place.&lt;br /&gt;
&lt;br /&gt;
The Roadmap of KDE 3.5.x is divided into the [[Schedules/KDE_3.5_Release_Schedule|Release Schedule]] and the [http://developer.kde.org/development-versions/kde-3.5-features.html Feature Plan].&lt;br /&gt;
&lt;br /&gt;
== KDE development ==&lt;br /&gt;
&lt;br /&gt;
The current KDE development concentrates on KDE 4, which will be a major release. It will include several new features as well as new APIs and frameworks and therefore will break the API compatibility. However, at the same time there are several efforts in the community making porting apps to KDE 4 quite easy.&lt;br /&gt;
&lt;br /&gt;
The Roadmap of KDE 4 is divided into the [[Schedules/KDE_4.0_Release_Schedule| Release Schedule]] and the [http://developer.kde.org/development-versions/kde-4.0-features.html Feature Plan].&lt;br /&gt;
&lt;br /&gt;
== Sub-projects ==&lt;br /&gt;
&lt;br /&gt;
Some KDE sub-projects have their own roadmaps:&lt;br /&gt;
* [http://multimedia.kde.org/roadmap.php KDE Multimedia project] - supported by [http://phonon.kde.org/ Phonon], a new multimedia API.&lt;br /&gt;
* [http://koffice.kde.org/developer/ KOffice] - a free, integrated office suite for KDE&lt;br /&gt;
&lt;br /&gt;
[[Category:ISV]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3</id>
		<title>Development/Architecture/KDE3</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3"/>
				<updated>2007-01-12T21:40:26Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Development HOWTOs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
&lt;br /&gt;
==Development Framework==&lt;br /&gt;
#[[/Library Structure|Library Structure]]&lt;br /&gt;
#Accessing System Resources&lt;br /&gt;
##[[/Standard Resources|Standard Resources]]&lt;br /&gt;
##[[/Icon Loader|Icon Loading]]&lt;br /&gt;
##[[/System Configuration Cache|System Configuration Cache (KSycoca)]]&lt;br /&gt;
#Graphics&lt;br /&gt;
##[[/Low-level Graphics|Low-level graphics with QPainter]]&lt;br /&gt;
##[[/Structured Graphics|Structured graphics with QCanvas]]&lt;br /&gt;
##[[/OpenGL Support|3D graphics with OpenGL]]&lt;br /&gt;
#User Interface&lt;br /&gt;
##[[/Action Pattern|Action Pattern]]&lt;br /&gt;
##[[/XMLGUI Technology|Defining menus and toolbars in XML]]&lt;br /&gt;
##[[/Providing Online Help|Providing online help]]&lt;br /&gt;
#Complex Widgets&lt;br /&gt;
##[[/KHTML|HTML renderer]] with JavaScript&lt;br /&gt;
##[[/KFile Library|File dialog]]&lt;br /&gt;
##[[/Data Views|Displaying large amounts of data - Using QListView, QListBox and QIconView]]&lt;br /&gt;
#Components and Services&lt;br /&gt;
##[[/Services|KDE services]]&lt;br /&gt;
##[[/MIME Types|MIME types]]&lt;br /&gt;
##[[/Network Transparency|Network transparency]]&lt;br /&gt;
#Inter Client Communication&lt;br /&gt;
##[[/DCOP|Desktop Communication Protocol (DCOP)]]&lt;br /&gt;
#[[/Starting Other Programs|Starting Other Programs]]&lt;br /&gt;
#[[/i18n and l10n|il8n and l10n]]&lt;br /&gt;
&lt;br /&gt;
==Desktop Framework==&lt;br /&gt;
#[[/Panel Applets|Panel Applets]]&lt;br /&gt;
#[[/Control Center Modules|Control Center Modules]]&lt;br /&gt;
&lt;br /&gt;
==Multimedia Framework==&lt;br /&gt;
#[http://space.twc.de/~stefan/kde/arts-mcop-doc/ aRts] - the current state&lt;br /&gt;
#[[/Imaging and Animation|Imaging and Animation]]&lt;br /&gt;
&lt;br /&gt;
==Component Architecture==&lt;br /&gt;
#[[/KParts|KParts]]&lt;br /&gt;
#[[/Docking Into the Panel's System Tray|Docking Into the Panel's System Tray]]&lt;br /&gt;
#[[/Java Integration|Java Integration]]&lt;br /&gt;
&lt;br /&gt;
==KOffice Architecture==&lt;br /&gt;
#[[/Document and View Introduction|Document and View Introduction]]&lt;br /&gt;
#[http://www.koffice.org/filters/ File Format Filters]&lt;br /&gt;
&lt;br /&gt;
==Protocols==&lt;br /&gt;
#[http://www.freedesktop.org/wiki/Standards_2fwm_2dspec Window Management]&lt;br /&gt;
#[[/Session Management|Session Management]]&lt;br /&gt;
#[[/System Tray Docking|System Tray Docking]]&lt;br /&gt;
#[[/Drag-And-Drop|Drag-And-Drop]]&lt;br /&gt;
#[[/Printing|Printing]]&lt;br /&gt;
&lt;br /&gt;
==Development Tools==&lt;br /&gt;
#[[/Interface Documentation Tool|Interface Documentation Tool (Doxygen)]]&lt;br /&gt;
#[[/Integrated Development Environment|Integrated Development Environment (KDevelop)]]&lt;br /&gt;
#[[/Graphical Debugger|Graphical Debugger (kdbg)]]&lt;br /&gt;
#[[/VCS Frontend|VCS Frontend (Subversion)]]&lt;br /&gt;
#[[/Advanced Developer Text Editor|Advanced Developer Text Editor (Kate)]]&lt;br /&gt;
#[[/Icon Editor|Icon Editor (KIconEdit)]]&lt;br /&gt;
#[[/Hex Editor|Hex Editor]]&lt;br /&gt;
&lt;br /&gt;
==Development HOWTOs==&lt;br /&gt;
#[[Development/Architecture/Binary_Compatibility_Issues_With_C%2B%2B|Binary Compatibility Issues With C++]]&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3</id>
		<title>Development/Architecture/KDE3</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3"/>
				<updated>2007-01-12T21:39:28Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Development HOWTOs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
&lt;br /&gt;
==Development Framework==&lt;br /&gt;
#[[/Library Structure|Library Structure]]&lt;br /&gt;
#Accessing System Resources&lt;br /&gt;
##[[/Standard Resources|Standard Resources]]&lt;br /&gt;
##[[/Icon Loader|Icon Loading]]&lt;br /&gt;
##[[/System Configuration Cache|System Configuration Cache (KSycoca)]]&lt;br /&gt;
#Graphics&lt;br /&gt;
##[[/Low-level Graphics|Low-level graphics with QPainter]]&lt;br /&gt;
##[[/Structured Graphics|Structured graphics with QCanvas]]&lt;br /&gt;
##[[/OpenGL Support|3D graphics with OpenGL]]&lt;br /&gt;
#User Interface&lt;br /&gt;
##[[/Action Pattern|Action Pattern]]&lt;br /&gt;
##[[/XMLGUI Technology|Defining menus and toolbars in XML]]&lt;br /&gt;
##[[/Providing Online Help|Providing online help]]&lt;br /&gt;
#Complex Widgets&lt;br /&gt;
##[[/KHTML|HTML renderer]] with JavaScript&lt;br /&gt;
##[[/KFile Library|File dialog]]&lt;br /&gt;
##[[/Data Views|Displaying large amounts of data - Using QListView, QListBox and QIconView]]&lt;br /&gt;
#Components and Services&lt;br /&gt;
##[[/Services|KDE services]]&lt;br /&gt;
##[[/MIME Types|MIME types]]&lt;br /&gt;
##[[/Network Transparency|Network transparency]]&lt;br /&gt;
#Inter Client Communication&lt;br /&gt;
##[[/DCOP|Desktop Communication Protocol (DCOP)]]&lt;br /&gt;
#[[/Starting Other Programs|Starting Other Programs]]&lt;br /&gt;
#[[/i18n and l10n|il8n and l10n]]&lt;br /&gt;
&lt;br /&gt;
==Desktop Framework==&lt;br /&gt;
#[[/Panel Applets|Panel Applets]]&lt;br /&gt;
#[[/Control Center Modules|Control Center Modules]]&lt;br /&gt;
&lt;br /&gt;
==Multimedia Framework==&lt;br /&gt;
#[http://space.twc.de/~stefan/kde/arts-mcop-doc/ aRts] - the current state&lt;br /&gt;
#[[/Imaging and Animation|Imaging and Animation]]&lt;br /&gt;
&lt;br /&gt;
==Component Architecture==&lt;br /&gt;
#[[/KParts|KParts]]&lt;br /&gt;
#[[/Docking Into the Panel's System Tray|Docking Into the Panel's System Tray]]&lt;br /&gt;
#[[/Java Integration|Java Integration]]&lt;br /&gt;
&lt;br /&gt;
==KOffice Architecture==&lt;br /&gt;
#[[/Document and View Introduction|Document and View Introduction]]&lt;br /&gt;
#[http://www.koffice.org/filters/ File Format Filters]&lt;br /&gt;
&lt;br /&gt;
==Protocols==&lt;br /&gt;
#[http://www.freedesktop.org/wiki/Standards_2fwm_2dspec Window Management]&lt;br /&gt;
#[[/Session Management|Session Management]]&lt;br /&gt;
#[[/System Tray Docking|System Tray Docking]]&lt;br /&gt;
#[[/Drag-And-Drop|Drag-And-Drop]]&lt;br /&gt;
#[[/Printing|Printing]]&lt;br /&gt;
&lt;br /&gt;
==Development Tools==&lt;br /&gt;
#[[/Interface Documentation Tool|Interface Documentation Tool (Doxygen)]]&lt;br /&gt;
#[[/Integrated Development Environment|Integrated Development Environment (KDevelop)]]&lt;br /&gt;
#[[/Graphical Debugger|Graphical Debugger (kdbg)]]&lt;br /&gt;
#[[/VCS Frontend|VCS Frontend (Subversion)]]&lt;br /&gt;
#[[/Advanced Developer Text Editor|Advanced Developer Text Editor (Kate)]]&lt;br /&gt;
#[[/Icon Editor|Icon Editor (KIconEdit)]]&lt;br /&gt;
#[[/Hex Editor|Hex Editor]]&lt;br /&gt;
&lt;br /&gt;
==Development HOWTOs==&lt;br /&gt;
#[[/Development/Architecture/Binary_Compatibility_Issues_With_C%2B%2B|Binary Compatibility Issues With C++]]&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/Java_Integration</id>
		<title>Development/Architecture/KDE3/Java Integration</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/Java_Integration"/>
				<updated>2007-01-12T21:20:25Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
&lt;br /&gt;
KDE makes it easy for application developers to add support for Java applets to their applications. The ''kdejava'' library provides a high level API that allows Java applets to be manipulated as if they were a normal QWidget. Lars and I added support for applets to khtml in a matter of hours at the KDE II conference - it really is that easy. KDE's Java support is in two parts, there is a pure Java server which provides the environment in which applets run etc. and a KDE library which handles the embedding of the applet window into the application. The Java and C++ code communicates via standard UNIX pipes using a simple text based protocol. It should be possible to use '''any''' Java VM with KJAS, including Java 2.&lt;br /&gt;
&lt;br /&gt;
==Simple Usage Example==&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;&lt;br /&gt;
 #include &amp;lt;kapp.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;kjavaappletwidget.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;qstring.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 int main(int argc, char **argv)&lt;br /&gt;
 {&lt;br /&gt;
   KApplication app( argc, argv );&lt;br /&gt;
 &lt;br /&gt;
   QString a,b,c,d,e,f;&lt;br /&gt;
 &lt;br /&gt;
   // The name of the applet&lt;br /&gt;
   a = &amp;quot;fred&amp;quot;;&lt;br /&gt;
   // The name of the class to be run&lt;br /&gt;
   b = &amp;quot;Lake.class&amp;quot;;&lt;br /&gt;
   // The base url it can be found at. Note the trailing '/', we could&lt;br /&gt;
   // also have written it as &amp;quot;file:/dos/pcplus/java/lake/Lake.html&amp;quot;&lt;br /&gt;
   c = &amp;quot;file:/dos/pcplus/java/lake/&amp;quot;;&lt;br /&gt;
 &lt;br /&gt;
   // Create the applet widget. We are using the default context and&lt;br /&gt;
   // server implicitly. We could have specified different ones. We&lt;br /&gt;
   // could also specify a parent QWidget, but we might as well make&lt;br /&gt;
   // the applet widget top level for this example.&lt;br /&gt;
   KJavaAppletWidget *applet = new KJavaAppletWidget();&lt;br /&gt;
   CHECK_PTR( applet );&lt;br /&gt;
 &lt;br /&gt;
   // You must set these BEFORE calling show()&lt;br /&gt;
   applet-&amp;gt;setAppletName( a );&lt;br /&gt;
   applet-&amp;gt;setAppletClass( b );&lt;br /&gt;
   applet-&amp;gt;setBaseURL( c );&lt;br /&gt;
 &lt;br /&gt;
   // My test applet needs an image to be specified as a parameter.&lt;br /&gt;
   d = &amp;quot;image&amp;quot;;&lt;br /&gt;
   e = &amp;quot;arch.jpg&amp;quot;;&lt;br /&gt;
   applet-&amp;gt;setParameter( d, e );&lt;br /&gt;
 &lt;br /&gt;
   // We show the widget as normal&lt;br /&gt;
   applet-&amp;gt;show();&lt;br /&gt;
 &lt;br /&gt;
   // Then start the event loop&lt;br /&gt;
   app.exec();&lt;br /&gt;
 }&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
&lt;br /&gt;
The diagram below shows the relationships between some of the more important classes involved in the KDE Java support. Those classes in libkdejava are C++ classes, all of the rest of the system is written in Java. There is no dependency other than the JVM for the KJAS server, this is the core of the KDE Java environment and could also be used to add Java support to other systems - you can control applets from a shell script using a KJAS server for example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;[[Image:kdejava.gif|KDE Java Architecture]]&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Unlike the Java support in Netscape or MS IE, KDE's support uses an out of process JVM - i.e. the JVM itself is not linked to the application that embeds the applet. The table below should explain some of the reasons behind this decision: &amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;90%&amp;quot; bgcolor=&amp;quot;#CCFFFF&amp;quot;&lt;br /&gt;
! bgcolor=&amp;quot;#66FFFF&amp;quot; align=&amp;quot;CENTER&amp;quot; | In process&lt;br /&gt;
! bgcolor=&amp;quot;#66FFFF&amp;quot; align=&amp;quot;CENTER&amp;quot; | Out of process&lt;br /&gt;
|-&lt;br /&gt;
| Have to contend with threading issues&lt;br /&gt;
| No threading problems&lt;br /&gt;
|-&lt;br /&gt;
| JVM crash will kill Konqueror&lt;br /&gt;
| JVM crash easy to handle&lt;br /&gt;
|-&lt;br /&gt;
| JVM load may block the application UI&lt;br /&gt;
| No problem&lt;br /&gt;
|-&lt;br /&gt;
| JVM cannot be unloaded&lt;br /&gt;
| JVM unload by killing child process&lt;br /&gt;
|-&lt;br /&gt;
| Fairly easy to communicate with the JVM (JNI)&lt;br /&gt;
| Need custom communication mechanism&lt;br /&gt;
|-&lt;br /&gt;
| Multiple VMs impossible&lt;br /&gt;
| Multiple VMs possible&lt;br /&gt;
|-&lt;br /&gt;
| Depends on a working Qt AWT port&lt;br /&gt;
| Can use the standard AWT&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/center&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An important advantage of the out of process approach is that it allows us to make use of the standard Motif implementation of the AWT, if we were using an in-process implementation this would require us to merge the Motif and Qt event loops which would be tricky to implement without the AWT peer class sources. Ultimately the plan is to remove the Motif dependency (and the associated memory hit) completely, but until the Qt port of the AWT is finished, this is impossible. The existing solution using swallowing is not perfect, but works reasonably well, when the QtAWT is finished it will be possible to use the QXEmbed API to provide a more polished embedding mechanism. It will also be possible to provide the option an in process JVM which may prove useful in some situations.&lt;br /&gt;
&lt;br /&gt;
==Class overview==&lt;br /&gt;
&lt;br /&gt;
This section outlines the major classes in ''libkdejava'', more detailed information is provided by the kdoc documentation.&lt;br /&gt;
&lt;br /&gt;
* '''KJavaAppletWidget'''&amp;lt;br /&amp;gt;This is the class responsible for the integration of the applet window into the KDE applications GUI. In simple cases, this is the only class you need to worry about and it provides a very straightforward API.&lt;br /&gt;
* '''KJavaApplet'''&amp;lt;br /&amp;gt;This is the class responsible for managing an applet. It ensures the applet is downloaded and provides the ability to start and stop the applet etc.&lt;br /&gt;
* '''KJavaAppletContext'''&amp;lt;br /&amp;gt;This is the environment in which applets exist. Applets in the same context can communicate with each other, those in different contexts cannot. In a web browser all the applets in a single frame will exist in the same context. The context can also be used by applets to communicate with the application they are embedded in, though this communication is currently very limited.&lt;br /&gt;
* '''KJavaAppletServer'''&amp;lt;br /&amp;gt;This is the class that provides access to the KJAS server. Normally, you can ignore this class as you will be automatically assigned a default server.&lt;br /&gt;
* '''KJavaProcess'''&amp;lt;br /&amp;gt;This is a wrapper for KProcess that provides a higher level API for invoking a JVM.&lt;br /&gt;
&lt;br /&gt;
There are a number of other classes in the library, but at the moment they should be regarded as ''internal'' parts of the implementation.&lt;br /&gt;
&lt;br /&gt;
===The road ahead===&lt;br /&gt;
&lt;br /&gt;
The current implementation of KDE-Java is not the end of the story, there are a number of other developments in the works. This section is simply intended to inform you of what to expect, if you want more detailed information then check out the ''kdejava'' CVS module where the code is kept.&lt;br /&gt;
&lt;br /&gt;
As I mentioned earlier I am working on QtAWT, a port of the AWT to the Qt toolkit. This is important for the future development of KDE Java, and has made significant progress. It is possible to create most of the predefined widgets, and to set properties such as the text of push buttons. There is currently no event dispatching, and no support for important classes such as the Canvas however, so the port cannot be considered even half complete. The port is now working with Qt 2.0, though the handling of Unicode strings is not optimal.&lt;br /&gt;
&lt;br /&gt;
In addition to support for standard Applets as used on the web, I also plan to support some extra facilities to allow applications to provide custom applet types/plugins. This facility is not currently very high priority, so it is unlikely to be ready for KDE 2.0, perhaps you'll see it in version 2.1.&lt;br /&gt;
&lt;br /&gt;
==Help required==&lt;br /&gt;
&lt;br /&gt;
There are a number of other projects that I would love to see someone working on, but which I don't have the time to do myself. If you know Java and are looking for a project then why not give one of these a try?&lt;br /&gt;
&lt;br /&gt;
* A Swing look and feel that integrates with KDE widget themes&lt;br /&gt;
* A JNI binding to the KDE libraries&lt;br /&gt;
* Java protocol handlers that provide access to the KIO library. This will allow Java to support SSL, tar files etc.&lt;br /&gt;
&lt;br /&gt;
In addition to the above, help with either the QtAWT , KJAS or libkdejava is always welcome.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/Docking_Into_the_Panel%27s_System_Tray</id>
		<title>Development/Architecture/KDE3/Docking Into the Panel's System Tray</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/Docking_Into_the_Panel%27s_System_Tray"/>
				<updated>2007-01-12T21:17:09Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
A tray window is a small window (typically 24x24 pixel) that docks into the system tray in the desktop panel. It usually displays an icon or an animated icon there. The icon serves as representative for the application, similar to a taskbar button, but consumes less screen space.&lt;br /&gt;
&lt;br /&gt;
[[Image:docking.png|System tray screenshot]]&lt;br /&gt;
&lt;br /&gt;
A CD Player and a Notes application inside the panel's system tray.&lt;br /&gt;
&lt;br /&gt;
When the user clicks with the left mouse button on the icon, the main application window is shown/raised and activated. With the right mouse button, she gets a popupmenu with application specific commands, including &amp;quot;Minimize/Restore&amp;quot; and &amp;quot;Quit&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Having an icon on the system tray is a useful technique for daemon-like applications that may run for some time without user interaction but have to be there immediately when the user needs them. Examples are kppp, kisdn, kscd, kmix or knotes. With kppp and kisdn, the docked icon even provides real-time information about the network status.&lt;br /&gt;
&lt;br /&gt;
With the KSystemTray in libkdeui, KDE provides a very simple API to add system tray items from your application. See the KSystemTray documentation in the [http://developer.kde.org/documentation/library/3.1-api/classref/kdeui/KSystemTray.html KDE 3.1 API Reference ] for further details.&lt;br /&gt;
&lt;br /&gt;
The mechanism works for non-KDE applications just as well. See the description of the [http://developer.kde.org/documentation/library/kdeqt/kde3arch/protocols-docking.html system tray docking protocol] for details.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/KParts</id>
		<title>Development/Architecture/KDE3/KParts</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/KParts"/>
				<updated>2007-01-12T21:15:27Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
The main idea behind components is reusability. Often, an application wants to use a functionality that another application provides. Of course, the way to do that is simply to create a shared library that both applications use. But without a standard framework for this, it means both applications are very much coupled to the library's API and will need to be changed if the applications decide to use another library instead. Furthermore, integrating the shared functionality has to be done manually by every application.&lt;br /&gt;
&lt;br /&gt;
A framework for components enables an application to use a component it never heard of - and wasn't specifically adapted for - because both the application and the component comply to the framework and know what to expect from each other. An existing component can be replaced with a new implementation of the same functionality, without changing a single line of code in the application, because the interface remains the same.&lt;br /&gt;
&lt;br /&gt;
The framework presented here concerns elaborate graphical components, such as an image viewer, a text editor, a mail composer, and so on. Simpler graphical components are usually widgets; I refine this distinction in the next section. Nongraphical components, such as a parser or a string manipulation class, are usually libraries with a specific Application Programming Interface (API).&lt;br /&gt;
&lt;br /&gt;
Similar frameworks for graphical components exist for a different environment, such as IBM and Apple's OpenDoc, Microsoft's OLE, Gnome's Bonobo, and KDE's previous OpenParts.&lt;br /&gt;
&lt;br /&gt;
==The Difference Between Components and Widgets==&lt;br /&gt;
&lt;br /&gt;
A KDE component is called a ''part'', and it encapsulates three things: a widget, the functionality that comes with it, and the user interface for this functionality.&lt;br /&gt;
&lt;br /&gt;
The usual example is a text editor component. Its widget is a multiline text widget; its functionality might include Search And Replace, Copy, Cut, Paste, Undo, Redo, Spell Checking. To make it possible for the user to access this functionality, the component also provides the user interface for it: menu items and toolbar buttons.&lt;br /&gt;
&lt;br /&gt;
An application using this component will get the widget embedded into a parent widget it provides, as well as the component's user interface merged into its own menubar and toolbars. This is like embedding a MS Excel document into MS Word, an example everybody knows, or when embedding a KSpread document into KWord, an example that will hopefully become very well known as well.&lt;br /&gt;
&lt;br /&gt;
Another example of very useful component is an image viewer. When using KDE's file manager (Konqueror), clicking an image file opens the image viewer component from KDE's image viewer (KView) and shows it inside Konqueror's window. The part provides actions for zoom in, zoom out, rotate, reset to original size, and orientation.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;90%&amp;quot; cellpadding=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| bgcolor=&amp;quot;#DDDDDD&amp;quot; |&lt;br /&gt;
'''Note -''' Note that KOffice parts are a bit different because they don't embed as a full window, but as a frame into the parent's view, which can be moved, resized, and even rotated - a functionality only KOffice has. This and the document/view architecture of KOffice applications mean that the framework for KOffice parts, although based on KParts, is much more elaborate and out of topic here.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
So, when do you use a part and when do you use a widget?&lt;br /&gt;
&lt;br /&gt;
Use a widget when all the functionality is in the widget itself and doesn't need additional user interface (menu items or toolbar buttons). A button is a widget, a multiline edit is a widget, but a text editor with all the functionality previously mentioned is a part. As you can see there is no problem choosing which one to use.&lt;br /&gt;
&lt;br /&gt;
==The KDE Component Framework==&lt;br /&gt;
&lt;br /&gt;
KParts is the framework for KDE parts, based on standard KDE/Qt objects, such as QWidget and KTMainWindow. It defines a very simple set of classes: part, plugin, mainwindow, and part manager.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
A ''part'', as previously described, is the name for a KDE component. To define a new part, you need to provide the widget, of course, but also the actions that give access to the part's functionality and an XML file that describes the layout of those actions in the user interface.&lt;br /&gt;
&lt;br /&gt;
A ''plugin''is a small piece of functionality that is not implemented by an embedded widget, but that defines some actions to be merged in the application's user interface, such as the calculator plugin for KSpread. It can be graphical, however, like a dialog box or a separate window popping up, or it can be an application-specific plugin and act on the application itself - a spell checker for a word processor, for example.&lt;br /&gt;
&lt;br /&gt;
A KParts ''mainwindow''is a special KTMainWindow whose user interface is described in XML and with actions so that it is able to embed parts. The reason it has to use XML is because merging user interfaces is implemented by merging XML documents.&lt;br /&gt;
&lt;br /&gt;
A ''part manager''is a more abstract object whose task is to handle the activation and the deactivation of the parts. Of course, this is useful only for mainwindows that embed more than one part, such as KOffice documents (where the main document is also a part), or Konqueror (where each view is a part). KWrite, which embeds only its own part, doesn't need a part manager.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/blockquote&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the following sections, you create a part for a simple text editor, a main window able to embed an existing PostScript-viewer part, a part manager to embed more than one part, and even a plug-in; thus, you will know everything about KParts.&lt;br /&gt;
&lt;br /&gt;
==Describing User Interface in XML==&lt;br /&gt;
&lt;br /&gt;
The XML file used by a part or a mainwindow provides only the layout of the actions in the user interface. The actions themselves are still implemented in the code, with slots, as usual.&lt;br /&gt;
&lt;br /&gt;
More precisely, the XML file describes the layout of the menus and submenus in the menubar (only one menubar is always present) and the menu items within those menus, as well as the toolbars and the toolbar buttons. The menubar, menus, and toolbars are containers; menu items and toolbar buttons are the actions.&lt;br /&gt;
&lt;br /&gt;
A sample XML file for a mainwindow looks like the one shown in Listing 13.1.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.1 Excerpt of konqueror.rc: A User Interface Described in XML''====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE kpartgui SYSTEM &amp;quot;kpartgui.dtd&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;kpartgui name=&amp;quot;Konqueror&amp;quot; version=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;MenuBar&amp;gt;&lt;br /&gt;
    &amp;lt;Menu name=&amp;quot;file&amp;quot;&amp;gt;&amp;lt;Text&amp;gt;&amp;amp;amp;File&amp;lt;/Text&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;find&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;Separator/&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;print&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;Separator/&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;close&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;/Menu&amp;gt;&lt;br /&gt;
    &amp;lt;Menu name=&amp;quot;edit&amp;quot;&amp;gt;&amp;lt;Text&amp;gt;&amp;amp;amp;Edit&amp;lt;/Text&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;cut&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;copy&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;paste&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;trash&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;Action name=&amp;quot;del&amp;quot;/&amp;gt;&lt;br /&gt;
     &amp;lt;Separator/&amp;gt;&lt;br /&gt;
     &amp;lt;Merge/&amp;gt;&lt;br /&gt;
     &amp;lt;Separator/&amp;gt;&lt;br /&gt;
    &amp;lt;/Menu&amp;gt;&lt;br /&gt;
    &amp;lt;Merge/&amp;gt;&lt;br /&gt;
   &amp;lt;/MenuBar&amp;gt;&lt;br /&gt;
   &amp;lt;ToolBar fullWidth=&amp;quot;true&amp;quot; name=&amp;quot;mainToolBar&amp;quot;&amp;gt;&amp;lt;Text&amp;gt;Main&amp;lt;/Text&amp;gt;&lt;br /&gt;
    &amp;lt;Action name=&amp;quot;cut&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;Action name=&amp;quot;copy&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;Action name=&amp;quot;paste&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;Action name=&amp;quot;print&amp;quot;/&amp;gt;&lt;br /&gt;
    &amp;lt;Separator/&amp;gt;&lt;br /&gt;
    &amp;lt;Merge/&amp;gt;&lt;br /&gt;
    &amp;lt;Separator/&amp;gt;&lt;br /&gt;
    &amp;lt;Action name=&amp;quot;animated_logo&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;/ToolBar&amp;gt;&lt;br /&gt;
   &amp;lt;ToolBar name=&amp;quot;locationToolBar&amp;quot;&amp;gt;&amp;lt;Text&amp;gt;Location&amp;lt;/Text&amp;gt;&lt;br /&gt;
    &amp;lt;Action name=&amp;quot;toolbar_url_combo&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;/ToolBar&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/kpartgui&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The DOCTYPE tag contains the name of the main element, which should be set to kpartgui. The top-level elements are MenuBar and ToolBar, as expected. In the MenuBar, the menus are described. Note that they have a name, used for merging later on, and a text, which is displayed in the user interface, possibly translated. Because this is XML, &amp;amp; has to be encoded as &amp;amp;amp;. Inside a Menu tag, the actions, some separators, and possibly submenus are laid out. The action names are very important because they are used to match the actions created in the code.&lt;br /&gt;
&lt;br /&gt;
The toolbars are then described. Note that the main toolbar has to be called mainToolBar because its settings can be different. KToolBar takes care of adding text under icons for this particular toolbar, if the user wants them. Actions are laid out in the toolbars the usual way. The text for a toolbar is used where the name of the toolbar is to be displayed to the user, possibly translated, such as the toolbar editor.&lt;br /&gt;
&lt;br /&gt;
Another important tag is the Merge tag. This tag tells the framework where the actions of the active part - and the plug-ins - should be merged in a given container. As you can see, this XML file inserts the part's actions before a separator in the Edit menu, whereas it doesn't specify a position for items in the File menu. This means that if the part defines actions for the File menu, they will be appended to the File menu of the mainwindow.&lt;br /&gt;
&lt;br /&gt;
The merging happens when a part simply uses the same menu name or toolbar name as the mainwindow.&lt;br /&gt;
&lt;br /&gt;
If a Merge tag is specified as a child of the MenuBar tag, the merging happens at that position; otherwise, it takes place on the right of the existing menus. The toolbar allows merging of the part's actions as well, based on the same principle.&lt;br /&gt;
&lt;br /&gt;
The Merge tag can also appear in a part's XML. It will be used for merging plug-ins or for more advanced uses; the merging engine can merge any number of &amp;quot;inputs&amp;quot; and it is possible to define specific inputs, such as the one Konqueror defines for its View menu.&lt;br /&gt;
&lt;br /&gt;
Another advanced use of the Merge tag is to set a name attribute for it. For instance, if another XML file wants to embed a part and any other parts or plug-ins at different positions in a given menu, it can use two merge tags:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Merge name=&amp;quot;MyPart&amp;quot;/&amp;gt;&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
 .&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;Merge /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using the name attribute for the Merge tag allows you to control at which position each XML fragment is merged, but it is usually unnecessary.&lt;br /&gt;
&lt;br /&gt;
==Read-Only and Read/Write Parts==&lt;br /&gt;
&lt;br /&gt;
The framework defines three kind of parts. The generic class is Part and is the one that provides the basic functionality for a part: widget, XML, and actions.&lt;br /&gt;
&lt;br /&gt;
===Read-Only Parts===&lt;br /&gt;
&lt;br /&gt;
The class ReadOnlyPart provides a common framework for all parts that implement any kind of viewer. A text viewer, an image viewer, a PostScript viewer, and a Web browser are all viewers. What they have in common is that they all act on a URL, and in a read-only way. It has always been a design decision in KDE to provide network transparency wherever possible, which is why most KDE applications use URLs, not only filenames. The framework defines methods for opening a URL, closing a URL, and above all provides network transparency - by downloading the file, if remote, and emitting signals (started, progression, completed). The part itself has to provide only openFile(), which opens a local file.&lt;br /&gt;
&lt;br /&gt;
This common framework for read-only parts enables applications to embed all viewers the same way and to better control those parts. For instance, when Konqueror uses a read-only part to display a file, it can make it open the file using openURL() and get all the progress information from the part. All this is not available in the generic Part class.&lt;br /&gt;
&lt;br /&gt;
===Read-Write Parts===&lt;br /&gt;
&lt;br /&gt;
The third kind of part is the ReadWritePart, which is an extension of the read-only one, to which it obviously adds the possibility to modify and save the document. This is the one used by a text editor part such as KWrite's, as well as all KOffice parts.&lt;br /&gt;
&lt;br /&gt;
For read/write parts, the framework provides the other half of the network transparency - re-uploading the document when saving, for remote files. A read/write part must also know how to act read-only, in case it is used as a read-only part. This is what happens when embedding KWrite or KOffice into Konqueror to view a text file, without being allowed to edit the file. More generally, any editor can be and must know how to be a viewer, as well.&lt;br /&gt;
&lt;br /&gt;
==Creating a Part==&lt;br /&gt;
&lt;br /&gt;
In this section, you create a very simple part for a text editor. If you have closely followed the previous section, you know that the part should inherit KParts::ReadWritePart.&lt;br /&gt;
&lt;br /&gt;
At this point, it is a very good idea to read kparts/part.h, directly or preferably after running kdoc on it (see Chapter 16, &amp;quot;Creating Documentation,&amp;quot; for information about kdoc). This tells you that a read/write part implementation has to provide the methods openFile() and saveFile().&lt;br /&gt;
&lt;br /&gt;
The task of openFile() is obviously to open a local file, which the framework has previously downloaded for us in case the URL that the user wants to open is a remote one. In this case, the file you open is a temporary local file.&lt;br /&gt;
&lt;br /&gt;
In saveFile(), the part saves to the local file, and in case it's a temporary file, the framework takes care of uploading the new file.&lt;br /&gt;
&lt;br /&gt;
You can now sketch the header file for your part, which is called NotepadPart (see Listing 13.2).&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.2 notepad_part.h: Header of the ''NotepadPart'' Class''====&lt;br /&gt;
&lt;br /&gt;
  1: #ifndef __notepad_h__&lt;br /&gt;
  2: #define __notepad_h__&lt;br /&gt;
  3:&lt;br /&gt;
  4: #include &amp;lt;kparts/part.h&amp;gt;&lt;br /&gt;
  5:&lt;br /&gt;
  6: class QMultiLineEdit;&lt;br /&gt;
  7:&lt;br /&gt;
  8: class NotepadPart : public KParts::ReadWritePart&lt;br /&gt;
  9: {&lt;br /&gt;
 10:   Q_OBJECT&lt;br /&gt;
 11: public:&lt;br /&gt;
 12:   NotepadPart( QWidget * parent, const char * name = 0L );&lt;br /&gt;
 13:   virtual ~NotepadPart() {}&lt;br /&gt;
 14:&lt;br /&gt;
 15:   virtual void setReadWrite( bool rw );&lt;br /&gt;
 16:&lt;br /&gt;
 17: protected:&lt;br /&gt;
 18:   virtual bool openFile();&lt;br /&gt;
 19:   virtual bool saveFile();&lt;br /&gt;
 20:&lt;br /&gt;
 21: protected slots:&lt;br /&gt;
 22:   void slotSelectAll();&lt;br /&gt;
 23:&lt;br /&gt;
 24: protected:&lt;br /&gt;
 25:   QMultiLineEdit * m_edit;&lt;br /&gt;
 26:   KInstance *m_instance;&lt;br /&gt;
 27: };&lt;br /&gt;
 28:&lt;br /&gt;
&lt;br /&gt;
 29: #endif&lt;br /&gt;
&lt;br /&gt;
The parent passed to the constructor is both the parent of the widget and the parent of the part itself, so that both get destroyed if the parent is destroyed. Note that having the same parent is not mandatory. If they have different parents, the framework deletes the widget if the part is destroyed and deletes the part if the widget is destroyed.&lt;br /&gt;
&lt;br /&gt;
The class members are a QMultiLineEdit (the multiline widget from Qt), and a KInstance. An instance enables access to global KDE objects, which can be different from the ones of the application. The application's configuration file and the one of any other instance is different, as well as the search paths for locate(), and so on. In KParts, this is used to locate the XML file describing the part, which is usually installed into share/apps/''instancename''/.&lt;br /&gt;
&lt;br /&gt;
In addition, you define a slot, slotSelectAll(), to be connected to the action your part provides.&lt;br /&gt;
&lt;br /&gt;
The corresponding XML file for the part NotepadPart is listed in Listing 13.3 and defines its GUI by an action named selectall, to be inserted into the menu Edit in the menubar. Note that the text for the Edit menu is specified, which is mandatory even if mainwindows usually specify it, because it has to work even if a mainwindow doesn't have an Edit menu on its own. So the rule is simple: always provide a text for all menus.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.3 notepadpart.rc: XML Description of the Notepad Part's User Interface''====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE kpartgui SYSTEM &amp;quot;kpartgui.dtd&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;kpartgui name=&amp;quot;NotepadPart&amp;quot; version=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;MenuBar&amp;gt;&lt;br /&gt;
  &amp;lt;Menu name=&amp;quot;Edit&amp;quot;&amp;gt;&amp;lt;Text&amp;gt;&amp;amp;amp;Edit&amp;lt;/Text&amp;gt;&lt;br /&gt;
   &amp;lt;Action name=&amp;quot;selectall&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/Menu&amp;gt;&lt;br /&gt;
 &amp;lt;/MenuBar&amp;gt;&lt;br /&gt;
 &amp;lt;StatusBar/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/kpartgui&amp;gt;&lt;br /&gt;
&lt;br /&gt;
An important task in the definition of a part is its constructor. It must at least define the instance, the widget, the actions, and the XML File. The constructor for this example could be as shown in Listing 13.4.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.4 notepad_part.cpp part 1: Constructor''====&lt;br /&gt;
&lt;br /&gt;
  1: NotepadPart::NotepadPart( QWidget * parent, const char * name )&lt;br /&gt;
  2:  : KParts::ReadWritePart( parent, name )&lt;br /&gt;
  3: {&lt;br /&gt;
  4:   KInstance * instance = new KInstance( &amp;quot;notepadpart&amp;quot; );&lt;br /&gt;
  5:   setInstance( instance );&lt;br /&gt;
  6:&lt;br /&gt;
  7:   m_edit = new QMultiLineEdit( parent, &amp;quot;multilineedit&amp;quot; );&lt;br /&gt;
  8:   m_edit-&amp;gt;setFocus();&lt;br /&gt;
  9:   setWidget( m_edit );&lt;br /&gt;
 10:&lt;br /&gt;
 11:   (void)new KAction( i18n( &amp;quot;Select All&amp;quot; ), 0, this,&lt;br /&gt;
 12:         SLOT( slotSelectAll() ), actionCollection(), &amp;quot;selectall&amp;quot; );&lt;br /&gt;
 13:   setXMLFile( &amp;quot;notepadpart.rc&amp;quot; );&lt;br /&gt;
 14:&lt;br /&gt;
 15:   setReadWrite( true );&lt;br /&gt;
&lt;br /&gt;
 16: }&lt;br /&gt;
&lt;br /&gt;
After calling the parent constructor with parent and name, you create an instance, named notepadpart, and declare it to the framework using setInstance(). This is a temporary solution; you'll see later how to use a library-factory's instance. Then you create the multiline edit widget, give it the focus, and declare it as well, using setWidget().&lt;br /&gt;
&lt;br /&gt;
The next step is to create the actions that your part provides. The &amp;quot;selectall&amp;quot; action is given a translated label, is connected to slotSelectAll(), and is created as a child of the action collection that the framework provides. This is important, because it's the only way to make it find the action later on, when parsing the XML file. This is why you don't even need to store the action in a variable, unless you want to be able to enable or disable it later.&lt;br /&gt;
&lt;br /&gt;
You also need to give the framework the name of the XML file describing the part's GUI. As mentioned previously, it is usually installed into share/apps/''instancename''/, and in this case, you simply pass the filename with no path. It is also possible, but not recommended, to install the XML file anywhere else and provide a full path in setXMLFile().&lt;br /&gt;
&lt;br /&gt;
Finally, the part is set to read/write mode. Read/write parts feature the setReadWrite() call, which enables you to set the read/write mode on or off. Most parts should reimplement this method to enable or disable anything that modifies the part, KActions as well as any direct modification provided by the widget itself. The reimplementation of setReadWrite() for the NotepadPart is shown in Listing 13.5.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.5 notepad_part.cpp part 2: Implementation of setReadWrite''====&lt;br /&gt;
&lt;br /&gt;
 void NotepadPart::setReadWrite( bool rw )&lt;br /&gt;
 {&lt;br /&gt;
   m_edit-&amp;gt;setReadOnly( !rw );&lt;br /&gt;
   if (rw)&lt;br /&gt;
     connect( m_edit, SIGNAL( textChanged() ), this, SLOT( setModified() ) );&lt;br /&gt;
   else&lt;br /&gt;
     disconnect( m_edit, SIGNAL( textChanged() ), this, SLOT( setModified() ) );&lt;br /&gt;
 &lt;br /&gt;
   ReadWritePart::setReadWrite( rw ); // always call the parent implementation&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
In the example, there are no actions to disable, but the multiline widget has to be set to its read-only mode.&lt;br /&gt;
&lt;br /&gt;
The connection to setModified(), done in read/write mode only, enables the framework to keep track of the state of the document. When closing a document that has been modified, the framework automatically asks whether it should save it and allow you to cancel the close. Note that to make all this work, you just needed to connect a signal when the part is in read/write mode and disconnect it when it's in read-only mode. This avoids warnings when a loading a file, which changes the text.&lt;br /&gt;
&lt;br /&gt;
It might seem a bit painful to have to handle both read/write and read-only mode, but doing this gives for free the possibility to embed the part as a viewer, in Konqueror, for instance, so it's usually worth doing.&lt;br /&gt;
&lt;br /&gt;
Your part is created; you need to make it useful. The method that all read-only parts - and by inheritance, all read/write parts as well - must reimplement is the openFile() method. This is where a part opens and displays the local file, whose full path is provided in the member variable m_file, and which the framework downloaded from a remote location first, if necessary. Because your part is a text viewer, all it has to do is read the file into a QString and set the multiline widget's text from it, as shown in Listing 13.6.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.6 notepad_part.cpp part 3: Implementation of openFile''====&lt;br /&gt;
&lt;br /&gt;
  1: bool NotepadPart::openFile()&lt;br /&gt;
  2: {&lt;br /&gt;
  3:   QFile f(m_file);&lt;br /&gt;
  4:   QString s;&lt;br /&gt;
  5:   if ( f.open(IO_ReadOnly) )&lt;br /&gt;
  6:   {&lt;br /&gt;
  7:     QTextStream t( &amp;amp;f );&lt;br /&gt;
  8:     while ( !t.eof() ) {&lt;br /&gt;
  9:       s += t.readLine() + &amp;quot;\n&amp;quot;;&lt;br /&gt;
 10:     }&lt;br /&gt;
 11:     f.close();&lt;br /&gt;
 12:   }&lt;br /&gt;
 13:   m_edit-&amp;gt;setText(s);&lt;br /&gt;
 14:&lt;br /&gt;
 15:   return true;&lt;br /&gt;
&lt;br /&gt;
 16: }&lt;br /&gt;
&lt;br /&gt;
The last thing you need to do is, of course, to provide saving; otherwise, the user will not like it! All read/write parts have to reimplement saveFile() to save the document to m_file, as shown in Listing 13.7. Note that the framework takes care of Save As (changing the URL to Save To), as well as uploading the saved file, if necessary.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.7 notepad_part.cpp part 4: Implementation of saveFile''====&lt;br /&gt;
&lt;br /&gt;
  1: bool NotepadPart::saveFile()&lt;br /&gt;
  2: {&lt;br /&gt;
  3:   if ( !isReadWrite() )&lt;br /&gt;
  4:     return false;&lt;br /&gt;
  5:   QFile f(m_file);&lt;br /&gt;
  6:   QString s;&lt;br /&gt;
  7:   if ( f.open(IO_WriteOnly) ) {&lt;br /&gt;
  8:     QTextStream t( &amp;amp;f );&lt;br /&gt;
  9:     t &amp;lt;&amp;lt; m_edit-&amp;gt;text();&lt;br /&gt;
 10:     f.close();&lt;br /&gt;
 11:     return true ;&lt;br /&gt;
 12:   } else&lt;br /&gt;
 13:     return false;&lt;br /&gt;
&lt;br /&gt;
 14: }&lt;br /&gt;
&lt;br /&gt;
==Making a Part Available Using Shared Libraries==&lt;br /&gt;
&lt;br /&gt;
You know how to create a part now. But currently, it can be used only by linking directly to its code. Although this is enough in some cases, such as KWrite's part embedded by KWrite itself, it is much more flexible to provide dynamic linking to the library containing the part. This is not directly related to KParts, but it is necessary to make it possible for any application to use the part.&lt;br /&gt;
&lt;br /&gt;
The first step is to compile the part in a shared library, which is really simple using automake. The relevant portion of Makefile.am is shown in Listing 13.8&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.8 Extract from Makefile.am''====&lt;br /&gt;
&lt;br /&gt;
 lib_LTLIBRARIES = libnotepad.la&lt;br /&gt;
 libnotepad_la_SOURCES = notepad_part.cpp notepad_factory.cpp&lt;br /&gt;
 libnotepad_la_LIBADD = $(LIB_KFILE) $(LIB_KPARTS)&lt;br /&gt;
 libnotepad_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)&lt;br /&gt;
&lt;br /&gt;
 METASOURCES = AUTO&lt;br /&gt;
&lt;br /&gt;
Your part is now available in a shared library, but this is not enough. You must provide a way for anybody opening that library dynamically to create a part. This is done using a factory, derived from KLibFactory, which you'll do in the class NotepadFactory. An application willing to open a shared library dynamically uses the class KLibLoader, which takes care of locating the library, opening it, and calling an initialization function - here init_libnotepad(). This function creates a NotepadFactory and returns it to KLibLoader, which can then call the create method on the factory. This means that all you need to do in the library itself is define init_libnotepad() and the NotepadFactory.&lt;br /&gt;
&lt;br /&gt;
The header for the factory is the one shown in Listing 13.9.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.9 notepad_factory.h: Header File for NotepadFactory''====&lt;br /&gt;
&lt;br /&gt;
  1: #include &amp;lt;klibloader.h&amp;gt;&lt;br /&gt;
  2: class KInstance;&lt;br /&gt;
  3: class KAboutData;&lt;br /&gt;
  4: class NotepadFactory: public KLibFactory&lt;br /&gt;
  5: {&lt;br /&gt;
  6:   Q_OBJECT&lt;br /&gt;
  7: public:&lt;br /&gt;
  8:   NotepadFactory( QObject * parent = 0, const char * name = 0 );&lt;br /&gt;
  9:   ~NotepadFactory();&lt;br /&gt;
 10:&lt;br /&gt;
 11:   // reimplemented from KLibFactory&lt;br /&gt;
 12:   virtual QObject * create( QObject * parent = 0, const char * name = 0,&lt;br /&gt;
 13:         const char * classname = &amp;quot;QObject&amp;quot;,&lt;br /&gt;
 14:         const QStringList &amp;amp;args = QStringList());&lt;br /&gt;
 15:&lt;br /&gt;
 16:   static KInstance * instance();&lt;br /&gt;
 17:&lt;br /&gt;
 18: private:&lt;br /&gt;
 19:  static KInstance * s_instance;&lt;br /&gt;
 20:  static KAboutData * s_about;&lt;br /&gt;
&lt;br /&gt;
 21: };&lt;br /&gt;
&lt;br /&gt;
As required by KLibFactory, your factory implements the create method, which creates a Notepad part and sets it to read/write mode or read-only mode, depending on whether the classname is KParts::ReadWritePart or KParts::ReadOnlyPart.&lt;br /&gt;
&lt;br /&gt;
It also features a static instance, which is used in the part, instead of creating your own instance for each part. It is static because usually there is only one instance per library.&lt;br /&gt;
&lt;br /&gt;
This means the code of notepad_part.cpp should be modified to call setInstance( NotepadFactory::instance() ); instead of creating its own instance.&lt;br /&gt;
&lt;br /&gt;
The implementation for the NotepadFactory is shown in Listing 13.10.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.10 notepad_factory.cpp: NotepadFactory Implementation.''====&lt;br /&gt;
&lt;br /&gt;
  1: #include &amp;quot;notepad_factory.h&amp;quot;&lt;br /&gt;
  2:&lt;br /&gt;
  3: #include &amp;lt;klocale.h&amp;gt;&lt;br /&gt;
  4: #include &amp;lt;kstddirs.h&amp;gt;&lt;br /&gt;
  5: #include &amp;lt;kinstance.h&amp;gt;&lt;br /&gt;
  6: #include &amp;lt;kaboutdata.h&amp;gt;&lt;br /&gt;
  7:&lt;br /&gt;
  8: #include &amp;quot;notepad_part.h&amp;quot;&lt;br /&gt;
  9:&lt;br /&gt;
 10: extern &amp;quot;C&amp;quot;&lt;br /&gt;
 11: {&lt;br /&gt;
 12:     void* init_libnotepad()&lt;br /&gt;
 13:     {&lt;br /&gt;
 14:     return new NotepadFactory;&lt;br /&gt;
 15:     }&lt;br /&gt;
 16: };&lt;br /&gt;
 17:&lt;br /&gt;
 18: KInstance* NotepadFactory::s_instance = 0L;&lt;br /&gt;
 19: KAboutData* NotepadFactory::s_about = 0L;&lt;br /&gt;
 20:&lt;br /&gt;
 21: NotepadFactory::NotepadFactory( QObject* parent, const char* name )&lt;br /&gt;
 22:     : KLibFactory( parent, name )&lt;br /&gt;
 23: {&lt;br /&gt;
 24: }&lt;br /&gt;
 25:&lt;br /&gt;
 26: NotepadFactory::~NotepadFactory()&lt;br /&gt;
 27: {&lt;br /&gt;
 28:   delete s_instance;&lt;br /&gt;
 29:   s_instance = 0L;&lt;br /&gt;
 30:   delete s_about;&lt;br /&gt;
 31: }&lt;br /&gt;
 32:&lt;br /&gt;
 33: QObject* NotepadFactory::create( QObject* parent, const char* name,&lt;br /&gt;
 34:                                  const char* classname, const QStringList &amp;amp; )&lt;br /&gt;
 35: {&lt;br /&gt;
 36:   if ( parent &amp;amp;&amp;amp; !parent-&amp;gt;inherits(&amp;quot;QWidget&amp;quot;) )&lt;br /&gt;
 37:   {&lt;br /&gt;
 38:     kdError() &amp;lt;&amp;lt; &amp;quot;NotepadFactory: parent does not inherit QWidget&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
 39:     return 0L;&lt;br /&gt;
 40:   }&lt;br /&gt;
 41:&lt;br /&gt;
 42:   NotepadPart* part = new NotepadPart( (QWidget*) parent, name );&lt;br /&gt;
 43:   // readonly ?&lt;br /&gt;
 44:   if (QCString(classname) == &amp;quot;KParts::ReadOnlyPart&amp;quot;)&lt;br /&gt;
 45:      part-&amp;gt;setReadWrite(false);&lt;br /&gt;
 46:&lt;br /&gt;
 47:   // otherwise, it has to be readwrite&lt;br /&gt;
 48:   else if (QCString(classname) != &amp;quot;KParts::ReadWritePart&amp;quot;)&lt;br /&gt;
 49:   {&lt;br /&gt;
 50:     kdError() &amp;lt;&amp;lt; &amp;quot;classname isn't ReadOnlyPart nor ReadWritePart !&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
 51:     return 0L;&lt;br /&gt;
 52:   }&lt;br /&gt;
 53:&lt;br /&gt;
 54:   emit objectCreated( part );&lt;br /&gt;
 55:   return part;&lt;br /&gt;
 56: }&lt;br /&gt;
 57:&lt;br /&gt;
 58: KInstance* NotepadFactory::instance()&lt;br /&gt;
 59: {&lt;br /&gt;
 60:   if( !s_instance )&lt;br /&gt;
 61:   {&lt;br /&gt;
 62:     s_about = new KAboutData( &amp;quot;notepadpart&amp;quot;,&lt;br /&gt;
 63:                               I18N_NOOP( &amp;quot;Notepad&amp;quot; ), &amp;quot;2.0pre&amp;quot; );&lt;br /&gt;
 64:     s_instance = new KInstance( s_about );&lt;br /&gt;
 65:   }&lt;br /&gt;
 66:   return s_instance;&lt;br /&gt;
 67: }&lt;br /&gt;
 68:&lt;br /&gt;
&lt;br /&gt;
 69: #include &amp;quot;notepad_factory.moc&amp;quot;&lt;br /&gt;
&lt;br /&gt;
The implementation is a bit long but contains nothing complex. Basically, you define the function that is the entry point of the library, init_libnotepad(). It needs to be linked as a C function to avoid C++ name mangling. C linkage means that the symbol in the library will match the function name.&lt;br /&gt;
&lt;br /&gt;
Then you define the NotepadFactory. The create method checks that the parent is a widget because this is needed for your part (remember, you create your widget with the parent widget given as an argument to the constructor). After creating the part, it has to emit objectCreated so that the library loader can do a proper reference counting; it automatically unloads the library after all objects created from it have been destroyed.&lt;br /&gt;
&lt;br /&gt;
The instance() method returns the static instance, creating it first, if necessary. To create an instance, I recommend that you give it a KAboutData pointer. This gives some information about the instance representing the library (here an instance name, a translatable description of it, and a version number). You can add a lot more information in the KAboutData object, such as authors, home page, and bug-report address. See the documentation for details.&lt;br /&gt;
&lt;br /&gt;
The standard KDE dialogs such as the Bug Report Dialog and the About Dialog use the data stored in KAboutData to show information about the current program, but in the future they will probably be improved to show information about the active part as well, which can have completely different About data from the application.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;90%&amp;quot; cellpadding=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| bgcolor=&amp;quot;#DDDDDD&amp;quot; |&lt;br /&gt;
'''Note -''' KParts provides a factory base class, KParts::Factory, which enhances KlibFactory by making it possible to have a parent for the widget different from the parent for the part. It also takes care of loading the translation message catalog for the newly created part. Look in kparts/factory.h for more on this.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Creating a KParts Application==&lt;br /&gt;
&lt;br /&gt;
If an application wants to use parts and the GUI merging feature, its own GUI needs to be defined in XML. The top level windows of the application will then use the class KParts::MainWindow.&lt;br /&gt;
&lt;br /&gt;
Note that it's also possible to use a part in a standard application, using KTMainWindow, but then no GUI merging happens. In this case, only the functionality provided by the widget and by the part API are available, so the application has to create the GUI for part's functionality itself, or the part has to provide it through context menus. In any case, it is much less flexible.&lt;br /&gt;
&lt;br /&gt;
As an example of a window based on KParts::MainWindow, you are going to create a PostScript viewer very easily, by embedding the part provided by KDE's PostScript viewer, KGhostView.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;90%&amp;quot; cellpadding=&amp;quot;3&amp;quot; align=&amp;quot;center&amp;quot;&lt;br /&gt;
| bgcolor=&amp;quot;#DDDDDD&amp;quot; |&lt;br /&gt;
'''Note -''' You need to install the package kdegraphics if you want to test this example.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first thing to look at is the mainwindow's GUI; an example is given in Listing 13.11.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.11 ghostviewtest_shell.rc: The Mainwindow's GUI''====&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE kpartgui SYSTEM &amp;quot;kpartgui.dtd&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;kpartgui name=&amp;quot;KGVShell&amp;quot; version=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;MenuBar&amp;gt;&lt;br /&gt;
  &amp;lt;Menu name=&amp;quot;file&amp;quot;&amp;gt;&amp;lt;text&amp;gt;&amp;amp;amp;File&amp;lt;/text&amp;gt;&lt;br /&gt;
   &amp;lt;Action name=&amp;quot;file_open&amp;quot;/&amp;gt;&lt;br /&gt;
   &amp;lt;Merge/&amp;gt;&lt;br /&gt;
   &amp;lt;Action name=&amp;quot;file_quit&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/Menu&amp;gt;&lt;br /&gt;
 &amp;lt;/MenuBar&amp;gt;&lt;br /&gt;
 &amp;lt;ToolBar name=&amp;quot;KGV-ToolBar&amp;quot;&amp;gt;&amp;lt;text&amp;gt;KGhostView&amp;lt;/text&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;file_open&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;file_quit&amp;quot;/&amp;gt;&lt;br /&gt;
 &amp;lt;/ToolBar&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/kpartgui&amp;gt;&lt;br /&gt;
&lt;br /&gt;
By analogy with a command line's shell, a main window is often called a shell. In its GUI you define the actions that will always be shown, whichever part is active. The listing for a simple KParts mainwindow is shown in Listing 13.12&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.12 ghostviewtest.h: Header for a Simple KParts Mainwindow''====&lt;br /&gt;
&lt;br /&gt;
  1: #include &amp;lt;kparts/mainwindow.h&amp;gt;&lt;br /&gt;
  2:&lt;br /&gt;
  3: class Shell : public KParts::MainWindow&lt;br /&gt;
  4: {&lt;br /&gt;
  5:   Q_OBJECT&lt;br /&gt;
  6: public:&lt;br /&gt;
  7:   Shell();&lt;br /&gt;
  8:   virtual ~Shell();&lt;br /&gt;
  9:&lt;br /&gt;
 10:   void openURL( const KURL &amp;amp; url );&lt;br /&gt;
 11:&lt;br /&gt;
 12: protected slots:&lt;br /&gt;
 13:   void slotFileOpen();&lt;br /&gt;
 14:&lt;br /&gt;
 15: private:&lt;br /&gt;
 16:   KParts::ReadOnlyPart *m_gvpart;&lt;br /&gt;
&lt;br /&gt;
 17: };&lt;br /&gt;
&lt;br /&gt;
The mainwindow inherits KParts::MainWindow instead of KTMainWindow. Nothing else is required; the openURL() here is just so that main() can call openURL() on the window. The URL could be passed to the constructor instead.&lt;br /&gt;
&lt;br /&gt;
The code for the mainwindow embedding the KGhostView part is part of the KParts examples, which can be found under kdelibs/kparts/tests/ghostview*, so Listing 13.13 only shows the relevant lines of ghostview.cpp.&lt;br /&gt;
&lt;br /&gt;
====''Listing 13.13 Excerpt of ghostviewtest.cpp: Implementation of the Simple KParts Mainwindow''====&lt;br /&gt;
&lt;br /&gt;
  1: Shell::Shell()&lt;br /&gt;
  2: {&lt;br /&gt;
  3:   setXMLFile( &amp;quot;ghostviewtest_shell.rc&amp;quot; );&lt;br /&gt;
  4:&lt;br /&gt;
  5:   KAction * paOpen = new KAction( i18n( &amp;quot;&amp;amp;Open file&amp;quot; ), &amp;quot;fileopen&amp;quot;, 0,&lt;br /&gt;
  6:             this, SLOT( slotFileOpen() ), actionCollection(), &amp;quot;file_open&amp;quot; );&lt;br /&gt;
  7:&lt;br /&gt;
  8:   KAction * paQuit = new KAction( i18n( &amp;quot;&amp;amp;Quit&amp;quot; ), &amp;quot;exit&amp;quot;, 0,&lt;br /&gt;
  9:             this, SLOT( close() ), actionCollection(), &amp;quot;file_quit&amp;quot; );&lt;br /&gt;
 10:&lt;br /&gt;
 11:   // Try to find libkghostview&lt;br /&gt;
 12:   KLibFactory *factory = KLibLoader::self()-&amp;gt;factory( &amp;quot;libkghostview&amp;quot; );&lt;br /&gt;
 13:   if (factory)&lt;br /&gt;
 14:   {&lt;br /&gt;
 15:     // Create the part&lt;br /&gt;
 16:     m_gvpart = (KParts::ReadOnlyPart *)factory-&amp;gt;create( this, &amp;quot;kgvpart&amp;quot;,&lt;br /&gt;
 17:                &amp;quot;KParts::ReadOnlyPart&amp;quot; );&lt;br /&gt;
 18:     // Set the main widget&lt;br /&gt;
 19:     setView( m_gvpart-&amp;gt;widget() );&lt;br /&gt;
 20:     // Integrate its GUI&lt;br /&gt;
 21:     createGUI( m_gvpart );&lt;br /&gt;
 22:   }&lt;br /&gt;
 23:   else&lt;br /&gt;
 24:     kdFatal() &amp;lt;&amp;lt; &amp;quot;No libkghostview found !&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
 25: }&lt;br /&gt;
 26:&lt;br /&gt;
 27: Shell::~Shell()&lt;br /&gt;
 28: {&lt;br /&gt;
 29:   delete m_gvpart;&lt;br /&gt;
 30: }&lt;br /&gt;
 31:&lt;br /&gt;
 32: void Shell::openURL( const KURL &amp;amp; url )&lt;br /&gt;
 33: {&lt;br /&gt;
 34:   m_gvpart-&amp;gt;openURL( url );&lt;br /&gt;
&lt;br /&gt;
 35: }&lt;br /&gt;
&lt;br /&gt;
A mainwindow is created much like a part, with an XML file and actions. To find a part, it uses KLibLoader to get the KLibFactory for the library. A flexible application would use .desktop files for this and KIO's trader for selecting the user's preferred component, but for the sake of simplicity, open the library by its name here. After the factory has been created, the mainwindow makes it create a ReadOnlyPart, and because here you have only one part in the window, the part's widget is set as the main widget of the window with setView. Then a mainwindow needs to call createGUI() to make the framework create the GUI, merging the actions of the mainwindow with those of the active part. A mainwindow with no part will simply call createGUI(0L).&lt;br /&gt;
&lt;br /&gt;
Using this mainwindow, for instance from main(), is as simple as&lt;br /&gt;
&lt;br /&gt;
 Shell *shell = new Shell;&lt;br /&gt;
 shell-&amp;gt;openURL( url );&lt;br /&gt;
&lt;br /&gt;
 shell-&amp;gt;show();&lt;br /&gt;
&lt;br /&gt;
Compile kdelibs/kparts/tests/ghostviewtest to test this simple example of how to embed a part.&lt;br /&gt;
&lt;br /&gt;
==Embedding More Than One Part in the Same Window==&lt;br /&gt;
&lt;br /&gt;
The previous example showed how to embed a part as the single widget of a window. KParts also makes it possible to embed more than one part in the same window, and it handles the activation of a part when the user clicks it (or uses Tab to give it the focus). This is the task of the PartManager.&lt;br /&gt;
&lt;br /&gt;
To display more than one part in a window, the solution is usually to use a splitter, or even nested splitters, such as in Konqueror. KOffice has another way of embedding several parts - by using frames for the child parts - but it still uses PartManager.&lt;br /&gt;
&lt;br /&gt;
Now modify the example to make it display, in addition to the PostScript document, the PostScript code for it. To display the text, the application uses the Notepad part in read-only mode. The two widgets will be hosted by a splitter.&lt;br /&gt;
&lt;br /&gt;
Displaying raw PostScript is not very useful, but this example could, for instance, be turned into an application showing the LaTeX source and the PostScript result side by side.&lt;br /&gt;
&lt;br /&gt;
ghostviewtest.h needs to be modified slightly to add the following private members:&lt;br /&gt;
&lt;br /&gt;
   KParts::ReadOnlyPart *m_notepadpart;&lt;br /&gt;
   KParts::PartManager *m_manager;&lt;br /&gt;
&lt;br /&gt;
   QSplitter *m_splitter;&lt;br /&gt;
&lt;br /&gt;
ghostviewtest.cpp needs to be more modified. To include the PartManager definition, use the following:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#include &amp;lt;kparts/partmanager.h&amp;gt;&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the constructor, create the part manager and connect its main signal, activePartChanged, to your createGUI slot. This means you don't need to call createGUI directly; it is called every time the active part changes.&lt;br /&gt;
&lt;br /&gt;
   m_manager = new KParts::PartManager( this );&lt;br /&gt;
   // When the manager says the active part changes,&lt;br /&gt;
   // the builder updates (recreates) the GUI&lt;br /&gt;
   connect( m_manager, SIGNAL( activePartChanged( KParts::Part * ) ),&lt;br /&gt;
&lt;br /&gt;
            this, SLOT( createGUI( KParts::Part * ) ) );&lt;br /&gt;
&lt;br /&gt;
Then create the splitter and transform the setView statement into the following:&lt;br /&gt;
&lt;br /&gt;
   m_splitter = new QSplitter( this );&lt;br /&gt;
&lt;br /&gt;
   setView( m_splitter );&lt;br /&gt;
&lt;br /&gt;
so that the main widget is now the splitter. Both parts need to be created with the splitter as a parent (instead of the window):&lt;br /&gt;
&lt;br /&gt;
   KLibFactory *factory = KLibLoader::self()-&amp;gt;factory( &amp;quot;libkghostview&amp;quot; );&lt;br /&gt;
   if (factory)&lt;br /&gt;
   {&lt;br /&gt;
     m_gvpart = (KParts::ReadOnlyPart *)factory-&amp;gt;create( m_splitter,&lt;br /&gt;
                 &amp;quot;kgvpart&amp;quot;, &amp;quot;KParts::ReadOnlyPart&amp;quot; );&lt;br /&gt;
   }&lt;br /&gt;
   else&lt;br /&gt;
      kdFatal() &amp;lt;&amp;lt; &amp;quot;No libkghostview found !&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
 &lt;br /&gt;
   factory = KLibLoader::self()-&amp;gt;factory( &amp;quot;libnotepad&amp;quot; );&lt;br /&gt;
   if (factory)&lt;br /&gt;
     m_notepadpart = (KParts::ReadOnlyPart *)factory-&amp;gt;create( m_splitter,&lt;br /&gt;
                      &amp;quot;knotepadpart&amp;quot;, &amp;quot;KParts::ReadOnlyPart&amp;quot; );&lt;br /&gt;
   else&lt;br /&gt;
&lt;br /&gt;
      kdFatal() &amp;lt;&amp;lt; &amp;quot;No libnotepad found !&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
&lt;br /&gt;
After the parts are created, they should be added to the part manager. At the same time, you can specify which one should initially be active:&lt;br /&gt;
&lt;br /&gt;
   m_manager-&amp;gt;addPart( m_gvpart, true ); // sets as the active part&lt;br /&gt;
&lt;br /&gt;
   m_manager-&amp;gt;addPart( m_notepadpart, false );&lt;br /&gt;
&lt;br /&gt;
Then the splitter can be set to a minimum size, as shown:&lt;br /&gt;
&lt;br /&gt;
   m_splitter-&amp;gt;setMinimumSize( 400, 300 );&lt;br /&gt;
&lt;br /&gt;
   m_splitter-&amp;gt;show();&lt;br /&gt;
&lt;br /&gt;
Finally, add the following line to openURL() to open the same URL in both parts:&lt;br /&gt;
&lt;br /&gt;
   m_notepadpart-&amp;gt;openURL( url );&lt;br /&gt;
&lt;br /&gt;
As you can see, the main idea is that the mainwindow creates a main widget (here, the splitter), creates all parts inside it, and registers the part to a part manager. Try clicking one part and then the other; each time the active part changes, the GUI is updated (both menus and toolbars) to show the GUI of the active part.&lt;br /&gt;
&lt;br /&gt;
Note also the change in the window caption. This is handled by the Part class, which receives the GUIActivateEvent from the mainwindow when the part is activated or deactivated. To set a different caption for a part, you need to emit setWindowCaption both in openFile() and in guiActivateEvent().&lt;br /&gt;
&lt;br /&gt;
==Creating a KParts Plug-in==&lt;br /&gt;
&lt;br /&gt;
A plug-in is the way to implement some functionality out of a part but still in a shared library, with actions defined by the plug-in to access this functionality. Those actions, whose layout is described in XML as usual, can be merged in a part's user interface or in a mainwindow's, depending on whether it applies to a part or to an application.&lt;br /&gt;
&lt;br /&gt;
Several reasons exist for using plug-ins. One is saving memory, because the plug-in is not loaded until one of its actions is called, but the main reason is reusability - the same plug-in can apply to several parts or applications. For instance, a spell-checker plug-in can apply to all kinds of text editors, mail composers, word processors, and even presenters.&lt;br /&gt;
&lt;br /&gt;
A plug-in can have a user interface, such as the dialog box for the spell checker, but not necessarily. Plug-ins can also act directly on the part or the application or anything else.&lt;br /&gt;
&lt;br /&gt;
The XML for a spell-checker plug-in is shown below:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;!DOCTYPE kpartgui&amp;gt;&lt;br /&gt;
 &amp;lt;kpartgui library=&amp;quot;libspellcheck&amp;quot;&amp;gt;&lt;br /&gt;
 &amp;lt;MenuBar&amp;gt;&lt;br /&gt;
  &amp;lt;Menu name=&amp;quot;edit&amp;quot;&amp;gt;&amp;lt;Text&amp;gt;&amp;amp;amp;Edit&amp;lt;/Text&amp;gt;&lt;br /&gt;
   &amp;lt;Action name=&amp;quot;spellcheck&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;/Menu&amp;gt;&lt;br /&gt;
 &amp;lt;/MenuBar&amp;gt;&lt;br /&gt;
 &amp;lt;/kpartgui&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;/kpartplugin&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note the additional attribute in the main tag: library defines the name of the library to open to find the plug-in. This is because no .desktop file exists for plug-ins. Installing the preceding XML file in partplugins/, under share/apps/notepadpart, automatically inserts the plug-in's action in the NotepadPart user interface.&lt;br /&gt;
&lt;br /&gt;
You know how the plug-in's library will be opened; now you need only to create a factory in the library, as usual, and let it create an instance of the plug-in. Writing the factory, which doesn't even need an instance in the simple case, and the init_libspellcheck() function will be left as an exercise to the reader.&lt;br /&gt;
&lt;br /&gt;
To define a plug-in, simply inherit KParts::Plugin and add slots for its actions:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#include &amp;lt;kparts/plugin.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 class PluginSpellCheck : public KParts::Plugin&lt;br /&gt;
 {&lt;br /&gt;
     Q_OBJECT&lt;br /&gt;
 public:&lt;br /&gt;
     PluginSpellCheck( QObject* parent = 0, const char* name = 0 );&lt;br /&gt;
     virtual ~PluginSpellCheck() {}&lt;br /&gt;
 &lt;br /&gt;
 public slots:&lt;br /&gt;
     void slotSpellCheck();&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 };&lt;br /&gt;
&lt;br /&gt;
In the implementation, you have to create the plug-in actions; no setXMLFile is here because it has been found by the part already.&lt;br /&gt;
&lt;br /&gt;
Because in this example you are not going to create a real spell checker - a libkspell exists for that - call the action &amp;quot;select current line&amp;quot; and implement that in the slot.&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;nowiki&amp;gt;#include &amp;quot;plugin_spellcheck.h&amp;quot;&lt;br /&gt;
 #include &amp;quot;notepad.h&amp;quot; // this plugin applies to a notepad part&lt;br /&gt;
 #include &amp;lt;qmultilineedit.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;kaction.h&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
 PluginSpellCheck::PluginSpellCheck( QObject* parent, const char* name )&lt;br /&gt;
     : Plugin( parent, name )&lt;br /&gt;
 {&lt;br /&gt;
     (void) new KAction( i18n( &amp;quot;&amp;amp;Select current line (plug-in)&amp;quot; ), 0, this,&lt;br /&gt;
                 SLOT(slotSpellCheck()), actionCollection(), &amp;quot;spellcheck&amp;quot; );&lt;br /&gt;
 }&lt;br /&gt;
 &lt;br /&gt;
 void PluginSpellCheck::slotSpellCheck()&lt;br /&gt;
 {&lt;br /&gt;
     // Check that the parent is a NotepadPart&lt;br /&gt;
     if ( !parent()-&amp;gt;inherits(&amp;quot;NotepadPart&amp;quot;) )&lt;br /&gt;
        kdFatal() &amp;lt;&amp;lt; &amp;quot;Spell-check plug-in for wrong part (not NotepadPart)&amp;quot; &amp;lt;&amp;lt; endl;&lt;br /&gt;
     else&lt;br /&gt;
     {&lt;br /&gt;
          NotepadPart * part = (NotepadPart *) parent();&lt;br /&gt;
          QMultiLineEdit * widget = (QMultiLineEdit *) part-&amp;gt;widget();&lt;br /&gt;
          widget-&amp;gt;selectAll(); //selects current line !&lt;br /&gt;
     }&lt;br /&gt;
 &amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 }&lt;br /&gt;
&lt;br /&gt;
Note that to access the part's widget, the plug-in has to assume - and check - that it has been installed for a NotepadPart. This means that you should not install it under another part's directory. But selecting the current line in an image viewer wouldn't mean much anyway.&lt;br /&gt;
&lt;br /&gt;
A more flexible plug-in would instead check and cast the parent to ReadWritePart and then check the type of its widget to be QMultiLineEdit.&lt;br /&gt;
&lt;br /&gt;
==Summary==&lt;br /&gt;
&lt;br /&gt;
After the presentation of component technology and how to lay out actions using XML, you have seen most of what KParts can do: three types of parts, part mainwindows, part manager, plug-ins, as well as how dynamic loading works - library factories and library loader.&lt;br /&gt;
&lt;br /&gt;
You can do other interesting things with parts. Having a part embed itself in Konqueror is very simple; it's just a matter of providing a .desktop file for it, stating that it is a service that implements some servicetypes, which are the mimetypes that the part allows to view, plus the servicetype KParts::ReadOnlyPart. That's it. Konqueror will use the part to view the files of those mimetypes if no other service is set as more preferred in Configure File Types.&lt;br /&gt;
&lt;br /&gt;
To provide better integration with Konqueror, you can also provide a KParts::BrowserExtension for the part, as defined in kparts/browserextension.h. This is what makes it possible to save and restore a view in Konqueror's history and for the part to use Konqueror's &amp;quot;standard actions.&amp;quot; Examples of parts using the browser extension can be found in KView, KDVI, KGhostView, KWrite and all built-in Konqueror views.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation</id>
		<title>Development/Architecture/KDE3/Imaging and Animation</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation"/>
				<updated>2007-01-12T21:10:31Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
&lt;br /&gt;
==KDE Image I/O library kimgio==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kimgio)&lt;br /&gt;
&lt;br /&gt;
===Reading and writing images===&lt;br /&gt;
&lt;br /&gt;
This library allows applications that use the Qt library to read and write images in extra formats. Current formats include:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! format&lt;br /&gt;
! read&lt;br /&gt;
! write&lt;br /&gt;
|-&lt;br /&gt;
| JPEG&lt;br /&gt;
| X&lt;br /&gt;
| if QImgio/libjpeg is installed&lt;br /&gt;
|-&lt;br /&gt;
| JPEG 2000&lt;br /&gt;
|&lt;br /&gt;
if [http://www.ece.uvic.ca/~mdadams/jasper/ JasPer] is installed&lt;br /&gt;
|-&lt;br /&gt;
| XV&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| EPS&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| NETPBM&lt;br /&gt;
| incomplete&lt;br /&gt;
|-&lt;br /&gt;
| TIFF&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| KRL&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNG (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| BMP (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| XBM (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PBM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| GIF&amp;lt;sup&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&amp;lt;/sup&amp;gt; (87 &amp;amp; 89a) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Due to patent reasons, GIF support isn't compiled in Qt by default. You need to enable it with &amp;lt;tt&amp;gt;./configure -gif&amp;lt;/tt&amp;gt; when compiling Qt.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that this is only legal if you've got a license from Unisys or don't live in a country where Unisys holds a patent on the LZW compression. Countries in that Unisys holds a patent include Canada, Japan, the USA, France, Germany, Italy and the UK. There is more information about that topic on the [http://www.unisys.com/unisys/lzw/ Unisys web site].&lt;br /&gt;
&lt;br /&gt;
To use these formats, you must&lt;br /&gt;
&lt;br /&gt;
# link the application with the libkimgio library&lt;br /&gt;
# Include the  &amp;lt;nowiki&amp;gt;#include &amp;lt;kimgio.h&amp;gt;&amp;lt;/nowiki&amp;gt; header file.&lt;br /&gt;
# call kimgioRegister() once, somewhere in your code before you load an image.&lt;br /&gt;
&lt;br /&gt;
===Writing handlers===&lt;br /&gt;
&lt;br /&gt;
Please read the documentation for the [http://doc.trolltech.com/qimageio.html QImageIO] class in the Qt documentation.&lt;br /&gt;
&lt;br /&gt;
# When writing handlers, there is a function naming convention; suppose, for example, we were writing PNG read and write handlers, we would name them&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
 void kimgio_png_read ( QImageIO * );&lt;br /&gt;
 void kimgio_png_write( QImageIO * );&lt;br /&gt;
 i.e.  &lt;br /&gt;
 &lt;br /&gt;
 kimgio_&amp;lt;format&amp;gt;_&amp;lt;read/write&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This should reduce the chance of identifier clashes with other code.&lt;br /&gt;
# If you only have either a reader or the writer for a particular format, don't use NULL in QImageIO::defineIOHandler. Instead, write a stub function for the unimplemented handler which displays a message on standard output. This prevents kimgio-using programs dumping core when attempting to call the unimplemented handler.&lt;br /&gt;
&lt;br /&gt;
==QImage==&lt;br /&gt;
&lt;br /&gt;
Qt's QImage class provides a hardware independent image representation class for the programmer. It can load and save files and allows - contrary to a QPixmap - direct access to the image data. This is useful for direct pixel based image manipulation.&lt;br /&gt;
&lt;br /&gt;
The QImage class has already some useful builtin functions like color depth conversion, smooth scaling, mirroring an image, painting text strings into it and also some other stuff. Be sure to read the [http://doc.trolltech.com/qimage.html QImage documentation] for more details.&lt;br /&gt;
&lt;br /&gt;
There are '''slow''' functions to convert between a QPixmap and QImage. They should be avoided especially for large images if possible. They're slow because the image data might need to be converted in depth and byte order and need to be transferred over a possibly slow network connection to the X server.&lt;br /&gt;
&lt;br /&gt;
==QMovie==&lt;br /&gt;
&lt;br /&gt;
Qt's QMovie class provides incrementally loading an image or an image animation, signalling as it progresses.&lt;br /&gt;
&lt;br /&gt;
A QMovie provides a QPixmap as the framePixmap(), and connections can be made via connectResize() and connectUpdate() to receive notification of size and pixmap changes. All decoding is driven by the normal event processing mechanisms, so make sure that you regularly return to the X11 event loop to make the animation not look ugly. The simplest way to display a QMovie, is to use a QLabel and QLabel::setMovie().&lt;br /&gt;
&lt;br /&gt;
The movie begins playing as soon as the QMovie is created (actually, once control returns to the event loop). When the last frame in the movie has been played, it may loop back to the start if such looping is defined in the input source.&lt;br /&gt;
&lt;br /&gt;
QMovie objects are explicitly shared. This means that a QMovie copied from another QMovie will be displaying the same frame at all times. If one shared movie pauses, all pause. To make independent movies, they must be constructed separately.&lt;br /&gt;
&lt;br /&gt;
The set of data formats supported by QMovie is determined by the decoder factories which have been installed, and the format of the input is determined as the input is decoded.&lt;br /&gt;
&lt;br /&gt;
QMovie's animations can be loaded from animated GIF files only if the gif support has been compiled in Qt. See the section about Kimgio above for more information.&lt;br /&gt;
&lt;br /&gt;
QMovie doesn't yet support the MNG format, that is the animated &amp;quot;variant&amp;quot; of PNG. However, Troll Tech has implemented a very nice and far superiour add-on to PNG as an replacement, which is unfortunately not yet standardized. However, they're working on adding it to the PNG standard and we all hope that they will succeed.&lt;br /&gt;
&lt;br /&gt;
The animated, well compressed PNG animation is supported by the yet experimental [http://doc.trolltech.com/qpngimagepacker.html QPNGImagePacker] class. The resulting PNG files are far better compressed than the animated GIF equivalents, because in every frames there is only the &amp;quot;difference&amp;quot; to the previous frame is stored. This is done by using transparency in the parts of the frame that hasn't changed.&lt;br /&gt;
&lt;br /&gt;
It is currently only recommended to use the non-standardized PNG animations if you fully control the creation and loading of these images, i.e. the user doesn't need to manipulate the images with other programs for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that currently the animated PNG files are only supported if Qt was linked statically with it's own distributed libpng. This is done by default. It will not work with the standard libpng that may be part of your system, as it uses a non-standardized extension.&lt;br /&gt;
&lt;br /&gt;
==KPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KPixmap inherits QPixmap, so it can be used as a compatible drop-in replacement for QPixmap. It has become a little bit obsolete in my opinion, but it still provides some nice features over [http://doc.trolltech.com/qpixmap.html QPixmap].&lt;br /&gt;
&lt;br /&gt;
KPixmap provides an easier and probably a little bit faster dithering management and conversion code. It has two new color modes, WebColor and LowColor, applicable to 8bpp displays.&lt;br /&gt;
&lt;br /&gt;
In WebColor mode all images are dithered to the Netscape palette, even when they have their own color table. WebColor is the default mode for KPixmap so that standard applications can share the Netscape palette across the desktop.&lt;br /&gt;
&lt;br /&gt;
In LowColor mode images are checked to see if their color table matches the KDE icon palette. If the color tables do not match, the images are dithered to a minimal 3x3x3 color cube. LowColor mode can be used to load icons, background images etc. so that components of the desktop which are always present use no more than 40 colors.&lt;br /&gt;
&lt;br /&gt;
It can also check if the color table of an image matches the Icon (KPixmap) palette or not. An image with one color not found in the Icon palette is considered to make a match, since this extra color may be a transparent background.&lt;br /&gt;
&lt;br /&gt;
==KSharedPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap is a very cool new class that is now used in KDE's core applications. It enables sharing of pixmaps between different programs. This is currently used to share the pixmap that is set by kdesktop, the desktop management and wallpaper painting program of KDE, between kdesktop and konsole which might use it to implement the pseudo transparency feature.&lt;br /&gt;
&lt;br /&gt;
A shared pixmap is a pixmap that resides only once in the X server. Every shared pixmap is referenced by an ID string, which has to be globally unique (unique among all X clients).&lt;br /&gt;
&lt;br /&gt;
You make a pixmap accessible to other X client by publishing it, using publish().&lt;br /&gt;
&lt;br /&gt;
Normally, if an X client exits, all its resources (including pixmaps) are deleted. This might give undesireable effects when other clients are using that pixmap. If you want to keep the pixmaps around, use setKeepResources(). This will keep _all_ this client's X recources in the server until it resets so don't use without thought.&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap inherits of course KPixmap, so it can be used wherever a KPixmap or a QPixmap can be used.&lt;br /&gt;
&lt;br /&gt;
==KPixmapEffects==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdeui)&lt;br /&gt;
&lt;br /&gt;
Did you ever see breathtaking gradient effects i.e. in popup menues of other window managers? Now you don't need to miss them any longer with KDE! KDE developers have implemented a wide variety of QPixmap based effects. As they're based on QPixmaps, they're normally hardware-accelerated by your graphics card and therefore bleeding fast.&lt;br /&gt;
&lt;br /&gt;
KPixmapEffects supports a wide variety of gradient effects including&lt;br /&gt;
&lt;br /&gt;
* VerticalGradient&lt;br /&gt;
* HorizontalGradient&lt;br /&gt;
* DiagonalGradient&lt;br /&gt;
* CrossDiagonalGradient&lt;br /&gt;
* PyramidGradient&lt;br /&gt;
* RectangleGradient&lt;br /&gt;
* PipeCrossGradient&lt;br /&gt;
* EllipticGradient&lt;br /&gt;
&lt;br /&gt;
both in a &amp;quot;balanced&amp;quot; and in a &amp;quot;unbalanced&amp;quot; variant. As an image helps more than thousand words, you'll see some samples of them here:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Balanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:balancedgradient.png|balanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Unbalanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:unbalancedgradient.png|unbalanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Additional effects include changing the intensity of pixmaps, providing blend effects, creating pattered &amp;quot;images&amp;quot;, or &amp;quot;flattening&amp;quot; as well as fading. Be sure you don't miss them!&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation</id>
		<title>Development/Architecture/KDE3/Imaging and Animation</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation"/>
				<updated>2007-01-12T21:09:29Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Writing handlers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==KDE Image I/O library kimgio==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kimgio)&lt;br /&gt;
&lt;br /&gt;
===Reading and writing images===&lt;br /&gt;
&lt;br /&gt;
This library allows applications that use the Qt library to read and write images in extra formats. Current formats include:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! format&lt;br /&gt;
! read&lt;br /&gt;
! write&lt;br /&gt;
|-&lt;br /&gt;
| JPEG&lt;br /&gt;
| X&lt;br /&gt;
| if QImgio/libjpeg is installed&lt;br /&gt;
|-&lt;br /&gt;
| JPEG 2000&lt;br /&gt;
|&lt;br /&gt;
if [http://www.ece.uvic.ca/~mdadams/jasper/ JasPer] is installed&lt;br /&gt;
|-&lt;br /&gt;
| XV&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| EPS&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| NETPBM&lt;br /&gt;
| incomplete&lt;br /&gt;
|-&lt;br /&gt;
| TIFF&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| KRL&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNG (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| BMP (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| XBM (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PBM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| GIF&amp;lt;sup&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&amp;lt;/sup&amp;gt; (87 &amp;amp; 89a) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Due to patent reasons, GIF support isn't compiled in Qt by default. You need to enable it with &amp;lt;tt&amp;gt;./configure -gif&amp;lt;/tt&amp;gt; when compiling Qt.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that this is only legal if you've got a license from Unisys or don't live in a country where Unisys holds a patent on the LZW compression. Countries in that Unisys holds a patent include Canada, Japan, the USA, France, Germany, Italy and the UK. There is more information about that topic on the [http://www.unisys.com/unisys/lzw/ Unisys web site].&lt;br /&gt;
&lt;br /&gt;
To use these formats, you must&lt;br /&gt;
&lt;br /&gt;
# link the application with the libkimgio library&lt;br /&gt;
# Include the  &amp;lt;nowiki&amp;gt;#include &amp;lt;kimgio.h&amp;gt;&amp;lt;/nowiki&amp;gt; header file.&lt;br /&gt;
# call kimgioRegister() once, somewhere in your code before you load an image.&lt;br /&gt;
&lt;br /&gt;
===Writing handlers===&lt;br /&gt;
&lt;br /&gt;
Please read the documentation for the [http://doc.trolltech.com/qimageio.html QImageIO] class in the Qt documentation.&lt;br /&gt;
&lt;br /&gt;
# When writing handlers, there is a function naming convention; suppose, for example, we were writing PNG read and write handlers, we would name them&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
 void kimgio_png_read ( QImageIO * );&lt;br /&gt;
 void kimgio_png_write( QImageIO * );&lt;br /&gt;
 i.e.  &lt;br /&gt;
 &lt;br /&gt;
 kimgio_&amp;lt;format&amp;gt;_&amp;lt;read/write&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This should reduce the chance of identifier clashes with other code.&lt;br /&gt;
# If you only have either a reader or the writer for a particular format, don't use NULL in QImageIO::defineIOHandler. Instead, write a stub function for the unimplemented handler which displays a message on standard output. This prevents kimgio-using programs dumping core when attempting to call the unimplemented handler.&lt;br /&gt;
&lt;br /&gt;
==QImage==&lt;br /&gt;
&lt;br /&gt;
Qt's QImage class provides a hardware independent image representation class for the programmer. It can load and save files and allows - contrary to a QPixmap - direct access to the image data. This is useful for direct pixel based image manipulation.&lt;br /&gt;
&lt;br /&gt;
The QImage class has already some useful builtin functions like color depth conversion, smooth scaling, mirroring an image, painting text strings into it and also some other stuff. Be sure to read the [http://doc.trolltech.com/qimage.html QImage documentation] for more details.&lt;br /&gt;
&lt;br /&gt;
There are '''slow''' functions to convert between a QPixmap and QImage. They should be avoided especially for large images if possible. They're slow because the image data might need to be converted in depth and byte order and need to be transferred over a possibly slow network connection to the X server.&lt;br /&gt;
&lt;br /&gt;
==QMovie==&lt;br /&gt;
&lt;br /&gt;
Qt's QMovie class provides incrementally loading an image or an image animation, signalling as it progresses.&lt;br /&gt;
&lt;br /&gt;
A QMovie provides a QPixmap as the framePixmap(), and connections can be made via connectResize() and connectUpdate() to receive notification of size and pixmap changes. All decoding is driven by the normal event processing mechanisms, so make sure that you regularly return to the X11 event loop to make the animation not look ugly. The simplest way to display a QMovie, is to use a QLabel and QLabel::setMovie().&lt;br /&gt;
&lt;br /&gt;
The movie begins playing as soon as the QMovie is created (actually, once control returns to the event loop). When the last frame in the movie has been played, it may loop back to the start if such looping is defined in the input source.&lt;br /&gt;
&lt;br /&gt;
QMovie objects are explicitly shared. This means that a QMovie copied from another QMovie will be displaying the same frame at all times. If one shared movie pauses, all pause. To make independent movies, they must be constructed separately.&lt;br /&gt;
&lt;br /&gt;
The set of data formats supported by QMovie is determined by the decoder factories which have been installed, and the format of the input is determined as the input is decoded.&lt;br /&gt;
&lt;br /&gt;
QMovie's animations can be loaded from animated GIF files only if the gif support has been compiled in Qt. See the section about Kimgio above for more information.&lt;br /&gt;
&lt;br /&gt;
QMovie doesn't yet support the MNG format, that is the animated &amp;quot;variant&amp;quot; of PNG. However, Troll Tech has implemented a very nice and far superiour add-on to PNG as an replacement, which is unfortunately not yet standardized. However, they're working on adding it to the PNG standard and we all hope that they will succeed.&lt;br /&gt;
&lt;br /&gt;
The animated, well compressed PNG animation is supported by the yet experimental [http://doc.trolltech.com/qpngimagepacker.html QPNGImagePacker] class. The resulting PNG files are far better compressed than the animated GIF equivalents, because in every frames there is only the &amp;quot;difference&amp;quot; to the previous frame is stored. This is done by using transparency in the parts of the frame that hasn't changed.&lt;br /&gt;
&lt;br /&gt;
It is currently only recommended to use the non-standardized PNG animations if you fully control the creation and loading of these images, i.e. the user doesn't need to manipulate the images with other programs for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that currently the animated PNG files are only supported if Qt was linked statically with it's own distributed libpng. This is done by default. It will not work with the standard libpng that may be part of your system, as it uses a non-standardized extension.&lt;br /&gt;
&lt;br /&gt;
==KPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KPixmap inherits QPixmap, so it can be used as a compatible drop-in replacement for QPixmap. It has become a little bit obsolete in my opinion, but it still provides some nice features over [http://doc.trolltech.com/qpixmap.html QPixmap].&lt;br /&gt;
&lt;br /&gt;
KPixmap provides an easier and probably a little bit faster dithering management and conversion code. It has two new color modes, WebColor and LowColor, applicable to 8bpp displays.&lt;br /&gt;
&lt;br /&gt;
In WebColor mode all images are dithered to the Netscape palette, even when they have their own color table. WebColor is the default mode for KPixmap so that standard applications can share the Netscape palette across the desktop.&lt;br /&gt;
&lt;br /&gt;
In LowColor mode images are checked to see if their color table matches the KDE icon palette. If the color tables do not match, the images are dithered to a minimal 3x3x3 color cube. LowColor mode can be used to load icons, background images etc. so that components of the desktop which are always present use no more than 40 colors.&lt;br /&gt;
&lt;br /&gt;
It can also check if the color table of an image matches the Icon (KPixmap) palette or not. An image with one color not found in the Icon palette is considered to make a match, since this extra color may be a transparent background.&lt;br /&gt;
&lt;br /&gt;
==KSharedPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap is a very cool new class that is now used in KDE's core applications. It enables sharing of pixmaps between different programs. This is currently used to share the pixmap that is set by kdesktop, the desktop management and wallpaper painting program of KDE, between kdesktop and konsole which might use it to implement the pseudo transparency feature.&lt;br /&gt;
&lt;br /&gt;
A shared pixmap is a pixmap that resides only once in the X server. Every shared pixmap is referenced by an ID string, which has to be globally unique (unique among all X clients).&lt;br /&gt;
&lt;br /&gt;
You make a pixmap accessible to other X client by publishing it, using publish().&lt;br /&gt;
&lt;br /&gt;
Normally, if an X client exits, all its resources (including pixmaps) are deleted. This might give undesireable effects when other clients are using that pixmap. If you want to keep the pixmaps around, use setKeepResources(). This will keep _all_ this client's X recources in the server until it resets so don't use without thought.&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap inherits of course KPixmap, so it can be used wherever a KPixmap or a QPixmap can be used.&lt;br /&gt;
&lt;br /&gt;
==KPixmapEffects==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdeui)&lt;br /&gt;
&lt;br /&gt;
Did you ever see breathtaking gradient effects i.e. in popup menues of other window managers? Now you don't need to miss them any longer with KDE! KDE developers have implemented a wide variety of QPixmap based effects. As they're based on QPixmaps, they're normally hardware-accelerated by your graphics card and therefore bleeding fast.&lt;br /&gt;
&lt;br /&gt;
KPixmapEffects supports a wide variety of gradient effects including&lt;br /&gt;
&lt;br /&gt;
* VerticalGradient&lt;br /&gt;
* HorizontalGradient&lt;br /&gt;
* DiagonalGradient&lt;br /&gt;
* CrossDiagonalGradient&lt;br /&gt;
* PyramidGradient&lt;br /&gt;
* RectangleGradient&lt;br /&gt;
* PipeCrossGradient&lt;br /&gt;
* EllipticGradient&lt;br /&gt;
&lt;br /&gt;
both in a &amp;quot;balanced&amp;quot; and in a &amp;quot;unbalanced&amp;quot; variant. As an image helps more than thousand words, you'll see some samples of them here:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Balanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:balancedgradient.png|balanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Unbalanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:unbalancedgradient.png|unbalanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Additional effects include changing the intensity of pixmaps, providing blend effects, creating pattered &amp;quot;images&amp;quot;, or &amp;quot;flattening&amp;quot; as well as fading. Be sure you don't miss them!&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation</id>
		<title>Development/Architecture/KDE3/Imaging and Animation</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation"/>
				<updated>2007-01-12T21:02:41Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Writing handlers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==KDE Image I/O library kimgio==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kimgio)&lt;br /&gt;
&lt;br /&gt;
===Reading and writing images===&lt;br /&gt;
&lt;br /&gt;
This library allows applications that use the Qt library to read and write images in extra formats. Current formats include:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! format&lt;br /&gt;
! read&lt;br /&gt;
! write&lt;br /&gt;
|-&lt;br /&gt;
| JPEG&lt;br /&gt;
| X&lt;br /&gt;
| if QImgio/libjpeg is installed&lt;br /&gt;
|-&lt;br /&gt;
| JPEG 2000&lt;br /&gt;
|&lt;br /&gt;
if [http://www.ece.uvic.ca/~mdadams/jasper/ JasPer] is installed&lt;br /&gt;
|-&lt;br /&gt;
| XV&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| EPS&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| NETPBM&lt;br /&gt;
| incomplete&lt;br /&gt;
|-&lt;br /&gt;
| TIFF&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| KRL&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNG (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| BMP (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| XBM (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PBM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| GIF&amp;lt;sup&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&amp;lt;/sup&amp;gt; (87 &amp;amp; 89a) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Due to patent reasons, GIF support isn't compiled in Qt by default. You need to enable it with &amp;lt;tt&amp;gt;./configure -gif&amp;lt;/tt&amp;gt; when compiling Qt.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that this is only legal if you've got a license from Unisys or don't live in a country where Unisys holds a patent on the LZW compression. Countries in that Unisys holds a patent include Canada, Japan, the USA, France, Germany, Italy and the UK. There is more information about that topic on the [http://www.unisys.com/unisys/lzw/ Unisys web site].&lt;br /&gt;
&lt;br /&gt;
To use these formats, you must&lt;br /&gt;
&lt;br /&gt;
# link the application with the libkimgio library&lt;br /&gt;
# Include the  &amp;lt;nowiki&amp;gt;#include &amp;lt;kimgio.h&amp;gt;&amp;lt;/nowiki&amp;gt; header file.&lt;br /&gt;
# call kimgioRegister() once, somewhere in your code before you load an image.&lt;br /&gt;
&lt;br /&gt;
===Writing handlers===&lt;br /&gt;
&lt;br /&gt;
Please read the documentation for the [http://doc.trolltech.com/qimageio.html QImageIO] class in the Qt documentation.&lt;br /&gt;
&lt;br /&gt;
# When writing handlers, there is a function naming convention; suppose, for example, we were writing PNG read and write handlers, we would name them  &lt;br /&gt;
 &lt;br /&gt;
 void kimgio_png_read ( QImageIO * );&lt;br /&gt;
 void kimgio_png_write( QImageIO * );&lt;br /&gt;
 i.e.  &lt;br /&gt;
 &lt;br /&gt;
 kimgio_&amp;lt;format&amp;gt;_&amp;lt;read/write&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This should reduce the chance of identifier clashes with other code.&lt;br /&gt;
# If you only have either a reader or the writer for a particular format, don't use NULL in QImageIO::defineIOHandler. Instead, write a stub function for the unimplemented handler which displays a message on standard output. This prevents kimgio-using programs dumping core when attempting to call the unimplemented handler.&lt;br /&gt;
&lt;br /&gt;
==QImage==&lt;br /&gt;
&lt;br /&gt;
Qt's QImage class provides a hardware independent image representation class for the programmer. It can load and save files and allows - contrary to a QPixmap - direct access to the image data. This is useful for direct pixel based image manipulation.&lt;br /&gt;
&lt;br /&gt;
The QImage class has already some useful builtin functions like color depth conversion, smooth scaling, mirroring an image, painting text strings into it and also some other stuff. Be sure to read the [http://doc.trolltech.com/qimage.html QImage documentation] for more details.&lt;br /&gt;
&lt;br /&gt;
There are '''slow''' functions to convert between a QPixmap and QImage. They should be avoided especially for large images if possible. They're slow because the image data might need to be converted in depth and byte order and need to be transferred over a possibly slow network connection to the X server.&lt;br /&gt;
&lt;br /&gt;
==QMovie==&lt;br /&gt;
&lt;br /&gt;
Qt's QMovie class provides incrementally loading an image or an image animation, signalling as it progresses.&lt;br /&gt;
&lt;br /&gt;
A QMovie provides a QPixmap as the framePixmap(), and connections can be made via connectResize() and connectUpdate() to receive notification of size and pixmap changes. All decoding is driven by the normal event processing mechanisms, so make sure that you regularly return to the X11 event loop to make the animation not look ugly. The simplest way to display a QMovie, is to use a QLabel and QLabel::setMovie().&lt;br /&gt;
&lt;br /&gt;
The movie begins playing as soon as the QMovie is created (actually, once control returns to the event loop). When the last frame in the movie has been played, it may loop back to the start if such looping is defined in the input source.&lt;br /&gt;
&lt;br /&gt;
QMovie objects are explicitly shared. This means that a QMovie copied from another QMovie will be displaying the same frame at all times. If one shared movie pauses, all pause. To make independent movies, they must be constructed separately.&lt;br /&gt;
&lt;br /&gt;
The set of data formats supported by QMovie is determined by the decoder factories which have been installed, and the format of the input is determined as the input is decoded.&lt;br /&gt;
&lt;br /&gt;
QMovie's animations can be loaded from animated GIF files only if the gif support has been compiled in Qt. See the section about Kimgio above for more information.&lt;br /&gt;
&lt;br /&gt;
QMovie doesn't yet support the MNG format, that is the animated &amp;quot;variant&amp;quot; of PNG. However, Troll Tech has implemented a very nice and far superiour add-on to PNG as an replacement, which is unfortunately not yet standardized. However, they're working on adding it to the PNG standard and we all hope that they will succeed.&lt;br /&gt;
&lt;br /&gt;
The animated, well compressed PNG animation is supported by the yet experimental [http://doc.trolltech.com/qpngimagepacker.html QPNGImagePacker] class. The resulting PNG files are far better compressed than the animated GIF equivalents, because in every frames there is only the &amp;quot;difference&amp;quot; to the previous frame is stored. This is done by using transparency in the parts of the frame that hasn't changed.&lt;br /&gt;
&lt;br /&gt;
It is currently only recommended to use the non-standardized PNG animations if you fully control the creation and loading of these images, i.e. the user doesn't need to manipulate the images with other programs for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that currently the animated PNG files are only supported if Qt was linked statically with it's own distributed libpng. This is done by default. It will not work with the standard libpng that may be part of your system, as it uses a non-standardized extension.&lt;br /&gt;
&lt;br /&gt;
==KPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KPixmap inherits QPixmap, so it can be used as a compatible drop-in replacement for QPixmap. It has become a little bit obsolete in my opinion, but it still provides some nice features over [http://doc.trolltech.com/qpixmap.html QPixmap].&lt;br /&gt;
&lt;br /&gt;
KPixmap provides an easier and probably a little bit faster dithering management and conversion code. It has two new color modes, WebColor and LowColor, applicable to 8bpp displays.&lt;br /&gt;
&lt;br /&gt;
In WebColor mode all images are dithered to the Netscape palette, even when they have their own color table. WebColor is the default mode for KPixmap so that standard applications can share the Netscape palette across the desktop.&lt;br /&gt;
&lt;br /&gt;
In LowColor mode images are checked to see if their color table matches the KDE icon palette. If the color tables do not match, the images are dithered to a minimal 3x3x3 color cube. LowColor mode can be used to load icons, background images etc. so that components of the desktop which are always present use no more than 40 colors.&lt;br /&gt;
&lt;br /&gt;
It can also check if the color table of an image matches the Icon (KPixmap) palette or not. An image with one color not found in the Icon palette is considered to make a match, since this extra color may be a transparent background.&lt;br /&gt;
&lt;br /&gt;
==KSharedPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap is a very cool new class that is now used in KDE's core applications. It enables sharing of pixmaps between different programs. This is currently used to share the pixmap that is set by kdesktop, the desktop management and wallpaper painting program of KDE, between kdesktop and konsole which might use it to implement the pseudo transparency feature.&lt;br /&gt;
&lt;br /&gt;
A shared pixmap is a pixmap that resides only once in the X server. Every shared pixmap is referenced by an ID string, which has to be globally unique (unique among all X clients).&lt;br /&gt;
&lt;br /&gt;
You make a pixmap accessible to other X client by publishing it, using publish().&lt;br /&gt;
&lt;br /&gt;
Normally, if an X client exits, all its resources (including pixmaps) are deleted. This might give undesireable effects when other clients are using that pixmap. If you want to keep the pixmaps around, use setKeepResources(). This will keep _all_ this client's X recources in the server until it resets so don't use without thought.&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap inherits of course KPixmap, so it can be used wherever a KPixmap or a QPixmap can be used.&lt;br /&gt;
&lt;br /&gt;
==KPixmapEffects==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdeui)&lt;br /&gt;
&lt;br /&gt;
Did you ever see breathtaking gradient effects i.e. in popup menues of other window managers? Now you don't need to miss them any longer with KDE! KDE developers have implemented a wide variety of QPixmap based effects. As they're based on QPixmaps, they're normally hardware-accelerated by your graphics card and therefore bleeding fast.&lt;br /&gt;
&lt;br /&gt;
KPixmapEffects supports a wide variety of gradient effects including&lt;br /&gt;
&lt;br /&gt;
* VerticalGradient&lt;br /&gt;
* HorizontalGradient&lt;br /&gt;
* DiagonalGradient&lt;br /&gt;
* CrossDiagonalGradient&lt;br /&gt;
* PyramidGradient&lt;br /&gt;
* RectangleGradient&lt;br /&gt;
* PipeCrossGradient&lt;br /&gt;
* EllipticGradient&lt;br /&gt;
&lt;br /&gt;
both in a &amp;quot;balanced&amp;quot; and in a &amp;quot;unbalanced&amp;quot; variant. As an image helps more than thousand words, you'll see some samples of them here:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Balanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:balancedgradient.png|balanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Unbalanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:unbalancedgradient.png|unbalanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Additional effects include changing the intensity of pixmaps, providing blend effects, creating pattered &amp;quot;images&amp;quot;, or &amp;quot;flattening&amp;quot; as well as fading. Be sure you don't miss them!&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation</id>
		<title>Development/Architecture/KDE3/Imaging and Animation</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/Imaging_and_Animation"/>
				<updated>2007-01-12T21:01:21Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==KDE Image I/O library kimgio==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kimgio)&lt;br /&gt;
&lt;br /&gt;
===Reading and writing images===&lt;br /&gt;
&lt;br /&gt;
This library allows applications that use the Qt library to read and write images in extra formats. Current formats include:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! format&lt;br /&gt;
! read&lt;br /&gt;
! write&lt;br /&gt;
|-&lt;br /&gt;
| JPEG&lt;br /&gt;
| X&lt;br /&gt;
| if QImgio/libjpeg is installed&lt;br /&gt;
|-&lt;br /&gt;
| JPEG 2000&lt;br /&gt;
|&lt;br /&gt;
if [http://www.ece.uvic.ca/~mdadams/jasper/ JasPer] is installed&lt;br /&gt;
|-&lt;br /&gt;
| XV&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| EPS&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| NETPBM&lt;br /&gt;
| incomplete&lt;br /&gt;
|-&lt;br /&gt;
| TIFF&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| KRL&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNG (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| BMP (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| XBM (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PNM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| PBM (several variants) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|-&lt;br /&gt;
| GIF&amp;lt;sup&amp;gt;&amp;lt;nowiki&amp;gt;*&amp;lt;/nowiki&amp;gt;&amp;lt;/sup&amp;gt; (87 &amp;amp; 89a) (Qt)&lt;br /&gt;
| X&lt;br /&gt;
| X&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
* Due to patent reasons, GIF support isn't compiled in Qt by default. You need to enable it with &amp;lt;tt&amp;gt;./configure -gif&amp;lt;/tt&amp;gt; when compiling Qt.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that this is only legal if you've got a license from Unisys or don't live in a country where Unisys holds a patent on the LZW compression. Countries in that Unisys holds a patent include Canada, Japan, the USA, France, Germany, Italy and the UK. There is more information about that topic on the [http://www.unisys.com/unisys/lzw/ Unisys web site].&lt;br /&gt;
&lt;br /&gt;
To use these formats, you must&lt;br /&gt;
&lt;br /&gt;
# link the application with the libkimgio library&lt;br /&gt;
# Include the  &amp;lt;nowiki&amp;gt;#include &amp;lt;kimgio.h&amp;gt;&amp;lt;/nowiki&amp;gt; header file.&lt;br /&gt;
# call kimgioRegister() once, somewhere in your code before you load an image.&lt;br /&gt;
&lt;br /&gt;
===Writing handlers===&lt;br /&gt;
&lt;br /&gt;
Please read the documentation for the [http://doc.trolltech.com/qimageio.html QImageIO] class in the Qt documentation.&lt;br /&gt;
&lt;br /&gt;
# When writing handlers, there is a function naming convention; suppose, for example, we were writing PNG read and write handlers, we would name them  &lt;br /&gt;
 &lt;br /&gt;
 void kimgio_png_read ( QImageIO * );&lt;br /&gt;
 void kimgio_png_write( QImageIO * );&lt;br /&gt;
 i.e.  &lt;br /&gt;
 &lt;br /&gt;
 kimgio_&amp;lt;format&amp;gt;_&amp;lt;read/write&amp;gt;&lt;br /&gt;
 &lt;br /&gt;
This should reduce the chance of identifier clashes with other code.&lt;br /&gt;
# If you only have either a reader or the writer for a particular format, don't use NULL in QImageIO::defineIOHandler. Instead, write a stub function for the unimplemented handler which displays a message on standard output. This prevents kimgio-using programs dumping core when attempting to call the unimplemented handler.&lt;br /&gt;
&lt;br /&gt;
[mailto:taj@kde.org Sirtaj Singh Kang].&lt;br /&gt;
&lt;br /&gt;
==QImage==&lt;br /&gt;
&lt;br /&gt;
Qt's QImage class provides a hardware independent image representation class for the programmer. It can load and save files and allows - contrary to a QPixmap - direct access to the image data. This is useful for direct pixel based image manipulation.&lt;br /&gt;
&lt;br /&gt;
The QImage class has already some useful builtin functions like color depth conversion, smooth scaling, mirroring an image, painting text strings into it and also some other stuff. Be sure to read the [http://doc.trolltech.com/qimage.html QImage documentation] for more details.&lt;br /&gt;
&lt;br /&gt;
There are '''slow''' functions to convert between a QPixmap and QImage. They should be avoided especially for large images if possible. They're slow because the image data might need to be converted in depth and byte order and need to be transferred over a possibly slow network connection to the X server.&lt;br /&gt;
&lt;br /&gt;
==QMovie==&lt;br /&gt;
&lt;br /&gt;
Qt's QMovie class provides incrementally loading an image or an image animation, signalling as it progresses.&lt;br /&gt;
&lt;br /&gt;
A QMovie provides a QPixmap as the framePixmap(), and connections can be made via connectResize() and connectUpdate() to receive notification of size and pixmap changes. All decoding is driven by the normal event processing mechanisms, so make sure that you regularly return to the X11 event loop to make the animation not look ugly. The simplest way to display a QMovie, is to use a QLabel and QLabel::setMovie().&lt;br /&gt;
&lt;br /&gt;
The movie begins playing as soon as the QMovie is created (actually, once control returns to the event loop). When the last frame in the movie has been played, it may loop back to the start if such looping is defined in the input source.&lt;br /&gt;
&lt;br /&gt;
QMovie objects are explicitly shared. This means that a QMovie copied from another QMovie will be displaying the same frame at all times. If one shared movie pauses, all pause. To make independent movies, they must be constructed separately.&lt;br /&gt;
&lt;br /&gt;
The set of data formats supported by QMovie is determined by the decoder factories which have been installed, and the format of the input is determined as the input is decoded.&lt;br /&gt;
&lt;br /&gt;
QMovie's animations can be loaded from animated GIF files only if the gif support has been compiled in Qt. See the section about Kimgio above for more information.&lt;br /&gt;
&lt;br /&gt;
QMovie doesn't yet support the MNG format, that is the animated &amp;quot;variant&amp;quot; of PNG. However, Troll Tech has implemented a very nice and far superiour add-on to PNG as an replacement, which is unfortunately not yet standardized. However, they're working on adding it to the PNG standard and we all hope that they will succeed.&lt;br /&gt;
&lt;br /&gt;
The animated, well compressed PNG animation is supported by the yet experimental [http://doc.trolltech.com/qpngimagepacker.html QPNGImagePacker] class. The resulting PNG files are far better compressed than the animated GIF equivalents, because in every frames there is only the &amp;quot;difference&amp;quot; to the previous frame is stored. This is done by using transparency in the parts of the frame that hasn't changed.&lt;br /&gt;
&lt;br /&gt;
It is currently only recommended to use the non-standardized PNG animations if you fully control the creation and loading of these images, i.e. the user doesn't need to manipulate the images with other programs for obvious reasons.&lt;br /&gt;
&lt;br /&gt;
'''Note''' that currently the animated PNG files are only supported if Qt was linked statically with it's own distributed libpng. This is done by default. It will not work with the standard libpng that may be part of your system, as it uses a non-standardized extension.&lt;br /&gt;
&lt;br /&gt;
==KPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KPixmap inherits QPixmap, so it can be used as a compatible drop-in replacement for QPixmap. It has become a little bit obsolete in my opinion, but it still provides some nice features over [http://doc.trolltech.com/qpixmap.html QPixmap].&lt;br /&gt;
&lt;br /&gt;
KPixmap provides an easier and probably a little bit faster dithering management and conversion code. It has two new color modes, WebColor and LowColor, applicable to 8bpp displays.&lt;br /&gt;
&lt;br /&gt;
In WebColor mode all images are dithered to the Netscape palette, even when they have their own color table. WebColor is the default mode for KPixmap so that standard applications can share the Netscape palette across the desktop.&lt;br /&gt;
&lt;br /&gt;
In LowColor mode images are checked to see if their color table matches the KDE icon palette. If the color tables do not match, the images are dithered to a minimal 3x3x3 color cube. LowColor mode can be used to load icons, background images etc. so that components of the desktop which are always present use no more than 40 colors.&lt;br /&gt;
&lt;br /&gt;
It can also check if the color table of an image matches the Icon (KPixmap) palette or not. An image with one color not found in the Icon palette is considered to make a match, since this extra color may be a transparent background.&lt;br /&gt;
&lt;br /&gt;
==KSharedPixmap==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdecore)&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap is a very cool new class that is now used in KDE's core applications. It enables sharing of pixmaps between different programs. This is currently used to share the pixmap that is set by kdesktop, the desktop management and wallpaper painting program of KDE, between kdesktop and konsole which might use it to implement the pseudo transparency feature.&lt;br /&gt;
&lt;br /&gt;
A shared pixmap is a pixmap that resides only once in the X server. Every shared pixmap is referenced by an ID string, which has to be globally unique (unique among all X clients).&lt;br /&gt;
&lt;br /&gt;
You make a pixmap accessible to other X client by publishing it, using publish().&lt;br /&gt;
&lt;br /&gt;
Normally, if an X client exits, all its resources (including pixmaps) are deleted. This might give undesireable effects when other clients are using that pixmap. If you want to keep the pixmaps around, use setKeepResources(). This will keep _all_ this client's X recources in the server until it resets so don't use without thought.&lt;br /&gt;
&lt;br /&gt;
KSharedPixmap inherits of course KPixmap, so it can be used wherever a KPixmap or a QPixmap can be used.&lt;br /&gt;
&lt;br /&gt;
==KPixmapEffects==&lt;br /&gt;
&lt;br /&gt;
 (kdelibs/kdeui)&lt;br /&gt;
&lt;br /&gt;
Did you ever see breathtaking gradient effects i.e. in popup menues of other window managers? Now you don't need to miss them any longer with KDE! KDE developers have implemented a wide variety of QPixmap based effects. As they're based on QPixmaps, they're normally hardware-accelerated by your graphics card and therefore bleeding fast.&lt;br /&gt;
&lt;br /&gt;
KPixmapEffects supports a wide variety of gradient effects including&lt;br /&gt;
&lt;br /&gt;
* VerticalGradient&lt;br /&gt;
* HorizontalGradient&lt;br /&gt;
* DiagonalGradient&lt;br /&gt;
* CrossDiagonalGradient&lt;br /&gt;
* PyramidGradient&lt;br /&gt;
* RectangleGradient&lt;br /&gt;
* PipeCrossGradient&lt;br /&gt;
* EllipticGradient&lt;br /&gt;
&lt;br /&gt;
both in a &amp;quot;balanced&amp;quot; and in a &amp;quot;unbalanced&amp;quot; variant. As an image helps more than thousand words, you'll see some samples of them here:&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Balanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:balancedgradient.png|balanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;4&amp;quot; bgcolor=&amp;quot;#F0F0FF&amp;quot;&lt;br /&gt;
! Unbalanced Gradients&lt;br /&gt;
|-&lt;br /&gt;
|&lt;br /&gt;
[[Image:unbalancedgradient.png|unbalanced gradient picture]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Additional effects include changing the intensity of pixmaps, providing blend effects, creating pattered &amp;quot;images&amp;quot;, or &amp;quot;flattening&amp;quot; as well as fading. Be sure you don't miss them!&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture</id>
		<title>Development/Architecture</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture"/>
				<updated>2007-01-12T20:42:57Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Design Documents */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following pages contain documentation about KDE's design and architecture in detail. They do not replace other documentation like API Documentation, tutorials, howtos and standards, see the [[Development|development portal]] for further information.&lt;br /&gt;
&lt;br /&gt;
For a better understanding it might help to be familiar with Trolltech's&amp;amp;trade; excellent [http://doc.trolltech.com/3.3/index.html Qt 3.3] or [http://doc.trolltech.com/4.2/index.html Qt 4.2] documentation and their [http://www.trolltech.com/developer/ Developer Pages].&lt;br /&gt;
&lt;br /&gt;
== Design Documents ==&lt;br /&gt;
; [[/KDE 4 Architecture|KDE 4 Architecture Overview]]&lt;br /&gt;
: An overview of the KDE 4 architecture, including discussions of common techniques, library classes, and general development issues.  This is for ''KDE 4.0''.&lt;br /&gt;
&lt;br /&gt;
; [[/KDE 3 Architecture|KDE 3 Architecture Overview]] [http://developer.kde.org/documentation/library/kdeqt/kde3arch/ (Original)]&lt;br /&gt;
: An overview of the KDE 3 architecture, including discussions of common techniques, library classes, and general development issues. This is for ''KDE 3.0''.&lt;br /&gt;
&lt;br /&gt;
; [[/KDE 2 Architecture|KDE 2 Architecture Overview]] [http://developer.kde.org/documentation/library/kdeqt/kde2arch/ (Original)]&lt;br /&gt;
: An overview of the KDE 2 architecture, similar to the above. This is for ''KDE 2.2''.&lt;br /&gt;
&lt;br /&gt;
; [[/DCOP|DCOP]]&lt;br /&gt;
: Design documents from 1999-2000.&lt;br /&gt;
&lt;br /&gt;
; [[Development/Architecture/Binary Compatibility Issues With C++|Binary Compatibility Issues With C++]] ([http://developer.kde.org/documentation/other/binarycompatibility.html Original])&lt;br /&gt;
: A quick overview of issues with binary compatibility with C++. Keep this in mind while altering the API of kdelibs.&lt;br /&gt;
&lt;br /&gt;
; [http://developer.kde.org/documentation/design/kde/simplinux-presentation/html-800x600/index.htm The design of the K Desktop Environment]&lt;br /&gt;
: This is a presentation given at the SIMPLINUX conference in Portugal. It discusses the design of KDE and how it has changed through the different releases. You can browse the [http://developer.kde.org/documentation/design/kde/simplinux-presentation/html-800x600/index.htm slides online], or [http://developer.kde.org/documentation/design/kde/simplinux-presentation/html-800x600.tar.gz download] them in one go. There is also a [http://developer.kde.org/documentation/design/kde/simplinux-presentation/html-800x600/tsld001.htm text only version] (only a couple of the slides are really pictures, the rest are fine as text). You can also see some photos of the presentation. (Design documents from 1999)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:38:41Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is obviously private. For public or protected access, provide both a set and a get function. Example&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding new data members to classes without d-pointer === &lt;br /&gt;
&lt;br /&gt;
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits QObject, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&lt;br /&gt;
&lt;br /&gt;
The basic trick in your class implementation of class Foo is:&lt;br /&gt;
* Create a private data class FooPrivate.&lt;br /&gt;
* Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the  &amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Add a line to your destructor:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.&lt;br /&gt;
* Do not forget to add a d-pointer to your next class.&lt;br /&gt;
&lt;br /&gt;
=== Adding a reimplemented virtual function ===&lt;br /&gt;
&lt;br /&gt;
As already explained, you can safely reimplement a virtual function defined in one of the base classes only if it is safe that the programs linked with the prior version call the implementation in the base class rather than the new one. This is because the compiler sometimes calls virtual functions directly if it can determine which one to call. For example, if you have &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo(). If a newer version of the library adds B::foo(), C::foo() will call it only after a recompilation.&lt;br /&gt;
&lt;br /&gt;
Another more common example is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&lt;br /&gt;
&lt;br /&gt;
If you can't guarantee things will continue to work without a recompilation, move functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in  calling B::foo(). The only case that will not work as expected are calls to A::foo() that explicitly specify A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&lt;br /&gt;
=== Using a new class ===&lt;br /&gt;
&lt;br /&gt;
A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement class that will include also the new functionality (and that may inherit from the old class to reuse the code). This of course requires adapting and recompiling applications using the library, so it is not possible this way to fix or extend functionality of classes that are used by applications compiled against an older version of the library. However, especially with small and/or performance-critical classes it may be simpler to write them without making sure they'll be simple to extend in the future and if the need arises later write a new replacement class that will provide new features or better performance.&lt;br /&gt;
&lt;br /&gt;
=== Adding new virtual functions to leaf classes ===&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add new virtual functions to a class that should stay binary compatible and there is no class inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are in applications). In such case it's possible to add a new class inheriting from the original one that will add them. Applications using the new functionality will of course have to be modified to use the new class.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also stay binary compatible because they'd have to inherit from the new class.&lt;br /&gt;
&lt;br /&gt;
=== Using signals instead of virtual functions ===&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro and it exists in every class inherited from QObject. Therefore adding new signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be used to emulate virtual functions.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality of it. Since signals have void return value, data must be returned using arguments. As there will be only one slot connected to the signal returning data from the slot this way will work without problems. Note that with Qt4 for this to work the connection type will have to be Qt::DirectConnection.&lt;br /&gt;
&lt;br /&gt;
If an inherited class will want to re-implement the functionality of bar() it will have to provide its own slot:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary to specify barslot() again as a slot in B and that in the constructor it is necessary to first disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot() instead.&lt;br /&gt;
&lt;br /&gt;
Note: the same can be accomplished by implementing a virtual slot.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:36:14Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is obviously private. For public or protected access, provide both a set and a get function. Example&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding new data members to classes without d-pointer === &lt;br /&gt;
&lt;br /&gt;
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits QObject, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&lt;br /&gt;
&lt;br /&gt;
The basic trick in your class implementation of class Foo is:&lt;br /&gt;
* Create a private data class FooPrivate.&lt;br /&gt;
* Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the  &amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Add a line to your destructor:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.&lt;br /&gt;
* Do not forget to add a d-pointer to your next class.&lt;br /&gt;
&lt;br /&gt;
=== Adding a reimplemented virtual function ===&lt;br /&gt;
&lt;br /&gt;
As already explained, you can safely reimplement a virtual function defined in one of the base classes only if it is safe that the programs linked with the prior version call the implementation in the base class rather than the new one. This is because the compiler sometimes calls virtual functions directly if it can determine which one to call. For example, if you have &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo(). If a newer version of the library adds B::foo(), C::foo() will call it only after a recompilation.&lt;br /&gt;
&lt;br /&gt;
Another more common example is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&lt;br /&gt;
&lt;br /&gt;
If you can't guarantee things will continue to work without a recompilation, move functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in  calling B::foo(). The only case that will not work as expected are calls to A::foo() that explicitly specify A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&lt;br /&gt;
=== Using a new class ===&lt;br /&gt;
&lt;br /&gt;
A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement class that will include also the new functionality (and that may inherit from the old class to reuse the code). This of course requires adapting and recompiling applications using the library, so it is not possible this way to fix or extend functionality of classes that are used by applications compiled against an older version of the library. However, especially with small and/or performance-critical classes it may be simpler to write them without making sure they'll be simple to extend in the future and if the need arises later write a new replacement class that will provide new features or better performance.&lt;br /&gt;
&lt;br /&gt;
=== Adding new virtual functions to leaf classes ===&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add new virtual functions to a class that should stay binary compatible and there is no class inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are in applications). In such case it's possible to add a new class inheriting from the original one that will add them. Applications using the new functionality will of course have to be modified to use the new class.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also stay binary compatible because they'd have to inherit from the new class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using signals instead of virtual functions&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro&lt;br /&gt;
and it exists in every class inherited from QObject. Therefore adding new&lt;br /&gt;
signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be&lt;br /&gt;
used to emulate virtual functions.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality&lt;br /&gt;
of it. Since signals have void return value, data must be returned using arguments. As&lt;br /&gt;
there will be only one slot connected to the signal returning data from the slot this way will&lt;br /&gt;
work without problems. Note that with Qt4 for this to work the connection type will have to be&lt;br /&gt;
Qt::DirectConnection.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
If an inherited class will want to reimplement the functionality of bar() it will have to provide&lt;br /&gt;
its own slot:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary&lt;br /&gt;
to specify barslot() again as a slot in B and that in the constructor it is necessary to first&lt;br /&gt;
disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot()&lt;br /&gt;
instead.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Note: the same can be accomplished by implementing a virtual slot.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt; &amp;lt;small&amp;gt; &amp;lt;em&amp;gt;&lt;br /&gt;
Matthias Ettrich &amp;lt;a href=&amp;quot;mailto:ettrich@kde.org&amp;quot;&amp;gt;ettrich@kde.org&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Lubos Lunak &amp;lt;a href=&amp;quot;mailto:l.lunak@kde.org&amp;quot;&amp;gt;l.lunak@kde.org&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/em&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:35:35Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is obviously private. For public or protected access, provide both a set and a get function. Example&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding new data members to classes without d-pointer === &lt;br /&gt;
&lt;br /&gt;
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits QObject, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&lt;br /&gt;
&lt;br /&gt;
The basic trick in your class implementation of class Foo is:&lt;br /&gt;
* Create a private data class FooPrivate.&lt;br /&gt;
* Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the  &amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Add a line to your destructor:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.&lt;br /&gt;
* Do not forget to add a d-pointer to your next class.&lt;br /&gt;
&lt;br /&gt;
=== Adding a reimplemented virtual function ===&lt;br /&gt;
&lt;br /&gt;
As already explained, you can safely reimplement a virtual function defined in one of the base classes only if it is safe that the programs linked with the prior version call the implementation in the base class rather than the new one. This is because the compiler sometimes calls virtual functions directly if it can determine which one to call. For example, if you have &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo(). If a newer version of the library adds B::foo(), C::foo() will call it only after a recompilation.&lt;br /&gt;
&lt;br /&gt;
Another more common example is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&lt;br /&gt;
&lt;br /&gt;
If you can't guarantee things will continue to work without a recompilation, move functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in  calling B::foo(). The only case that will not work as expected are calls to A::foo() that explicitly specify A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&lt;br /&gt;
=== Using a new class ===&lt;br /&gt;
&lt;br /&gt;
A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement class that will include also the new functionality (and that may inherit from the old class to reuse the code). This of course requires adapting and recompiling applications using the library, so it is not possible this way to fix or extend functionality of classes that are used by applications compiled against an older version of the library. However, especially with small and/or performance-critical classes it may be simpler to write them without making sure they'll be simple to extend in the future and if the need arises later write a new replacement class that will provide new features or better performance.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new virtual functions to leaf classes&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add&lt;br /&gt;
new virtual functions to a class that should stay binary compatible and there is no class&lt;br /&gt;
inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are&lt;br /&gt;
in applications). In such case it's possible to add a new class inheriting from the original one&lt;br /&gt;
that will add them. Applications using the new functionality will of course have to be modified&lt;br /&gt;
to use the new class.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also&lt;br /&gt;
stay binary compatible because they'd have to inherit from the new class.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using signals instead of virtual functions&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro&lt;br /&gt;
and it exists in every class inherited from QObject. Therefore adding new&lt;br /&gt;
signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be&lt;br /&gt;
used to emulate virtual functions.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality&lt;br /&gt;
of it. Since signals have void return value, data must be returned using arguments. As&lt;br /&gt;
there will be only one slot connected to the signal returning data from the slot this way will&lt;br /&gt;
work without problems. Note that with Qt4 for this to work the connection type will have to be&lt;br /&gt;
Qt::DirectConnection.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
If an inherited class will want to reimplement the functionality of bar() it will have to provide&lt;br /&gt;
its own slot:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary&lt;br /&gt;
to specify barslot() again as a slot in B and that in the constructor it is necessary to first&lt;br /&gt;
disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot()&lt;br /&gt;
instead.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Note: the same can be accomplished by implementing a virtual slot.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt; &amp;lt;small&amp;gt; &amp;lt;em&amp;gt;&lt;br /&gt;
Matthias Ettrich &amp;lt;a href=&amp;quot;mailto:ettrich@kde.org&amp;quot;&amp;gt;ettrich@kde.org&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Lubos Lunak &amp;lt;a href=&amp;quot;mailto:l.lunak@kde.org&amp;quot;&amp;gt;l.lunak@kde.org&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/em&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:34:52Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is obviously private. For public or protected access, provide both a set and a get function. Example&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding new data members to classes without d-pointer === &lt;br /&gt;
&lt;br /&gt;
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits QObject, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&lt;br /&gt;
&lt;br /&gt;
The basic trick in your class implementation of class Foo is:&lt;br /&gt;
* Create a private data class FooPrivate.&lt;br /&gt;
* Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the  &amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Add a line to your destructor:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.&lt;br /&gt;
* Do not forget to add a d-pointer to your next class.&lt;br /&gt;
&lt;br /&gt;
=== Adding a reimplemented virtual function ===&lt;br /&gt;
&lt;br /&gt;
As already explained, you can safely reimplement a virtual function defined in one of the base classes only if it is safe that the programs linked with the prior version call the implementation in the base class rather than the new one. This is because the compiler sometimes calls virtual functions directly if it can determine which one to call. For example, if you have &lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo(). If a newer version of the library adds B::foo(), C::foo() will call it only after a recompilation.&lt;br /&gt;
&lt;br /&gt;
Another more common example is:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&lt;br /&gt;
&lt;br /&gt;
If you can't guarantee things will continue to work without a recompilation, move functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in  calling B::foo(). The only case that will not work as expected are calls to A::foo() that explicitly specify A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using a new class&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement&lt;br /&gt;
class that will include also the new functionality (and that may inherit from the old&lt;br /&gt;
class to reuse the code). This of course requires adapting and recompiling applications using&lt;br /&gt;
the library, so it is not possible this way to fix or extend functionality of classes&lt;br /&gt;
that are used by applications compiled against an older version of the library. However,&lt;br /&gt;
especially with small and/or performance-critical classes it may be simpler to write&lt;br /&gt;
them without making sure they'll be simple to extend in the future and if the need arises&lt;br /&gt;
later write a new replacement class that will provide new features or better performance.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new virtual functions to leaf classes&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add&lt;br /&gt;
new virtual functions to a class that should stay binary compatible and there is no class&lt;br /&gt;
inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are&lt;br /&gt;
in applications). In such case it's possible to add a new class inheriting from the original one&lt;br /&gt;
that will add them. Applications using the new functionality will of course have to be modified&lt;br /&gt;
to use the new class.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also&lt;br /&gt;
stay binary compatible because they'd have to inherit from the new class.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using signals instead of virtual functions&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro&lt;br /&gt;
and it exists in every class inherited from QObject. Therefore adding new&lt;br /&gt;
signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be&lt;br /&gt;
used to emulate virtual functions.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality&lt;br /&gt;
of it. Since signals have void return value, data must be returned using arguments. As&lt;br /&gt;
there will be only one slot connected to the signal returning data from the slot this way will&lt;br /&gt;
work without problems. Note that with Qt4 for this to work the connection type will have to be&lt;br /&gt;
Qt::DirectConnection.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
If an inherited class will want to reimplement the functionality of bar() it will have to provide&lt;br /&gt;
its own slot:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary&lt;br /&gt;
to specify barslot() again as a slot in B and that in the constructor it is necessary to first&lt;br /&gt;
disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot()&lt;br /&gt;
instead.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Note: the same can be accomplished by implementing a virtual slot.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt; &amp;lt;small&amp;gt; &amp;lt;em&amp;gt;&lt;br /&gt;
Matthias Ettrich &amp;lt;a href=&amp;quot;mailto:ettrich@kde.org&amp;quot;&amp;gt;ettrich@kde.org&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Lubos Lunak &amp;lt;a href=&amp;quot;mailto:l.lunak@kde.org&amp;quot;&amp;gt;l.lunak@kde.org&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/em&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:31:41Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is obviously private. For public or protected access, provide both a set and a get function. Example&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Adding new data members to classes without d-pointer === &lt;br /&gt;
&lt;br /&gt;
If you don't have free bitflags, reserved variables and no d-pointer either, but you absolutely have to add a new private member variable, there are still some possibilities left. If your class inherits QObject, you can for example place the additional data in a special child and find it by traversing over the list of children. You can access the list of children with QObject::children(). However, a fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&lt;br /&gt;
&lt;br /&gt;
The basic trick in your class implementation of class Foo is:&lt;br /&gt;
* Create a private data class FooPrivate.&lt;br /&gt;
* Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
*Note that some compilers/linkers (almost all, unfortunately) do not manage to create static objects in shared libraries. They simply forget to call the constructor. Therefore you should use the  &amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Now you can use the d-pointer in your class almost as simple as in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Add a line to your destructor:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
* Do not forget to add a BCI remark, so that the hack can be removed in the next version of the library.&lt;br /&gt;
* Do not forget to add a d-pointer to your next class.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding a reimplemented virtual function&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;As already explained, you can safely reimplement a virtual function defined&lt;br /&gt;
in one of the base classes only if it is safe that the programs linked&lt;br /&gt;
with the prior version call the implementation in the base class rather than&lt;br /&gt;
the new one. This is because the compiler sometimes calls virtual functions&lt;br /&gt;
directly if it can determine which one to call (for example if you have&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements&lt;br /&gt;
foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo().&lt;br /&gt;
If a newer version of the library adds B::foo(), C::foo() will call it only after&lt;br /&gt;
a recompilation.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Another more common example is:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;If you can't guarantee things will continue to work without a recompilation, move&lt;br /&gt;
functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in calling B::foo().&lt;br /&gt;
The only case that will not work as expected are calls to A::foo() that explicitly specify&lt;br /&gt;
A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using a new class&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement&lt;br /&gt;
class that will include also the new functionality (and that may inherit from the old&lt;br /&gt;
class to reuse the code). This of course requires adapting and recompiling applications using&lt;br /&gt;
the library, so it is not possible this way to fix or extend functionality of classes&lt;br /&gt;
that are used by applications compiled against an older version of the library. However,&lt;br /&gt;
especially with small and/or performance-critical classes it may be simpler to write&lt;br /&gt;
them without making sure they'll be simple to extend in the future and if the need arises&lt;br /&gt;
later write a new replacement class that will provide new features or better performance.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new virtual functions to leaf classes&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add&lt;br /&gt;
new virtual functions to a class that should stay binary compatible and there is no class&lt;br /&gt;
inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are&lt;br /&gt;
in applications). In such case it's possible to add a new class inheriting from the original one&lt;br /&gt;
that will add them. Applications using the new functionality will of course have to be modified&lt;br /&gt;
to use the new class.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also&lt;br /&gt;
stay binary compatible because they'd have to inherit from the new class.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using signals instead of virtual functions&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro&lt;br /&gt;
and it exists in every class inherited from QObject. Therefore adding new&lt;br /&gt;
signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be&lt;br /&gt;
used to emulate virtual functions.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality&lt;br /&gt;
of it. Since signals have void return value, data must be returned using arguments. As&lt;br /&gt;
there will be only one slot connected to the signal returning data from the slot this way will&lt;br /&gt;
work without problems. Note that with Qt4 for this to work the connection type will have to be&lt;br /&gt;
Qt::DirectConnection.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
If an inherited class will want to reimplement the functionality of bar() it will have to provide&lt;br /&gt;
its own slot:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary&lt;br /&gt;
to specify barslot() again as a slot in B and that in the constructor it is necessary to first&lt;br /&gt;
disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot()&lt;br /&gt;
instead.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Note: the same can be accomplished by implementing a virtual slot.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt; &amp;lt;small&amp;gt; &amp;lt;em&amp;gt;&lt;br /&gt;
Matthias Ettrich &amp;lt;a href=&amp;quot;mailto:ettrich@kde.org&amp;quot;&amp;gt;ettrich@kde.org&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Lubos Lunak &amp;lt;a href=&amp;quot;mailto:l.lunak@kde.org&amp;quot;&amp;gt;l.lunak@kde.org&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/em&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:27:51Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Using a d-Pointer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You may not want all member variables to live in the private data object, though. For very often used members, it's faster to put them directly in the class, since inline functions cannot access the d-pointer data. Also note that all data covered by the d-pointer is obviously private. For public or protected access, provide both a set and a get function. Example&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new data members to classes without d-pointer&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; If you don't have free bitflags, reserved variables and no&lt;br /&gt;
d-pointer either, but you absolutely have to add a new private member&lt;br /&gt;
variable, there are still some possibilities left. If your class&lt;br /&gt;
inherits QObject, you can for example place the additional data in a&lt;br /&gt;
special child and find it by traversing over the list of children. You&lt;br /&gt;
can access the list of children with QObject::children(). However, a&lt;br /&gt;
fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt&lt;br /&gt;
provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; The basic trick in your class implementation of class Foo is:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Create a private data class FooPrivate.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; Note that some compilers/linkers (almost all, unfortunately) do&lt;br /&gt;
not manage to create static objects in shared libraries. They simply&lt;br /&gt;
forget to call the constructor. Therefore you should use the &lt;br /&gt;
&amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Now you can use the d-pointer in your class almost as simple as&lt;br /&gt;
in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Add a line to your destructor:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Do not forget to add a BCI remark, so that the hack can be&lt;br /&gt;
removed in the next version of the library.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Do not forget to add a d-pointer to your next class.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding a reimplemented virtual function&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;As already explained, you can safely reimplement a virtual function defined&lt;br /&gt;
in one of the base classes only if it is safe that the programs linked&lt;br /&gt;
with the prior version call the implementation in the base class rather than&lt;br /&gt;
the new one. This is because the compiler sometimes calls virtual functions&lt;br /&gt;
directly if it can determine which one to call (for example if you have&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements&lt;br /&gt;
foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo().&lt;br /&gt;
If a newer version of the library adds B::foo(), C::foo() will call it only after&lt;br /&gt;
a recompilation.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Another more common example is:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;If you can't guarantee things will continue to work without a recompilation, move&lt;br /&gt;
functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in calling B::foo().&lt;br /&gt;
The only case that will not work as expected are calls to A::foo() that explicitly specify&lt;br /&gt;
A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using a new class&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement&lt;br /&gt;
class that will include also the new functionality (and that may inherit from the old&lt;br /&gt;
class to reuse the code). This of course requires adapting and recompiling applications using&lt;br /&gt;
the library, so it is not possible this way to fix or extend functionality of classes&lt;br /&gt;
that are used by applications compiled against an older version of the library. However,&lt;br /&gt;
especially with small and/or performance-critical classes it may be simpler to write&lt;br /&gt;
them without making sure they'll be simple to extend in the future and if the need arises&lt;br /&gt;
later write a new replacement class that will provide new features or better performance.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new virtual functions to leaf classes&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add&lt;br /&gt;
new virtual functions to a class that should stay binary compatible and there is no class&lt;br /&gt;
inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are&lt;br /&gt;
in applications). In such case it's possible to add a new class inheriting from the original one&lt;br /&gt;
that will add them. Applications using the new functionality will of course have to be modified&lt;br /&gt;
to use the new class.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also&lt;br /&gt;
stay binary compatible because they'd have to inherit from the new class.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using signals instead of virtual functions&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro&lt;br /&gt;
and it exists in every class inherited from QObject. Therefore adding new&lt;br /&gt;
signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be&lt;br /&gt;
used to emulate virtual functions.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality&lt;br /&gt;
of it. Since signals have void return value, data must be returned using arguments. As&lt;br /&gt;
there will be only one slot connected to the signal returning data from the slot this way will&lt;br /&gt;
work without problems. Note that with Qt4 for this to work the connection type will have to be&lt;br /&gt;
Qt::DirectConnection.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
If an inherited class will want to reimplement the functionality of bar() it will have to provide&lt;br /&gt;
its own slot:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary&lt;br /&gt;
to specify barslot() again as a slot in B and that in the constructor it is necessary to first&lt;br /&gt;
disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot()&lt;br /&gt;
instead.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Note: the same can be accomplished by implementing a virtual slot.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt; &amp;lt;small&amp;gt; &amp;lt;em&amp;gt;&lt;br /&gt;
Matthias Ettrich &amp;lt;a href=&amp;quot;mailto:ettrich@kde.org&amp;quot;&amp;gt;ettrich@kde.org&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Lubos Lunak &amp;lt;a href=&amp;quot;mailto:l.lunak@kde.org&amp;quot;&amp;gt;l.lunak@kde.org&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/em&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:26:21Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* The Do's and Don'ts */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. ''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; You may not want all member variables to live in the private data&lt;br /&gt;
object, though. For very often used members, it's faster to put them&lt;br /&gt;
directly in the class, since inline functions cannot access the&lt;br /&gt;
d-pointer data. Also note that all data covered by the d-pointer is&lt;br /&gt;
obviously private. For public or protected access, provide both a set&lt;br /&gt;
and a get function. Example&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new data members to classes without d-pointer&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; If you don't have free bitflags, reserved variables and no&lt;br /&gt;
d-pointer either, but you absolutely have to add a new private member&lt;br /&gt;
variable, there are still some possibilities left. If your class&lt;br /&gt;
inherits QObject, you can for example place the additional data in a&lt;br /&gt;
special child and find it by traversing over the list of children. You&lt;br /&gt;
can access the list of children with QObject::children(). However, a&lt;br /&gt;
fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt&lt;br /&gt;
provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; The basic trick in your class implementation of class Foo is:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Create a private data class FooPrivate.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; Note that some compilers/linkers (almost all, unfortunately) do&lt;br /&gt;
not manage to create static objects in shared libraries. They simply&lt;br /&gt;
forget to call the constructor. Therefore you should use the &lt;br /&gt;
&amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Now you can use the d-pointer in your class almost as simple as&lt;br /&gt;
in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Add a line to your destructor:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Do not forget to add a BCI remark, so that the hack can be&lt;br /&gt;
removed in the next version of the library.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Do not forget to add a d-pointer to your next class.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding a reimplemented virtual function&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;As already explained, you can safely reimplement a virtual function defined&lt;br /&gt;
in one of the base classes only if it is safe that the programs linked&lt;br /&gt;
with the prior version call the implementation in the base class rather than&lt;br /&gt;
the new one. This is because the compiler sometimes calls virtual functions&lt;br /&gt;
directly if it can determine which one to call (for example if you have&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements&lt;br /&gt;
foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo().&lt;br /&gt;
If a newer version of the library adds B::foo(), C::foo() will call it only after&lt;br /&gt;
a recompilation.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Another more common example is:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;If you can't guarantee things will continue to work without a recompilation, move&lt;br /&gt;
functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in calling B::foo().&lt;br /&gt;
The only case that will not work as expected are calls to A::foo() that explicitly specify&lt;br /&gt;
A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using a new class&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement&lt;br /&gt;
class that will include also the new functionality (and that may inherit from the old&lt;br /&gt;
class to reuse the code). This of course requires adapting and recompiling applications using&lt;br /&gt;
the library, so it is not possible this way to fix or extend functionality of classes&lt;br /&gt;
that are used by applications compiled against an older version of the library. However,&lt;br /&gt;
especially with small and/or performance-critical classes it may be simpler to write&lt;br /&gt;
them without making sure they'll be simple to extend in the future and if the need arises&lt;br /&gt;
later write a new replacement class that will provide new features or better performance.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new virtual functions to leaf classes&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add&lt;br /&gt;
new virtual functions to a class that should stay binary compatible and there is no class&lt;br /&gt;
inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are&lt;br /&gt;
in applications). In such case it's possible to add a new class inheriting from the original one&lt;br /&gt;
that will add them. Applications using the new functionality will of course have to be modified&lt;br /&gt;
to use the new class.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also&lt;br /&gt;
stay binary compatible because they'd have to inherit from the new class.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using signals instead of virtual functions&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro&lt;br /&gt;
and it exists in every class inherited from QObject. Therefore adding new&lt;br /&gt;
signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be&lt;br /&gt;
used to emulate virtual functions.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality&lt;br /&gt;
of it. Since signals have void return value, data must be returned using arguments. As&lt;br /&gt;
there will be only one slot connected to the signal returning data from the slot this way will&lt;br /&gt;
work without problems. Note that with Qt4 for this to work the connection type will have to be&lt;br /&gt;
Qt::DirectConnection.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
If an inherited class will want to reimplement the functionality of bar() it will have to provide&lt;br /&gt;
its own slot:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary&lt;br /&gt;
to specify barslot() again as a slot in B and that in the constructor it is necessary to first&lt;br /&gt;
disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot()&lt;br /&gt;
instead.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Note: the same can be accomplished by implementing a virtual slot.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt; &amp;lt;small&amp;gt; &amp;lt;em&amp;gt;&lt;br /&gt;
Matthias Ettrich &amp;lt;a href=&amp;quot;mailto:ettrich@kde.org&amp;quot;&amp;gt;ettrich@kde.org&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Lubos Lunak &amp;lt;a href=&amp;quot;mailto:l.lunak@kde.org&amp;quot;&amp;gt;l.lunak@kde.org&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/em&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B</id>
		<title>Policies/Binary Compatibility Issues With C++</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C%2B%2B"/>
				<updated>2007-01-12T20:20:48Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Definition ==&lt;br /&gt;
&lt;br /&gt;
A library is '''binary compatible''', if a program linked dynamically to a former version of the library continues running with newer versions of the library without the need to recompile.&lt;br /&gt;
&lt;br /&gt;
If a program needs to be recompiled to run with a new version of library but doesn't require any further modifications, the library is '''source compatible'''.&lt;br /&gt;
&lt;br /&gt;
Binary compatibility saves a lot of trouble. It makes it much easier to distribute software for a certain platform. Without ensuring binary compatibility between releases, people will be forced to provide statically linked binaries. Static binaries  are bad because they&lt;br /&gt;
* waste resources (especially memory)&lt;br /&gt;
* don't allow the program to benefit from bugfixes or extensions in the libraries&lt;br /&gt;
&lt;br /&gt;
In the KDE project, we will provide binary compatibility within the life-span of a major release.&lt;br /&gt;
&lt;br /&gt;
== The Do's and Don'ts ==&lt;br /&gt;
&lt;br /&gt;
You can...&lt;br /&gt;
&lt;br /&gt;
* add new non-virtual functions including signals and slots.&lt;br /&gt;
* add a new enum to a class.&lt;br /&gt;
* append new enumerators to an existing enum.&lt;br /&gt;
* reimplement virtual functions defined in one of the base classes '''if''' it is safe that programs linked with the prior version of the library call the implementation in the base class rather than the new one. '''This is tricky and might be dangerous. Think twice before doing it. Alternatively see below for a workaround.''&lt;br /&gt;
* change an inline function or make an inline function non-inline '''if''' it is safe that programs linked with the prior version of the library call the old implementation. ''This is tricky and might be dangerous. Think twice before doing it.'' Because of this, classes that are supposed to stay binary compatible should '''always''' have non-inline destructor, even if it's empty, otherwise the compiler will automatically generate an empty inlined one.&lt;br /&gt;
* Remove private non-virtual functions '''if''' they are not called&lt;br /&gt;
by any inline functions.&lt;br /&gt;
* change the default arguments of a method. It requires recompilation to use the actual new default argument values, though.&lt;br /&gt;
* add new '''static''' data members.&lt;br /&gt;
* add new classes.&lt;br /&gt;
&lt;br /&gt;
You cannot...&lt;br /&gt;
* add new virtual functions as this will change the layout of the virtual table and thus break subclasses. ''See below for some workarounds or ask on mailing lists.''&lt;br /&gt;
* change the order of virtual functions in the class declaration. This will just as well change the layout of the virtual table.&lt;br /&gt;
* change the signature of a function. This includes:&lt;br /&gt;
** changing any of the types of the arguments in the parameter list (instead, add a new method)&lt;br /&gt;
** changing the return type&lt;br /&gt;
** extending a function with another parameter, even if this parameter has a default argument&lt;br /&gt;
Suggestion: when adding new functions with the same name and different/extended argument lists, you may want to add a short note that the two functions shall be merged with a default argument in later versions of the library:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void functionname( int a );&lt;br /&gt;
void functionname( int a, int b ); //BCI: merge with int b = 0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* change the access rights to some functions or data members, for example from&lt;br /&gt;
&amp;lt;tt&amp;gt;private&amp;lt;/tt&amp;gt; to &amp;lt;tt&amp;gt;public&amp;lt;/tt&amp;gt;. With some compilers, this information may be part of the signature. If you need to make a private function protected or even public, you have to add a new function that calls the private one.&lt;br /&gt;
* add new data members to a class or change order of data members in a class (doesn't apply to static ones).&lt;br /&gt;
* change the class hierachy apart from adding new classes.&lt;br /&gt;
&lt;br /&gt;
You should...&lt;br /&gt;
&lt;br /&gt;
In order to make a class to extend in the future you should follow these rules:&lt;br /&gt;
* add d-pointer. ''See below''.&lt;br /&gt;
* add non-inline virtual destructor even if the body is empty.&lt;br /&gt;
* reimplement &amp;lt;tt&amp;gt;event&amp;lt;/tt&amp;gt; in widget classes, even if the body for the function is empty.&lt;br /&gt;
* make all constructors non-inline.&lt;br /&gt;
* write non-inline implementations of the copy constructor and assignment operator unless the class cannot be copied by value (e.g. classes inherited from QObject can't be)&lt;br /&gt;
&lt;br /&gt;
== Techniques for Library Programmers ==&lt;br /&gt;
&lt;br /&gt;
The biggest problem when writing libraries is, that one cannot safely add data members since this would change the size and layout of every class, struct, or array containing objects of the type, including subclasses.&lt;br /&gt;
&lt;br /&gt;
=== Bitflags ===&lt;br /&gt;
One exception are bitflags. If you use bitflags for enums or bools, you can safely round up to at least the next byte minus 1. A class with members&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	uint m1 : 1;&lt;br /&gt;
	uint m2 : 3;&lt;br /&gt;
	uint m3 : 1;&lt;br /&gt;
	uint m4 : 2; // new member&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
without breaking binary compatibility. Please round up to a maxmimum of 7 bits (or 15 if the bitfield was already larger than 8). Using the very last bit may cause problems on some compilers.&lt;br /&gt;
&lt;br /&gt;
=== Using a d-Pointer===&lt;br /&gt;
Bitflags and predefined reserved variables are nice, but far from being sufficient.  This is where the d-pointer technique comes into play.  The name &amp;quot;d-pointer&amp;quot; stems from Trolltech's Arnt Gulbrandsen, who first introduced the technique into Qt, making it one of the first C++ GUI libraries to maintain binary compatibility even between bigger release. The technique was quickly adapted as general programming pattern for the KDE libraries by everyone who saw it. It's a great trick to be able to add new private data members to a class without breaking binary compatibility.&lt;br /&gt;
&lt;br /&gt;
'''Remark:''' The d-pointer pattern has been described many&lt;br /&gt;
times in computer science history under various names, e.g. as pimpl,&lt;br /&gt;
as handle/body or as cheshire cat.  Google helps finding online papers&lt;br /&gt;
for any of these, just add C++ to the search terms.&amp;lt;/small&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; In your class definition for class Foo, define a forward declaration&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
class FooPrivate;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
and the d-pointer in the private section:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
private:&lt;br /&gt;
	FooPrivate* d;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
The FooPrivate class itself is purely defined in the clas implementation file (usually *.cpp ), for example:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
class FooPrivate {&lt;br /&gt;
public:&lt;br /&gt;
	FooPrivate()&lt;br /&gt;
	: m1(0), m2(0)&lt;br /&gt;
	{};&lt;br /&gt;
	int m1;&lt;br /&gt;
	int m2;&lt;br /&gt;
	QString s;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
All you have to do now is to create the private data in your constructors or your init function with&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	d = new FooPrivate;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
and to delete it again in your destructor with&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	delete d;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; You may not want all member variables to live in the private data&lt;br /&gt;
object, though. For very often used members, it's faster to put them&lt;br /&gt;
directly in the class, since inline functions cannot access the&lt;br /&gt;
d-pointer data. Also note that all data covered by the d-pointer is&lt;br /&gt;
obviously private. For public or protected access, provide both a set&lt;br /&gt;
and a get function. Example&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	QString Foo::string() const&lt;br /&gt;
	{&lt;br /&gt;
		return d-&amp;gt;s;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void setString( const QString&amp;amp;amp; s )&lt;br /&gt;
	{&lt;br /&gt;
		d-&amp;gt;s = s;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h2&amp;gt;Trouble shooting&amp;lt;/h2&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new data members to classes without d-pointer&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; If you don't have free bitflags, reserved variables and no&lt;br /&gt;
d-pointer either, but you absolutely have to add a new private member&lt;br /&gt;
variable, there are still some possibilities left. If your class&lt;br /&gt;
inherits QObject, you can for example place the additional data in a&lt;br /&gt;
special child and find it by traversing over the list of children. You&lt;br /&gt;
can access the list of children with QObject::children(). However, a&lt;br /&gt;
fancier and usually faster approach is to use a hashtable to store a&lt;br /&gt;
mapping between your object and the extra data. For this purpose, Qt&lt;br /&gt;
provides a pointer-based dictionary called QHash (or QPtrDict in Qt3).&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; The basic trick in your class implementation of class Foo is:&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Create a private data class FooPrivate.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Create a static QHash&amp;amp;lt;Foo *, FooPrivate&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt; Note that some compilers/linkers (almost all, unfortunately) do&lt;br /&gt;
not manage to create static objects in shared libraries. They simply&lt;br /&gt;
forget to call the constructor. Therefore you should use the &lt;br /&gt;
&amp;lt;tt&amp;gt;Q_GLOBAL_STATIC&amp;lt;/tt&amp;gt; macro to create and access the object:&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	// BCI: Add a real d-pointer&lt;br /&gt;
	Q_GLOBAL_STATIC(QHash&amp;amp;lt;Foo *,FooPrivate&amp;amp;gt;, d_func);&lt;br /&gt;
	static FooPrivate* d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
		if ( ! ret ) {&lt;br /&gt;
			ret = new FooPrivate;&lt;br /&gt;
			d_func()-&amp;gt;insert( foo, ret );&lt;br /&gt;
		}&lt;br /&gt;
		return ret;&lt;br /&gt;
	}&lt;br /&gt;
	static void delete_d( const Foo* foo )&lt;br /&gt;
	{&lt;br /&gt;
		FooPrivate* ret = d_func()-&amp;gt;value( foo, 0 );&lt;br /&gt;
	        delete ret;&lt;br /&gt;
	        d_func()-&amp;gt;remove( foo );&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Now you can use the d-pointer in your class almost as simple as&lt;br /&gt;
in the code before, just with a function call to d(this). For example:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	d(this)-&amp;gt;m1 = 5;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Add a line to your destructor:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	delete_d(this);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&amp;lt;/li&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;li&amp;gt; Do not forget to add a BCI remark, so that the hack can be&lt;br /&gt;
removed in the next version of the library.&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt; Do not forget to add a d-pointer to your next class.&amp;lt;/li&amp;gt;&lt;br /&gt;
 &amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding a reimplemented virtual function&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;As already explained, you can safely reimplement a virtual function defined&lt;br /&gt;
in one of the base classes only if it is safe that the programs linked&lt;br /&gt;
with the prior version call the implementation in the base class rather than&lt;br /&gt;
the new one. This is because the compiler sometimes calls virtual functions&lt;br /&gt;
directly if it can determine which one to call (for example if you have&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void C::foo()&lt;br /&gt;
	{&lt;br /&gt;
		B::foo();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then B::foo() is called directly. If class B inherits from class A which implements&lt;br /&gt;
foo() and B itself doesn't reimplement it, then C::foo() will in fact call A::foo().&lt;br /&gt;
If a newer version of the library adds B::foo(), C::foo() will call it only after&lt;br /&gt;
a recompilation.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Another more common example is:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	B b;		// B derives from A&lt;br /&gt;
	b.foo();&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
then the call to foo() will not use the virtual table. That means that&lt;br /&gt;
if B::foo() didn't exist in the library but now does, code that was&lt;br /&gt;
compiled with the earlier version will still call A::foo().&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;If you can't guarantee things will continue to work without a recompilation, move&lt;br /&gt;
functionality from A::foo() to a new protected function A::foo2() and use this code:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		if( B* b = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			b-&amp;gt;B::foo(); // B:: is important&lt;br /&gt;
		else&lt;br /&gt;
			foo2();&lt;br /&gt;
	}&lt;br /&gt;
	void B::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// added functionality&lt;br /&gt;
		A::foo2(); // call base function with real functionality&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
All calls to A::foo() for objects of type B (or inherited) will result in calling B::foo().&lt;br /&gt;
The only case that will not work as expected are calls to A::foo() that explicitly specify&lt;br /&gt;
A::foo(), but B::foo() calls A::foo2() instead and there should not be other places doing so.&lt;br /&gt;
&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using a new class&amp;lt;/h3&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;A relatively simple method of &amp;quot;extending&amp;quot; a class can be writing a replacement&lt;br /&gt;
class that will include also the new functionality (and that may inherit from the old&lt;br /&gt;
class to reuse the code). This of course requires adapting and recompiling applications using&lt;br /&gt;
the library, so it is not possible this way to fix or extend functionality of classes&lt;br /&gt;
that are used by applications compiled against an older version of the library. However,&lt;br /&gt;
especially with small and/or performance-critical classes it may be simpler to write&lt;br /&gt;
them without making sure they'll be simple to extend in the future and if the need arises&lt;br /&gt;
later write a new replacement class that will provide new features or better performance.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Adding new virtual functions to leaf classes&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
This technique is one of cases of using a new class that can help if there's a need to add&lt;br /&gt;
new virtual functions to a class that should stay binary compatible and there is no class&lt;br /&gt;
inheriting from it that should also stay binary compatible (i.e. all classes inheriting from it are&lt;br /&gt;
in applications). In such case it's possible to add a new class inheriting from the original one&lt;br /&gt;
that will add them. Applications using the new functionality will of course have to be modified&lt;br /&gt;
to use the new class.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A {&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	};&lt;br /&gt;
	class B : public A { // newly added class&lt;br /&gt;
	public:&lt;br /&gt;
		virtual void bar(); // newly added virtual function&lt;br /&gt;
	};&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		// here it's needed to call a new virtual function&lt;br /&gt;
		if( B* this2 = dynamic_cast&amp;lt; B* &amp;gt;( this ))&lt;br /&gt;
			this2-&amp;gt;bar();&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
It is not possible to use this technique when there are other inherited classes that should also&lt;br /&gt;
stay binary compatible because they'd have to inherit from the new class.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;h3&amp;gt;Using signals instead of virtual functions&amp;lt;/h3&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
Qt's signals and slots are invoked using a special virtual method created by the Q_OBJECT macro&lt;br /&gt;
and it exists in every class inherited from QObject. Therefore adding new&lt;br /&gt;
signals and slots doesn't affect binary compatibility and the signals/slots mechanism can be&lt;br /&gt;
used to emulate virtual functions.&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class A : public QObject {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		A();&lt;br /&gt;
		virtual void foo();&lt;br /&gt;
	signals:&lt;br /&gt;
		void bar( int* ); // added new &amp;quot;virtual&amp;quot; function&lt;br /&gt;
	protected slots:&lt;br /&gt;
		void barslot( int* ); // implementation of the virtual function in A&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	A::A()&lt;br /&gt;
	{&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::foo()&lt;br /&gt;
	{&lt;br /&gt;
		int ret;&lt;br /&gt;
		emit bar( &amp;amp;ret );&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void A::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 10;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Function bar() will act like a virtual function, barslot() implements the actual functionality&lt;br /&gt;
of it. Since signals have void return value, data must be returned using arguments. As&lt;br /&gt;
there will be only one slot connected to the signal returning data from the slot this way will&lt;br /&gt;
work without problems. Note that with Qt4 for this to work the connection type will have to be&lt;br /&gt;
Qt::DirectConnection.&amp;lt;/p&amp;gt;&lt;br /&gt;
&amp;lt;p&amp;gt;&lt;br /&gt;
If an inherited class will want to reimplement the functionality of bar() it will have to provide&lt;br /&gt;
its own slot:&lt;br /&gt;
&amp;lt;table align=&amp;quot;center&amp;quot;  width=&amp;quot;80%&amp;quot;&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td BGCOLOR=&amp;quot;#F0F0FF&amp;quot;&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
	class B : public A {&lt;br /&gt;
	Q_OBJECT&lt;br /&gt;
	public:&lt;br /&gt;
		B();&lt;br /&gt;
	protected slots: // necessary to specify as a slot again&lt;br /&gt;
		void barslot( int* ); // reimplemented functionality of bar()&lt;br /&gt;
	};&lt;br /&gt;
&lt;br /&gt;
	B::B()&lt;br /&gt;
	{&lt;br /&gt;
		disconnect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
		connect( this, SIGNAL( bar( int* )), this, SLOT( barslot( int* )));&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	void B::barslot( int* ret )&lt;br /&gt;
	{&lt;br /&gt;
		*ret = 20;&lt;br /&gt;
	}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/td&amp;gt;&amp;lt;/tr&amp;gt;&amp;lt;/table&amp;gt;&lt;br /&gt;
Now B::barslot() will act like virtual reimplementation of A::bar(). Note that it is necessary&lt;br /&gt;
to specify barslot() again as a slot in B and that in the constructor it is necessary to first&lt;br /&gt;
disconnect and then connect again, that will disconnect A::barslot() and connect B::barslot()&lt;br /&gt;
instead.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;Note: the same can be accomplished by implementing a virtual slot.&amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p align=&amp;quot;right&amp;quot;&amp;gt; &amp;lt;small&amp;gt; &amp;lt;em&amp;gt;&lt;br /&gt;
Matthias Ettrich &amp;lt;a href=&amp;quot;mailto:ettrich@kde.org&amp;quot;&amp;gt;ettrich@kde.org&amp;lt;/a&amp;gt;&amp;lt;br&amp;gt;&lt;br /&gt;
Lubos Lunak &amp;lt;a href=&amp;quot;mailto:l.lunak@kde.org&amp;quot;&amp;gt;l.lunak@kde.org&amp;lt;/a&amp;gt;&lt;br /&gt;
&amp;lt;/em&amp;gt;&amp;lt;/small&amp;gt;&amp;lt;/p&amp;gt;&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff</id>
		<title>Development/Tutorials/Introduction to Get Hot New Stuff</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff"/>
				<updated>2007-01-12T18:13:45Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Improve... TODO...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
Similar to how programming languages shifted focus from algorithms to data structures in the 70s, desktop application development emphasizes more and more on user data, i.e. data intentionally produced or consumed by the user. Both on the internet and in corporate intranets, sharing this data is considered an easy way to customize desktops and to advertise one's creativity. The 'Get Hot New Stuff' (GHNS) framework in KDE exists to support this approach, and the KNewStuff library is the key for application authors to enable GHNS.&lt;br /&gt;
&lt;br /&gt;
== Preparations ==&lt;br /&gt;
The first steps are usually made in preparing the usage of KNewStuff. For this matter, the library must be available (a task which could be done using autoconf, but since it's part of kdelibs, we simply assume it's available with any recent KDE installation.) Authors of 3rd pary applications can ensure the availability as part of kdepim-libs in KDE 3.2 using the AC_KNEWSTUFF macro. It must also be included in the set of libraries against which the application is linked, so modifying the Makefile.am and reconfiguring the application are to be done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
bin_PROGRAMS = myapp&lt;br /&gt;
myapp_LDADD = $(LIB_KDECORE) ... -lknewstuff&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The header files are installed under $kdedir/include/knewstuff/, so in the relevant files, they're included with statements such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/downloaddialog.h&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The following header files are provided by KNewStuff:&lt;br /&gt;
* downloaddialog.h: Easy to use download dialog&lt;br /&gt;
* engine.h: Access to the complex, but customizable background operations&lt;br /&gt;
* entry.h: (internal) Data fields of entries, such as Author or Title&lt;br /&gt;
* ghns.h: [not installed]&lt;br /&gt;
* knewstuffgeneric.h: Easy to use installation handler for the downloaded files&lt;br /&gt;
* knewstuff.h: Main knewstuff functionality&lt;br /&gt;
* providerdialog.h: Preconfigured dialog for provider selection&lt;br /&gt;
* provider.h: Provider entries, and ProviderLoader&lt;br /&gt;
* testnewstuff.h: [not installed]&lt;br /&gt;
* uploaddialog.h: Easy to use upload dialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on the background processes, please have a look at the information provided by [http://www.kstuff.org/docs/ kstuff.org]. However application authors should only need a basic understanding of those.&lt;br /&gt;
&lt;br /&gt;
== Downloading Data ==&lt;br /&gt;
&lt;br /&gt;
Depending on the application, providing additional data can be accomplished using the 'File Import' dialog, 'Internet Level' menu item, or just an 'Update now' KAction. All of those have in common that they invoke a slot which will contain the actual KNewStuff calls. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void MyApp::slotDownload()&lt;br /&gt;
{&lt;br /&gt;
  KNewStuff::DownloadDialog::open(&amp;quot;myapp/templates&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is all. If desired, more control can be exercised on the whole download process, as outlined below. For the beginning, the above is already fully functional, and should be used at first. &lt;br /&gt;
&lt;br /&gt;
== TODO Downloading in Detail ==&lt;br /&gt;
The example above implicitely constructs an internal Engine object, retrieves the directory list, fetches the provider lists specified in the directory, and the entries in each of the provider lists, compares them to the data files previously installed, and displays them in the download dialog. This dialog in turn handles all the installation issues. Of course there is no magic involved, and for more control about the subtasks, the following is recommended: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(to be precised)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Similar to the provider list, the installation procedures are described in the application's configuration file. The default (if these entries are missing) is to just download the file to a temporary location, which is not useful in most of the cases. There are two entries: target location, and post-installation command. The target location can either be StandardResource, matching the KDE resource types, or TargetDir, matching an application directory under $KDEHOME/share/apps/appname. The post installation command can be a binary with '%f' as parameter (note the single quotes to prevent string format attacks), but it can as well be a DCOP call, so the application can directly work with the data. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[KNewStuff]&lt;br /&gt;
StandardResource=wallpaper&lt;br /&gt;
InstallationCommand=dcop kdesktop KBackgroundIface setWallpaper '%f' 2&lt;br /&gt;
&lt;br /&gt;
TargetDir=kamikaze&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uploads ==&lt;br /&gt;
&lt;br /&gt;
The beginning of the upload process works similar to downloads. A MasterServer or ProvidersUrl is used to retrieve the provider list, and one of the providers is selected by the user. Only providers which allow uploads are taken into account. After this selection however, the differences begin. The user has to fill in the necessary information such as title, author name or version number into the upload dialog. Also, the payload and preview files have to be selected, this however will in most cases be the application's task.  In Kamikaze, the level file is pre-rendered to an invisible QCanvas, and the resulting graphics is minimized and automatically specified for the upload.  The upload will then happen using the protocol accepted by the provider, which in most cases will be anonymous FTP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
#include &amp;lt;knewstuff/knewstuffgeneric.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/engine.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/uploaddialog.h&amp;gt;&lt;br /&gt;
// ...&lt;br /&gt;
QString file, previewfile;&lt;br /&gt;
KNewStuffGeneric *ns = new KNewStuffGeneric(&amp;quot;myapp/templates&amp;quot;, this);&lt;br /&gt;
ns-&amp;gt;upload(file.name(), previewfile.name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Sharing creativity should become a default property of modern desktops, and KDE once again leads the pack by providing both upload and download facilities. If enough applications of different areas make use of them, it helps users to be more productive and have more fun with their computer.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff</id>
		<title>Development/Tutorials/Introduction to Get Hot New Stuff</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff"/>
				<updated>2007-01-12T18:13:18Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Downloading in Detail */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Similar to how programming languages shifted focus from algorithms to data structures in the 70s, desktop application development emphasizes more and more on user data, i.e. data intentionally produced or consumed by the user. Both on the internet and in corporate intranets, sharing this data is considered an easy way to customize desktops and to advertise one's creativity. The 'Get Hot New Stuff' (GHNS) framework in KDE exists to support this approach, and the KNewStuff library is the key for application authors to enable GHNS.&lt;br /&gt;
&lt;br /&gt;
== Preparations ==&lt;br /&gt;
The first steps are usually made in preparing the usage of KNewStuff. For this matter, the library must be available (a task which could be done using autoconf, but since it's part of kdelibs, we simply assume it's available with any recent KDE installation.) Authors of 3rd pary applications can ensure the availability as part of kdepim-libs in KDE 3.2 using the AC_KNEWSTUFF macro. It must also be included in the set of libraries against which the application is linked, so modifying the Makefile.am and reconfiguring the application are to be done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
bin_PROGRAMS = myapp&lt;br /&gt;
myapp_LDADD = $(LIB_KDECORE) ... -lknewstuff&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The header files are installed under $kdedir/include/knewstuff/, so in the relevant files, they're included with statements such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/downloaddialog.h&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The following header files are provided by KNewStuff:&lt;br /&gt;
* downloaddialog.h: Easy to use download dialog&lt;br /&gt;
* engine.h: Access to the complex, but customizable background operations&lt;br /&gt;
* entry.h: (internal) Data fields of entries, such as Author or Title&lt;br /&gt;
* ghns.h: [not installed]&lt;br /&gt;
* knewstuffgeneric.h: Easy to use installation handler for the downloaded files&lt;br /&gt;
* knewstuff.h: Main knewstuff functionality&lt;br /&gt;
* providerdialog.h: Preconfigured dialog for provider selection&lt;br /&gt;
* provider.h: Provider entries, and ProviderLoader&lt;br /&gt;
* testnewstuff.h: [not installed]&lt;br /&gt;
* uploaddialog.h: Easy to use upload dialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on the background processes, please have a look at the information provided by [http://www.kstuff.org/docs/ kstuff.org]. However application authors should only need a basic understanding of those.&lt;br /&gt;
&lt;br /&gt;
== Downloading Data ==&lt;br /&gt;
&lt;br /&gt;
Depending on the application, providing additional data can be accomplished using the 'File Import' dialog, 'Internet Level' menu item, or just an 'Update now' KAction. All of those have in common that they invoke a slot which will contain the actual KNewStuff calls. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void MyApp::slotDownload()&lt;br /&gt;
{&lt;br /&gt;
  KNewStuff::DownloadDialog::open(&amp;quot;myapp/templates&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is all. If desired, more control can be exercised on the whole download process, as outlined below. For the beginning, the above is already fully functional, and should be used at first. &lt;br /&gt;
&lt;br /&gt;
== TODO Downloading in Detail ==&lt;br /&gt;
The example above implicitely constructs an internal Engine object, retrieves the directory list, fetches the provider lists specified in the directory, and the entries in each of the provider lists, compares them to the data files previously installed, and displays them in the download dialog. This dialog in turn handles all the installation issues. Of course there is no magic involved, and for more control about the subtasks, the following is recommended: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(to be precised)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Similar to the provider list, the installation procedures are described in the application's configuration file. The default (if these entries are missing) is to just download the file to a temporary location, which is not useful in most of the cases. There are two entries: target location, and post-installation command. The target location can either be StandardResource, matching the KDE resource types, or TargetDir, matching an application directory under $KDEHOME/share/apps/appname. The post installation command can be a binary with '%f' as parameter (note the single quotes to prevent string format attacks), but it can as well be a DCOP call, so the application can directly work with the data. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[KNewStuff]&lt;br /&gt;
StandardResource=wallpaper&lt;br /&gt;
InstallationCommand=dcop kdesktop KBackgroundIface setWallpaper '%f' 2&lt;br /&gt;
&lt;br /&gt;
TargetDir=kamikaze&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uploads ==&lt;br /&gt;
&lt;br /&gt;
The beginning of the upload process works similar to downloads. A MasterServer or ProvidersUrl is used to retrieve the provider list, and one of the providers is selected by the user. Only providers which allow uploads are taken into account. After this selection however, the differences begin. The user has to fill in the necessary information such as title, author name or version number into the upload dialog. Also, the payload and preview files have to be selected, this however will in most cases be the application's task.  In Kamikaze, the level file is pre-rendered to an invisible QCanvas, and the resulting graphics is minimized and automatically specified for the upload.  The upload will then happen using the protocol accepted by the provider, which in most cases will be anonymous FTP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
#include &amp;lt;knewstuff/knewstuffgeneric.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/engine.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/uploaddialog.h&amp;gt;&lt;br /&gt;
// ...&lt;br /&gt;
QString file, previewfile;&lt;br /&gt;
KNewStuffGeneric *ns = new KNewStuffGeneric(&amp;quot;myapp/templates&amp;quot;, this);&lt;br /&gt;
ns-&amp;gt;upload(file.name(), previewfile.name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Sharing creativity should become a default property of modern desktops, and KDE once again leads the pack by providing both upload and download facilities. If enough applications of different areas make use of them, it helps users to be more productive and have more fun with their computer.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials</id>
		<title>Development/Tutorials</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials"/>
				<updated>2007-01-12T03:34:13Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Shell */  Original Link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tutorials are the fastest way of finding out what KDE will do for you, and how to do it. Here is a list of currently available tutorials.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
;[[/Programming Tutorial KDE 4|Introduction To KDE 4 Programming]]&lt;br /&gt;
:''You are interested in writing applications with KDE 4? This tutorial series is aimed at those completely new to KDE programming.''&lt;br /&gt;
&lt;br /&gt;
;[[/CMake|Introduction to CMake]]&lt;br /&gt;
:''How to use the CMake build system used by KDE4''&lt;br /&gt;
&lt;br /&gt;
;[[/Using Qt Designer|Using Qt Designer to build user interfaces]]&lt;br /&gt;
:''How to create UI files with designer, and how to integrate them into a KDE program''&lt;br /&gt;
&lt;br /&gt;
;[[/Command-Line Options|Using Command-line Options]]&lt;br /&gt;
:''How to use the KDE Command-line arguments system''&lt;br /&gt;
&lt;br /&gt;
;[[/Debugging|Debugging your application]]&lt;br /&gt;
:''Tips, tools and techniques to apply when debugging your KDE application''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Unittests|Writing Unittests for Qt4 and KDE4 with QTestLib]] ([http://developer.kde.org/documentation/tutorials/writingunittests/writingunittests.html Original link])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to write unit tests using the QTestLib framework. It is presented as an example based tutorial, and is still under development.'' '''Does this belong in this section? It's hardly a beginner tutorial.'''&lt;br /&gt;
&lt;br /&gt;
;[[/Code_Checking|Semi-automatic ways to detect code errors]]&lt;br /&gt;
:''Techniques you can use to detect errors in KDE code'' '''Maybe this should be put under the Dubugging page? Or maybe both these pages should be put in their own subsection on this page?'''&lt;br /&gt;
&lt;br /&gt;
== Managing Configuration Data With KConfig ==&lt;br /&gt;
&lt;br /&gt;
;[[/Using KConfig XT|Using KConfig XT]]&lt;br /&gt;
:''Tutorial on how to efficiently use the KConfig XT framework.''&lt;br /&gt;
&lt;br /&gt;
== File Access With KIO ==&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
;[[/Localization/Unicode|101: Unicode]]&lt;br /&gt;
:''An introduction to what Unicode is as well as how to handle Unicode data in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n|110: Writing Applications With Localization in Mind]]&lt;br /&gt;
:''This tutorial covers what localization is, why it's important and how to ensure your application is ready to be localized. A must read for all application developers.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Mistakes|115: Avoiding Common Localization Pitfalls]]&lt;br /&gt;
:''There are several common mistakes that prevent applications from being properly localized. Find out what they are and how to easily avoid them in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/Building KDE's l10n Module|120: Building KDE's Localization Module]]&lt;br /&gt;
:''Building and installing language support from KDE's localization (l10n) module is a good idea for those working on applications in the main KDE repository. Doing so will allow you to test your application in another language and spot problem areas. Learn how to do just that in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Build Systems|200: Incorporating i18n Into the Build System]]&lt;br /&gt;
:''Once your application is ready to be localized, the next step is to ensure that translation files are built automatically and kept up to date. This tutorial covers the necessary CMakeFiles.txt additions as well the process of distributing the resulting message catalogs with your application.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Challenges|210: Common i18n Challenges and Solutions]]&lt;br /&gt;
:''This tutorial covers challenges that you may eventually run into such as translating handbooks and other data that exists outside of the source code, merging and handling obsolete .po files, deeling with freezes, coding in languages other than English and creating independent releases of or moving applications between KDE modules.''&lt;br /&gt;
&lt;br /&gt;
== Components and Plugins ==&lt;br /&gt;
&lt;br /&gt;
== Application Automation and Scripting ==&lt;br /&gt;
&lt;br /&gt;
=== D-Bus ===&lt;br /&gt;
; [[/D-Bus/Introduction|101: Introduction to D-Bus]]&lt;br /&gt;
:''A straight-forward introduction to the core concepts in D-Bus from an application developer's perspective, this tutorial covers what D-Bus is and how it can be used by applications.''&lt;br /&gt;
; [[/D-Bus/Accessing Interfaces|201: Accessing D-Bus Interfaces]]&lt;br /&gt;
:''A step-by-step guide to calling D-Bus methods and connecting to D-Bus signals using QtDBus.''&lt;br /&gt;
; [[/D-Bus/Creating Interfaces|211: Creating D-Bus Interfaces]]&lt;br /&gt;
:''Learn how to expose functionality in your application by creating and using custom D-Bus interfaces. Covers generating the XML descriptions, instantiating interfaces at run time and setting up the build system with CMake.''&lt;br /&gt;
; [[/D-Bus/Autostart Services|300: D-Bus Autostart Services]]&lt;br /&gt;
:''Turn your application into a D-Bus autostart service with this tutorial. This D-Bus feature will ensure that even when your application isn't running that D-Bus calls made to it will work by relying on the D-Bus daemon itself to start your app if and when needed.''&lt;br /&gt;
&lt;br /&gt;
=== Konqueror ===&lt;br /&gt;
; [[/Creating Konqueror Service Menus|Creating Konqueror Service Menus]]&lt;br /&gt;
:''This tutorial shows you how to create mimetype-specific actions in Konqueror's context menu (aka &amp;quot;servicemenus&amp;quot;).''&lt;br /&gt;
&lt;br /&gt;
===Kross===&lt;br /&gt;
; [[Development/Tutorials/Kross-Tutorial|Kross Tutorial]] ([http://wiki.koffice.org/index.php?title=Kross/Tutorial Original Link])&lt;br /&gt;
:''This tutorial explains how to integrate the Kross scripting framework into an application.''&lt;br /&gt;
&lt;br /&gt;
== Search and Metadata ==&lt;br /&gt;
&lt;br /&gt;
; [[/Writing file analyzers|Writing file analyzers]]&lt;br /&gt;
:''File analyzers extract data from files to display in the file dialogs and file managers. The data gathered this way is also used to search for files. KDE4 allows the use of multiple analyzers per file type. This tutorial describes how you can write new analyzers.''&lt;br /&gt;
&lt;br /&gt;
== Hardware Awareness ==&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Tutorials|Introduction to Solid]]&lt;br /&gt;
:''An introduction to using the Solid hardware discovery and interaction system in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Network_Tutorial|Accessing Network Information]]&lt;br /&gt;
:''How to use the Solid system to get information about the network''&lt;br /&gt;
&lt;br /&gt;
==Printing==&lt;br /&gt;
&lt;br /&gt;
;[[/Printing Hello World|101: Hello World]]&lt;br /&gt;
:''Introduction to the KDE printing system''&lt;br /&gt;
&lt;br /&gt;
;TODO 110 Print Dialog&lt;br /&gt;
:''Using the KDE print dialog''&lt;br /&gt;
&lt;br /&gt;
== Get Hot New Stuff ==&lt;br /&gt;
; [[Development/Tutorials/Introduction to Get Hot New Stuff|Introduction to Get Hot New Stuff]] ([http://edu.kde.org/development/ghns.php Original Link])&lt;br /&gt;
:''An introduction to the developer-friendly network update system that allows KDE applications to fetch new application data at runtime in a user friendly manner.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KNewStuffSecure|KNewStuff Secure]] ([http://developer.kde.org/documentation/tutorials/knewstuffsecure/index.html Original Link])&lt;br /&gt;
:''Tutorial showing how to share resources in a secured way (KDE 3.4 and later).''  By Andr&amp;amp;#225;s Mantia &amp;amp;lt;amantia@kde.org&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Rapid Application Development ==&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/101_Python_introduction_to_signal_and_slots|101 Introduction to signal and slots]]&lt;br /&gt;
:''A simple introduction to QT's signal and slots architecture.''&lt;br /&gt;
&lt;br /&gt;
;[http://www.xs4all.nl/~bsarempt/python/tutorial.html KDE-Python tutorial]&lt;br /&gt;
:''A python version of Daniel's KDE tutorial by Boudewijn Rempt.''&lt;br /&gt;
&lt;br /&gt;
=== Ruby ===&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/language-bindings/ruby/kde3tutorial/index.html KDE Ruby Korundum tutorial]&lt;br /&gt;
:''A ruby version of Antonio Larrosa Jim&amp;amp;eacute;nez's KDE tutorial by Richard Dale. See the [http://developer.kde.org/language-bindings/ruby/index.html Ruby Developers Corner] for Qt tutorials and other info.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Qt4_Ruby_Tutorial|Qt4 Ruby Tutorial]]&lt;br /&gt;
:''Trolltech's fabulous introductory tutorial to Qt, translated to Ruby.''&lt;br /&gt;
&lt;br /&gt;
=== Shell ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Shell_Scripting_with_KDE_Dialogs|Shell Scripting with KDE dialogs]] ([http://developer.kde.org/documentation/tutorials/kdialog/t1.html Original Link])  ([http://developer.kde.org/documentation/tutorials/kdialog-german/t1.html German Version])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to use KDE dialogs in shell scripts with kdialog. It is presented as an example based tutorial.''&lt;br /&gt;
&lt;br /&gt;
== Other tutorials ==&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/documentation/tutorials/kdeeduplot/kdeeduplot_tutorial.tar.bz2 Using and extending the KDE EDU Plot widget (docbook archive)]&lt;br /&gt;
:''This tutorial introduces Jason Harris' KPlotWidget that is part of the KDE EDU package. Contains information about defining your own widget in QT / KDevelop designer and about subclassing widgets and overriding member functions to extend functionality.''&lt;br /&gt;
&lt;br /&gt;
== KDE2 and KDE3 Materials ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE3|KDE3 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE3.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE2|KDE2 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE2.''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials</id>
		<title>Development/Tutorials</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials"/>
				<updated>2007-01-12T03:33:18Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Get Hot New Stuff */  Original Link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tutorials are the fastest way of finding out what KDE will do for you, and how to do it. Here is a list of currently available tutorials.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
;[[/Programming Tutorial KDE 4|Introduction To KDE 4 Programming]]&lt;br /&gt;
:''You are interested in writing applications with KDE 4? This tutorial series is aimed at those completely new to KDE programming.''&lt;br /&gt;
&lt;br /&gt;
;[[/CMake|Introduction to CMake]]&lt;br /&gt;
:''How to use the CMake build system used by KDE4''&lt;br /&gt;
&lt;br /&gt;
;[[/Using Qt Designer|Using Qt Designer to build user interfaces]]&lt;br /&gt;
:''How to create UI files with designer, and how to integrate them into a KDE program''&lt;br /&gt;
&lt;br /&gt;
;[[/Command-Line Options|Using Command-line Options]]&lt;br /&gt;
:''How to use the KDE Command-line arguments system''&lt;br /&gt;
&lt;br /&gt;
;[[/Debugging|Debugging your application]]&lt;br /&gt;
:''Tips, tools and techniques to apply when debugging your KDE application''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Unittests|Writing Unittests for Qt4 and KDE4 with QTestLib]] ([http://developer.kde.org/documentation/tutorials/writingunittests/writingunittests.html Original link])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to write unit tests using the QTestLib framework. It is presented as an example based tutorial, and is still under development.'' '''Does this belong in this section? It's hardly a beginner tutorial.'''&lt;br /&gt;
&lt;br /&gt;
;[[/Code_Checking|Semi-automatic ways to detect code errors]]&lt;br /&gt;
:''Techniques you can use to detect errors in KDE code'' '''Maybe this should be put under the Dubugging page? Or maybe both these pages should be put in their own subsection on this page?'''&lt;br /&gt;
&lt;br /&gt;
== Managing Configuration Data With KConfig ==&lt;br /&gt;
&lt;br /&gt;
;[[/Using KConfig XT|Using KConfig XT]]&lt;br /&gt;
:''Tutorial on how to efficiently use the KConfig XT framework.''&lt;br /&gt;
&lt;br /&gt;
== File Access With KIO ==&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
;[[/Localization/Unicode|101: Unicode]]&lt;br /&gt;
:''An introduction to what Unicode is as well as how to handle Unicode data in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n|110: Writing Applications With Localization in Mind]]&lt;br /&gt;
:''This tutorial covers what localization is, why it's important and how to ensure your application is ready to be localized. A must read for all application developers.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Mistakes|115: Avoiding Common Localization Pitfalls]]&lt;br /&gt;
:''There are several common mistakes that prevent applications from being properly localized. Find out what they are and how to easily avoid them in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/Building KDE's l10n Module|120: Building KDE's Localization Module]]&lt;br /&gt;
:''Building and installing language support from KDE's localization (l10n) module is a good idea for those working on applications in the main KDE repository. Doing so will allow you to test your application in another language and spot problem areas. Learn how to do just that in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Build Systems|200: Incorporating i18n Into the Build System]]&lt;br /&gt;
:''Once your application is ready to be localized, the next step is to ensure that translation files are built automatically and kept up to date. This tutorial covers the necessary CMakeFiles.txt additions as well the process of distributing the resulting message catalogs with your application.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Challenges|210: Common i18n Challenges and Solutions]]&lt;br /&gt;
:''This tutorial covers challenges that you may eventually run into such as translating handbooks and other data that exists outside of the source code, merging and handling obsolete .po files, deeling with freezes, coding in languages other than English and creating independent releases of or moving applications between KDE modules.''&lt;br /&gt;
&lt;br /&gt;
== Components and Plugins ==&lt;br /&gt;
&lt;br /&gt;
== Application Automation and Scripting ==&lt;br /&gt;
&lt;br /&gt;
=== D-Bus ===&lt;br /&gt;
; [[/D-Bus/Introduction|101: Introduction to D-Bus]]&lt;br /&gt;
:''A straight-forward introduction to the core concepts in D-Bus from an application developer's perspective, this tutorial covers what D-Bus is and how it can be used by applications.''&lt;br /&gt;
; [[/D-Bus/Accessing Interfaces|201: Accessing D-Bus Interfaces]]&lt;br /&gt;
:''A step-by-step guide to calling D-Bus methods and connecting to D-Bus signals using QtDBus.''&lt;br /&gt;
; [[/D-Bus/Creating Interfaces|211: Creating D-Bus Interfaces]]&lt;br /&gt;
:''Learn how to expose functionality in your application by creating and using custom D-Bus interfaces. Covers generating the XML descriptions, instantiating interfaces at run time and setting up the build system with CMake.''&lt;br /&gt;
; [[/D-Bus/Autostart Services|300: D-Bus Autostart Services]]&lt;br /&gt;
:''Turn your application into a D-Bus autostart service with this tutorial. This D-Bus feature will ensure that even when your application isn't running that D-Bus calls made to it will work by relying on the D-Bus daemon itself to start your app if and when needed.''&lt;br /&gt;
&lt;br /&gt;
=== Konqueror ===&lt;br /&gt;
; [[/Creating Konqueror Service Menus|Creating Konqueror Service Menus]]&lt;br /&gt;
:''This tutorial shows you how to create mimetype-specific actions in Konqueror's context menu (aka &amp;quot;servicemenus&amp;quot;).''&lt;br /&gt;
&lt;br /&gt;
===Kross===&lt;br /&gt;
; [[Development/Tutorials/Kross-Tutorial|Kross Tutorial]] ([http://wiki.koffice.org/index.php?title=Kross/Tutorial Original Link])&lt;br /&gt;
:''This tutorial explains how to integrate the Kross scripting framework into an application.''&lt;br /&gt;
&lt;br /&gt;
== Search and Metadata ==&lt;br /&gt;
&lt;br /&gt;
; [[/Writing file analyzers|Writing file analyzers]]&lt;br /&gt;
:''File analyzers extract data from files to display in the file dialogs and file managers. The data gathered this way is also used to search for files. KDE4 allows the use of multiple analyzers per file type. This tutorial describes how you can write new analyzers.''&lt;br /&gt;
&lt;br /&gt;
== Hardware Awareness ==&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Tutorials|Introduction to Solid]]&lt;br /&gt;
:''An introduction to using the Solid hardware discovery and interaction system in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Network_Tutorial|Accessing Network Information]]&lt;br /&gt;
:''How to use the Solid system to get information about the network''&lt;br /&gt;
&lt;br /&gt;
==Printing==&lt;br /&gt;
&lt;br /&gt;
;[[/Printing Hello World|101: Hello World]]&lt;br /&gt;
:''Introduction to the KDE printing system''&lt;br /&gt;
&lt;br /&gt;
;TODO 110 Print Dialog&lt;br /&gt;
:''Using the KDE print dialog''&lt;br /&gt;
&lt;br /&gt;
== Get Hot New Stuff ==&lt;br /&gt;
; [[Development/Tutorials/Introduction to Get Hot New Stuff|Introduction to Get Hot New Stuff]] ([http://edu.kde.org/development/ghns.php Original Link])&lt;br /&gt;
:''An introduction to the developer-friendly network update system that allows KDE applications to fetch new application data at runtime in a user friendly manner.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KNewStuffSecure|KNewStuff Secure]] ([http://developer.kde.org/documentation/tutorials/knewstuffsecure/index.html Original Link])&lt;br /&gt;
:''Tutorial showing how to share resources in a secured way (KDE 3.4 and later).''  By Andr&amp;amp;#225;s Mantia &amp;amp;lt;amantia@kde.org&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Rapid Application Development ==&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/101_Python_introduction_to_signal_and_slots|101 Introduction to signal and slots]]&lt;br /&gt;
:''A simple introduction to QT's signal and slots architecture.''&lt;br /&gt;
&lt;br /&gt;
;[http://www.xs4all.nl/~bsarempt/python/tutorial.html KDE-Python tutorial]&lt;br /&gt;
:''A python version of Daniel's KDE tutorial by Boudewijn Rempt.''&lt;br /&gt;
&lt;br /&gt;
=== Ruby ===&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/language-bindings/ruby/kde3tutorial/index.html KDE Ruby Korundum tutorial]&lt;br /&gt;
:''A ruby version of Antonio Larrosa Jim&amp;amp;eacute;nez's KDE tutorial by Richard Dale. See the [http://developer.kde.org/language-bindings/ruby/index.html Ruby Developers Corner] for Qt tutorials and other info.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Qt4_Ruby_Tutorial|Qt4 Ruby Tutorial]]&lt;br /&gt;
:''Trolltech's fabulous introductory tutorial to Qt, translated to Ruby.''&lt;br /&gt;
&lt;br /&gt;
=== Shell ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Shell_Scripting_with_KDE_Dialogs|Shell Scripting with KDE dialogs]] ([http://developer.kde.org/documentation/tutorials/kdialog-german/t1.html German Version])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to use KDE dialogs in shell scripts with kdialog. It is presented as an example based tutorial.''&lt;br /&gt;
&lt;br /&gt;
== Other tutorials ==&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/documentation/tutorials/kdeeduplot/kdeeduplot_tutorial.tar.bz2 Using and extending the KDE EDU Plot widget (docbook archive)]&lt;br /&gt;
:''This tutorial introduces Jason Harris' KPlotWidget that is part of the KDE EDU package. Contains information about defining your own widget in QT / KDevelop designer and about subclassing widgets and overriding member functions to extend functionality.''&lt;br /&gt;
&lt;br /&gt;
== KDE2 and KDE3 Materials ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE3|KDE3 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE3.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE2|KDE2 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE2.''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials</id>
		<title>Development/Tutorials</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials"/>
				<updated>2007-01-12T03:31:51Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Shell */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tutorials are the fastest way of finding out what KDE will do for you, and how to do it. Here is a list of currently available tutorials.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
;[[/Programming Tutorial KDE 4|Introduction To KDE 4 Programming]]&lt;br /&gt;
:''You are interested in writing applications with KDE 4? This tutorial series is aimed at those completely new to KDE programming.''&lt;br /&gt;
&lt;br /&gt;
;[[/CMake|Introduction to CMake]]&lt;br /&gt;
:''How to use the CMake build system used by KDE4''&lt;br /&gt;
&lt;br /&gt;
;[[/Using Qt Designer|Using Qt Designer to build user interfaces]]&lt;br /&gt;
:''How to create UI files with designer, and how to integrate them into a KDE program''&lt;br /&gt;
&lt;br /&gt;
;[[/Command-Line Options|Using Command-line Options]]&lt;br /&gt;
:''How to use the KDE Command-line arguments system''&lt;br /&gt;
&lt;br /&gt;
;[[/Debugging|Debugging your application]]&lt;br /&gt;
:''Tips, tools and techniques to apply when debugging your KDE application''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Unittests|Writing Unittests for Qt4 and KDE4 with QTestLib]] ([http://developer.kde.org/documentation/tutorials/writingunittests/writingunittests.html Original link])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to write unit tests using the QTestLib framework. It is presented as an example based tutorial, and is still under development.'' '''Does this belong in this section? It's hardly a beginner tutorial.'''&lt;br /&gt;
&lt;br /&gt;
;[[/Code_Checking|Semi-automatic ways to detect code errors]]&lt;br /&gt;
:''Techniques you can use to detect errors in KDE code'' '''Maybe this should be put under the Dubugging page? Or maybe both these pages should be put in their own subsection on this page?'''&lt;br /&gt;
&lt;br /&gt;
== Managing Configuration Data With KConfig ==&lt;br /&gt;
&lt;br /&gt;
;[[/Using KConfig XT|Using KConfig XT]]&lt;br /&gt;
:''Tutorial on how to efficiently use the KConfig XT framework.''&lt;br /&gt;
&lt;br /&gt;
== File Access With KIO ==&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
;[[/Localization/Unicode|101: Unicode]]&lt;br /&gt;
:''An introduction to what Unicode is as well as how to handle Unicode data in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n|110: Writing Applications With Localization in Mind]]&lt;br /&gt;
:''This tutorial covers what localization is, why it's important and how to ensure your application is ready to be localized. A must read for all application developers.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Mistakes|115: Avoiding Common Localization Pitfalls]]&lt;br /&gt;
:''There are several common mistakes that prevent applications from being properly localized. Find out what they are and how to easily avoid them in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/Building KDE's l10n Module|120: Building KDE's Localization Module]]&lt;br /&gt;
:''Building and installing language support from KDE's localization (l10n) module is a good idea for those working on applications in the main KDE repository. Doing so will allow you to test your application in another language and spot problem areas. Learn how to do just that in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Build Systems|200: Incorporating i18n Into the Build System]]&lt;br /&gt;
:''Once your application is ready to be localized, the next step is to ensure that translation files are built automatically and kept up to date. This tutorial covers the necessary CMakeFiles.txt additions as well the process of distributing the resulting message catalogs with your application.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Challenges|210: Common i18n Challenges and Solutions]]&lt;br /&gt;
:''This tutorial covers challenges that you may eventually run into such as translating handbooks and other data that exists outside of the source code, merging and handling obsolete .po files, deeling with freezes, coding in languages other than English and creating independent releases of or moving applications between KDE modules.''&lt;br /&gt;
&lt;br /&gt;
== Components and Plugins ==&lt;br /&gt;
&lt;br /&gt;
== Application Automation and Scripting ==&lt;br /&gt;
&lt;br /&gt;
=== D-Bus ===&lt;br /&gt;
; [[/D-Bus/Introduction|101: Introduction to D-Bus]]&lt;br /&gt;
:''A straight-forward introduction to the core concepts in D-Bus from an application developer's perspective, this tutorial covers what D-Bus is and how it can be used by applications.''&lt;br /&gt;
; [[/D-Bus/Accessing Interfaces|201: Accessing D-Bus Interfaces]]&lt;br /&gt;
:''A step-by-step guide to calling D-Bus methods and connecting to D-Bus signals using QtDBus.''&lt;br /&gt;
; [[/D-Bus/Creating Interfaces|211: Creating D-Bus Interfaces]]&lt;br /&gt;
:''Learn how to expose functionality in your application by creating and using custom D-Bus interfaces. Covers generating the XML descriptions, instantiating interfaces at run time and setting up the build system with CMake.''&lt;br /&gt;
; [[/D-Bus/Autostart Services|300: D-Bus Autostart Services]]&lt;br /&gt;
:''Turn your application into a D-Bus autostart service with this tutorial. This D-Bus feature will ensure that even when your application isn't running that D-Bus calls made to it will work by relying on the D-Bus daemon itself to start your app if and when needed.''&lt;br /&gt;
&lt;br /&gt;
=== Konqueror ===&lt;br /&gt;
; [[/Creating Konqueror Service Menus|Creating Konqueror Service Menus]]&lt;br /&gt;
:''This tutorial shows you how to create mimetype-specific actions in Konqueror's context menu (aka &amp;quot;servicemenus&amp;quot;).''&lt;br /&gt;
&lt;br /&gt;
===Kross===&lt;br /&gt;
; [[Development/Tutorials/Kross-Tutorial|Kross Tutorial]] ([http://wiki.koffice.org/index.php?title=Kross/Tutorial Original Link])&lt;br /&gt;
:''This tutorial explains how to integrate the Kross scripting framework into an application.''&lt;br /&gt;
&lt;br /&gt;
== Search and Metadata ==&lt;br /&gt;
&lt;br /&gt;
; [[/Writing file analyzers|Writing file analyzers]]&lt;br /&gt;
:''File analyzers extract data from files to display in the file dialogs and file managers. The data gathered this way is also used to search for files. KDE4 allows the use of multiple analyzers per file type. This tutorial describes how you can write new analyzers.''&lt;br /&gt;
&lt;br /&gt;
== Hardware Awareness ==&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Tutorials|Introduction to Solid]]&lt;br /&gt;
:''An introduction to using the Solid hardware discovery and interaction system in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Network_Tutorial|Accessing Network Information]]&lt;br /&gt;
:''How to use the Solid system to get information about the network''&lt;br /&gt;
&lt;br /&gt;
==Printing==&lt;br /&gt;
&lt;br /&gt;
;[[/Printing Hello World|101: Hello World]]&lt;br /&gt;
:''Introduction to the KDE printing system''&lt;br /&gt;
&lt;br /&gt;
;TODO 110 Print Dialog&lt;br /&gt;
:''Using the KDE print dialog''&lt;br /&gt;
&lt;br /&gt;
== Get Hot New Stuff ==&lt;br /&gt;
; [[Development/Tutorials/Introduction to Get Hot New Stuff|Introduction to Get Hot New Stuff]]&lt;br /&gt;
:''An introduction to the developer-friendly network update system that allows KDE applications to fetch new application data at runtime in a user friendly manner.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KNewStuffSecure|KNewStuff Secure]] ([http://developer.kde.org/documentation/tutorials/knewstuffsecure/index.html Original Link])&lt;br /&gt;
:''Tutorial showing how to share resources in a secured way (KDE 3.4 and later).''  By Andr&amp;amp;#225;s Mantia &amp;amp;lt;amantia@kde.org&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Rapid Application Development ==&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/101_Python_introduction_to_signal_and_slots|101 Introduction to signal and slots]]&lt;br /&gt;
:''A simple introduction to QT's signal and slots architecture.''&lt;br /&gt;
&lt;br /&gt;
;[http://www.xs4all.nl/~bsarempt/python/tutorial.html KDE-Python tutorial]&lt;br /&gt;
:''A python version of Daniel's KDE tutorial by Boudewijn Rempt.''&lt;br /&gt;
&lt;br /&gt;
=== Ruby ===&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/language-bindings/ruby/kde3tutorial/index.html KDE Ruby Korundum tutorial]&lt;br /&gt;
:''A ruby version of Antonio Larrosa Jim&amp;amp;eacute;nez's KDE tutorial by Richard Dale. See the [http://developer.kde.org/language-bindings/ruby/index.html Ruby Developers Corner] for Qt tutorials and other info.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Qt4_Ruby_Tutorial|Qt4 Ruby Tutorial]]&lt;br /&gt;
:''Trolltech's fabulous introductory tutorial to Qt, translated to Ruby.''&lt;br /&gt;
&lt;br /&gt;
=== Shell ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Shell_Scripting_with_KDE_Dialogs|Shell Scripting with KDE dialogs]] ([http://developer.kde.org/documentation/tutorials/kdialog-german/t1.html German Version])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to use KDE dialogs in shell scripts with kdialog. It is presented as an example based tutorial.''&lt;br /&gt;
&lt;br /&gt;
== Other tutorials ==&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/documentation/tutorials/kdeeduplot/kdeeduplot_tutorial.tar.bz2 Using and extending the KDE EDU Plot widget (docbook archive)]&lt;br /&gt;
:''This tutorial introduces Jason Harris' KPlotWidget that is part of the KDE EDU package. Contains information about defining your own widget in QT / KDevelop designer and about subclassing widgets and overriding member functions to extend functionality.''&lt;br /&gt;
&lt;br /&gt;
== KDE2 and KDE3 Materials ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE3|KDE3 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE3.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE2|KDE2 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE2.''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials</id>
		<title>Development/Tutorials</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials"/>
				<updated>2007-01-12T03:29:22Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Get Hot New Stuff */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tutorials are the fastest way of finding out what KDE will do for you, and how to do it. Here is a list of currently available tutorials.&lt;br /&gt;
&lt;br /&gt;
== Getting started ==&lt;br /&gt;
;[[/Programming Tutorial KDE 4|Introduction To KDE 4 Programming]]&lt;br /&gt;
:''You are interested in writing applications with KDE 4? This tutorial series is aimed at those completely new to KDE programming.''&lt;br /&gt;
&lt;br /&gt;
;[[/CMake|Introduction to CMake]]&lt;br /&gt;
:''How to use the CMake build system used by KDE4''&lt;br /&gt;
&lt;br /&gt;
;[[/Using Qt Designer|Using Qt Designer to build user interfaces]]&lt;br /&gt;
:''How to create UI files with designer, and how to integrate them into a KDE program''&lt;br /&gt;
&lt;br /&gt;
;[[/Command-Line Options|Using Command-line Options]]&lt;br /&gt;
:''How to use the KDE Command-line arguments system''&lt;br /&gt;
&lt;br /&gt;
;[[/Debugging|Debugging your application]]&lt;br /&gt;
:''Tips, tools and techniques to apply when debugging your KDE application''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Unittests|Writing Unittests for Qt4 and KDE4 with QTestLib]] ([http://developer.kde.org/documentation/tutorials/writingunittests/writingunittests.html Original link])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to write unit tests using the QTestLib framework. It is presented as an example based tutorial, and is still under development.'' '''Does this belong in this section? It's hardly a beginner tutorial.'''&lt;br /&gt;
&lt;br /&gt;
;[[/Code_Checking|Semi-automatic ways to detect code errors]]&lt;br /&gt;
:''Techniques you can use to detect errors in KDE code'' '''Maybe this should be put under the Dubugging page? Or maybe both these pages should be put in their own subsection on this page?'''&lt;br /&gt;
&lt;br /&gt;
== Managing Configuration Data With KConfig ==&lt;br /&gt;
&lt;br /&gt;
;[[/Using KConfig XT|Using KConfig XT]]&lt;br /&gt;
:''Tutorial on how to efficiently use the KConfig XT framework.''&lt;br /&gt;
&lt;br /&gt;
== File Access With KIO ==&lt;br /&gt;
&lt;br /&gt;
== Localization ==&lt;br /&gt;
;[[/Localization/Unicode|101: Unicode]]&lt;br /&gt;
:''An introduction to what Unicode is as well as how to handle Unicode data in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n|110: Writing Applications With Localization in Mind]]&lt;br /&gt;
:''This tutorial covers what localization is, why it's important and how to ensure your application is ready to be localized. A must read for all application developers.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Mistakes|115: Avoiding Common Localization Pitfalls]]&lt;br /&gt;
:''There are several common mistakes that prevent applications from being properly localized. Find out what they are and how to easily avoid them in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/Building KDE's l10n Module|120: Building KDE's Localization Module]]&lt;br /&gt;
:''Building and installing language support from KDE's localization (l10n) module is a good idea for those working on applications in the main KDE repository. Doing so will allow you to test your application in another language and spot problem areas. Learn how to do just that in this tutorial.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Build Systems|200: Incorporating i18n Into the Build System]]&lt;br /&gt;
:''Once your application is ready to be localized, the next step is to ensure that translation files are built automatically and kept up to date. This tutorial covers the necessary CMakeFiles.txt additions as well the process of distributing the resulting message catalogs with your application.''&lt;br /&gt;
&lt;br /&gt;
; [[/Localization/i18n Challenges|210: Common i18n Challenges and Solutions]]&lt;br /&gt;
:''This tutorial covers challenges that you may eventually run into such as translating handbooks and other data that exists outside of the source code, merging and handling obsolete .po files, deeling with freezes, coding in languages other than English and creating independent releases of or moving applications between KDE modules.''&lt;br /&gt;
&lt;br /&gt;
== Components and Plugins ==&lt;br /&gt;
&lt;br /&gt;
== Application Automation and Scripting ==&lt;br /&gt;
&lt;br /&gt;
=== D-Bus ===&lt;br /&gt;
; [[/D-Bus/Introduction|101: Introduction to D-Bus]]&lt;br /&gt;
:''A straight-forward introduction to the core concepts in D-Bus from an application developer's perspective, this tutorial covers what D-Bus is and how it can be used by applications.''&lt;br /&gt;
; [[/D-Bus/Accessing Interfaces|201: Accessing D-Bus Interfaces]]&lt;br /&gt;
:''A step-by-step guide to calling D-Bus methods and connecting to D-Bus signals using QtDBus.''&lt;br /&gt;
; [[/D-Bus/Creating Interfaces|211: Creating D-Bus Interfaces]]&lt;br /&gt;
:''Learn how to expose functionality in your application by creating and using custom D-Bus interfaces. Covers generating the XML descriptions, instantiating interfaces at run time and setting up the build system with CMake.''&lt;br /&gt;
; [[/D-Bus/Autostart Services|300: D-Bus Autostart Services]]&lt;br /&gt;
:''Turn your application into a D-Bus autostart service with this tutorial. This D-Bus feature will ensure that even when your application isn't running that D-Bus calls made to it will work by relying on the D-Bus daemon itself to start your app if and when needed.''&lt;br /&gt;
&lt;br /&gt;
=== Konqueror ===&lt;br /&gt;
; [[/Creating Konqueror Service Menus|Creating Konqueror Service Menus]]&lt;br /&gt;
:''This tutorial shows you how to create mimetype-specific actions in Konqueror's context menu (aka &amp;quot;servicemenus&amp;quot;).''&lt;br /&gt;
&lt;br /&gt;
===Kross===&lt;br /&gt;
; [[Development/Tutorials/Kross-Tutorial|Kross Tutorial]] ([http://wiki.koffice.org/index.php?title=Kross/Tutorial Original Link])&lt;br /&gt;
:''This tutorial explains how to integrate the Kross scripting framework into an application.''&lt;br /&gt;
&lt;br /&gt;
== Search and Metadata ==&lt;br /&gt;
&lt;br /&gt;
; [[/Writing file analyzers|Writing file analyzers]]&lt;br /&gt;
:''File analyzers extract data from files to display in the file dialogs and file managers. The data gathered this way is also used to search for files. KDE4 allows the use of multiple analyzers per file type. This tutorial describes how you can write new analyzers.''&lt;br /&gt;
&lt;br /&gt;
== Hardware Awareness ==&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Tutorials|Introduction to Solid]]&lt;br /&gt;
:''An introduction to using the Solid hardware discovery and interaction system in KDE applications.''&lt;br /&gt;
&lt;br /&gt;
;[[/Solid_Network_Tutorial|Accessing Network Information]]&lt;br /&gt;
:''How to use the Solid system to get information about the network''&lt;br /&gt;
&lt;br /&gt;
==Printing==&lt;br /&gt;
&lt;br /&gt;
;[[/Printing Hello World|101: Hello World]]&lt;br /&gt;
:''Introduction to the KDE printing system''&lt;br /&gt;
&lt;br /&gt;
;TODO 110 Print Dialog&lt;br /&gt;
:''Using the KDE print dialog''&lt;br /&gt;
&lt;br /&gt;
== Get Hot New Stuff ==&lt;br /&gt;
; [[Development/Tutorials/Introduction to Get Hot New Stuff|Introduction to Get Hot New Stuff]]&lt;br /&gt;
:''An introduction to the developer-friendly network update system that allows KDE applications to fetch new application data at runtime in a user friendly manner.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KNewStuffSecure|KNewStuff Secure]] ([http://developer.kde.org/documentation/tutorials/knewstuffsecure/index.html Original Link])&lt;br /&gt;
:''Tutorial showing how to share resources in a secured way (KDE 3.4 and later).''  By Andr&amp;amp;#225;s Mantia &amp;amp;lt;amantia@kde.org&amp;amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Rapid Application Development ==&lt;br /&gt;
&lt;br /&gt;
=== Python ===&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/101_Python_introduction_to_signal_and_slots|101 Introduction to signal and slots]]&lt;br /&gt;
:''A simple introduction to QT's signal and slots architecture.''&lt;br /&gt;
&lt;br /&gt;
;[http://www.xs4all.nl/~bsarempt/python/tutorial.html KDE-Python tutorial]&lt;br /&gt;
:''A python version of Daniel's KDE tutorial by Boudewijn Rempt.''&lt;br /&gt;
&lt;br /&gt;
=== Ruby ===&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/language-bindings/ruby/kde3tutorial/index.html KDE Ruby Korundum tutorial]&lt;br /&gt;
:''A ruby version of Antonio Larrosa Jim&amp;amp;eacute;nez's KDE tutorial by Richard Dale. See the [http://developer.kde.org/language-bindings/ruby/index.html Ruby Developers Corner] for Qt tutorials and other info.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/Qt4_Ruby_Tutorial|Qt4 Ruby Tutorial]]&lt;br /&gt;
:''Trolltech's fabulous introductory tutorial to Qt, translated to Ruby.''&lt;br /&gt;
&lt;br /&gt;
=== Shell ===&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/documentation/tutorials/kdialog/t1.html Shell Scripting with KDE dialogs] ([http://developer.kde.org/documentation/tutorials/kdialog-german/t1.html German Version])&lt;br /&gt;
:''Tutorial by [mailto:bradh@frogmouth.net Brad Hards] that describes how to use KDE dialogs in shell scripts with kdialog. It is presented as an example based tutorial.''&lt;br /&gt;
&lt;br /&gt;
== Other tutorials ==&lt;br /&gt;
&lt;br /&gt;
;[http://developer.kde.org/documentation/tutorials/kdeeduplot/kdeeduplot_tutorial.tar.bz2 Using and extending the KDE EDU Plot widget (docbook archive)]&lt;br /&gt;
:''This tutorial introduces Jason Harris' KPlotWidget that is part of the KDE EDU package. Contains information about defining your own widget in QT / KDevelop designer and about subclassing widgets and overriding member functions to extend functionality.''&lt;br /&gt;
&lt;br /&gt;
== KDE2 and KDE3 Materials ==&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE3|KDE3 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE3.''&lt;br /&gt;
&lt;br /&gt;
;[[Development/Tutorials/KDE2|KDE2 Tutorials]]&lt;br /&gt;
:''These tutorials cover topics related to KDE2.''&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff</id>
		<title>Development/Tutorials/Introduction to Get Hot New Stuff</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff"/>
				<updated>2007-01-12T03:26:05Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Preparations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Similar to how programming languages shifted focus from algorithms to data structures in the 70s, desktop application development emphasizes more and more on user data, i.e. data intentionally produced or consumed by the user. Both on the internet and in corporate intranets, sharing this data is considered an easy way to customize desktops and to advertise one's creativity. The 'Get Hot New Stuff' (GHNS) framework in KDE exists to support this approach, and the KNewStuff library is the key for application authors to enable GHNS.&lt;br /&gt;
&lt;br /&gt;
== Preparations ==&lt;br /&gt;
The first steps are usually made in preparing the usage of KNewStuff. For this matter, the library must be available (a task which could be done using autoconf, but since it's part of kdelibs, we simply assume it's available with any recent KDE installation.) Authors of 3rd pary applications can ensure the availability as part of kdepim-libs in KDE 3.2 using the AC_KNEWSTUFF macro. It must also be included in the set of libraries against which the application is linked, so modifying the Makefile.am and reconfiguring the application are to be done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
bin_PROGRAMS = myapp&lt;br /&gt;
myapp_LDADD = $(LIB_KDECORE) ... -lknewstuff&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The header files are installed under $kdedir/include/knewstuff/, so in the relevant files, they're included with statements such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/downloaddialog.h&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The following header files are provided by KNewStuff:&lt;br /&gt;
* downloaddialog.h: Easy to use download dialog&lt;br /&gt;
* engine.h: Access to the complex, but customizable background operations&lt;br /&gt;
* entry.h: (internal) Data fields of entries, such as Author or Title&lt;br /&gt;
* ghns.h: [not installed]&lt;br /&gt;
* knewstuffgeneric.h: Easy to use installation handler for the downloaded files&lt;br /&gt;
* knewstuff.h: Main knewstuff functionality&lt;br /&gt;
* providerdialog.h: Preconfigured dialog for provider selection&lt;br /&gt;
* provider.h: Provider entries, and ProviderLoader&lt;br /&gt;
* testnewstuff.h: [not installed]&lt;br /&gt;
* uploaddialog.h: Easy to use upload dialog&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For more information on the background processes, please have a look at the information provided by [http://www.kstuff.org/docs/ kstuff.org]. However application authors should only need a basic understanding of those.&lt;br /&gt;
&lt;br /&gt;
== Downloading Data ==&lt;br /&gt;
&lt;br /&gt;
Depending on the application, providing additional data can be accomplished using the 'File Import' dialog, 'Internet Level' menu item, or just an 'Update now' KAction. All of those have in common that they invoke a slot which will contain the actual KNewStuff calls. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void MyApp::slotDownload()&lt;br /&gt;
{&lt;br /&gt;
  KNewStuff::DownloadDialog::open(&amp;quot;myapp/templates&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is all. If desired, more control can be exercised on the whole download process, as outlined below. For the beginning, the above is already fully functional, and should be used at first. &lt;br /&gt;
&lt;br /&gt;
== Downloading in Detail ==&lt;br /&gt;
The example above implicitely constructs an internal Engine object, retrieves the directory list, fetches the provider lists specified in the directory, and the entries in each of the provider lists, compares them to the data files previously installed, and displays them in the download dialog. This dialog in turn handles all the installation issues. Of course there is no magic involved, and for more control about the subtasks, the following is recommended: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(to be precised)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Similar to the provider list, the installation procedures are described in the application's configuration file. The default (if these entries are missing) is to just download the file to a temporary location, which is not useful in most of the cases. There are two entries: target location, and post-installation command. The target location can either be StandardResource, matching the KDE resource types, or TargetDir, matching an application directory under $KDEHOME/share/apps/appname. The post installation command can be a binary with '%f' as parameter (note the single quotes to prevent string format attacks), but it can as well be a DCOP call, so the application can directly work with the data. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[KNewStuff]&lt;br /&gt;
StandardResource=wallpaper&lt;br /&gt;
InstallationCommand=dcop kdesktop KBackgroundIface setWallpaper '%f' 2&lt;br /&gt;
&lt;br /&gt;
TargetDir=kamikaze&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uploads ==&lt;br /&gt;
&lt;br /&gt;
The beginning of the upload process works similar to downloads. A MasterServer or ProvidersUrl is used to retrieve the provider list, and one of the providers is selected by the user. Only providers which allow uploads are taken into account. After this selection however, the differences begin. The user has to fill in the necessary information such as title, author name or version number into the upload dialog. Also, the payload and preview files have to be selected, this however will in most cases be the application's task.  In Kamikaze, the level file is pre-rendered to an invisible QCanvas, and the resulting graphics is minimized and automatically specified for the upload.  The upload will then happen using the protocol accepted by the provider, which in most cases will be anonymous FTP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
#include &amp;lt;knewstuff/knewstuffgeneric.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/engine.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/uploaddialog.h&amp;gt;&lt;br /&gt;
// ...&lt;br /&gt;
QString file, previewfile;&lt;br /&gt;
KNewStuffGeneric *ns = new KNewStuffGeneric(&amp;quot;myapp/templates&amp;quot;, this);&lt;br /&gt;
ns-&amp;gt;upload(file.name(), previewfile.name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Sharing creativity should become a default property of modern desktops, and KDE once again leads the pack by providing both upload and download facilities. If enough applications of different areas make use of them, it helps users to be more productive and have more fun with their computer.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff</id>
		<title>Development/Tutorials/Introduction to Get Hot New Stuff</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff"/>
				<updated>2007-01-12T03:25:11Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Preparations */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Similar to how programming languages shifted focus from algorithms to data structures in the 70s, desktop application development emphasizes more and more on user data, i.e. data intentionally produced or consumed by the user. Both on the internet and in corporate intranets, sharing this data is considered an easy way to customize desktops and to advertise one's creativity. The 'Get Hot New Stuff' (GHNS) framework in KDE exists to support this approach, and the KNewStuff library is the key for application authors to enable GHNS.&lt;br /&gt;
&lt;br /&gt;
== Preparations ==&lt;br /&gt;
The first steps are usually made in preparing the usage of KNewStuff. For this matter, the library must be available (a task which could be done using autoconf, but since it's part of kdelibs, we simply assume it's available with any recent KDE installation.) Authors of 3rd pary applications can ensure the availability as part of kdepim-libs in KDE 3.2 using the AC_KNEWSTUFF macro. It must also be included in the set of libraries against which the application is linked, so modifying the Makefile.am and reconfiguring the application are to be done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
bin_PROGRAMS = myapp&lt;br /&gt;
myapp_LDADD = $(LIB_KDECORE) ... -lknewstuff&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The header files are installed under $kdedir/include/knewstuff/, so in the relevant files, they're included with statements such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/downloaddialog.h&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The following header files are provided by KNewStuff:&lt;br /&gt;
* downloaddialog.h: Easy to use download dialog&lt;br /&gt;
* engine.h: Access to the complex, but customizable background operations&lt;br /&gt;
* entry.h: (internal) Data fields of entries, such as Author or Title&lt;br /&gt;
* ghns.h: [not installed]&lt;br /&gt;
* knewstuffgeneric.h: Easy to use installation handler for the downloaded files&lt;br /&gt;
* knewstuff.h: Main knewstuff functionality&lt;br /&gt;
* providerdialog.h: Preconfigured dialog for provider selection&lt;br /&gt;
* provider.h: Provider entries, and ProviderLoader&lt;br /&gt;
* testnewstuff.h: [not installed]&lt;br /&gt;
* uploaddialog.h: Easy to use upload dialog&lt;br /&gt;
&lt;br /&gt;
For more information on the background processes, please have a look at the information provided by [http://www.kstuff.org/docs/ kstuff.org]. However application authors should only need a basic understanding of those.&lt;br /&gt;
&lt;br /&gt;
== Downloading Data ==&lt;br /&gt;
&lt;br /&gt;
Depending on the application, providing additional data can be accomplished using the 'File Import' dialog, 'Internet Level' menu item, or just an 'Update now' KAction. All of those have in common that they invoke a slot which will contain the actual KNewStuff calls. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void MyApp::slotDownload()&lt;br /&gt;
{&lt;br /&gt;
  KNewStuff::DownloadDialog::open(&amp;quot;myapp/templates&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is all. If desired, more control can be exercised on the whole download process, as outlined below. For the beginning, the above is already fully functional, and should be used at first. &lt;br /&gt;
&lt;br /&gt;
== Downloading in Detail ==&lt;br /&gt;
The example above implicitely constructs an internal Engine object, retrieves the directory list, fetches the provider lists specified in the directory, and the entries in each of the provider lists, compares them to the data files previously installed, and displays them in the download dialog. This dialog in turn handles all the installation issues. Of course there is no magic involved, and for more control about the subtasks, the following is recommended: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(to be precised)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Similar to the provider list, the installation procedures are described in the application's configuration file. The default (if these entries are missing) is to just download the file to a temporary location, which is not useful in most of the cases. There are two entries: target location, and post-installation command. The target location can either be StandardResource, matching the KDE resource types, or TargetDir, matching an application directory under $KDEHOME/share/apps/appname. The post installation command can be a binary with '%f' as parameter (note the single quotes to prevent string format attacks), but it can as well be a DCOP call, so the application can directly work with the data. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[KNewStuff]&lt;br /&gt;
StandardResource=wallpaper&lt;br /&gt;
InstallationCommand=dcop kdesktop KBackgroundIface setWallpaper '%f' 2&lt;br /&gt;
&lt;br /&gt;
TargetDir=kamikaze&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uploads ==&lt;br /&gt;
&lt;br /&gt;
The beginning of the upload process works similar to downloads. A MasterServer or ProvidersUrl is used to retrieve the provider list, and one of the providers is selected by the user. Only providers which allow uploads are taken into account. After this selection however, the differences begin. The user has to fill in the necessary information such as title, author name or version number into the upload dialog. Also, the payload and preview files have to be selected, this however will in most cases be the application's task.  In Kamikaze, the level file is pre-rendered to an invisible QCanvas, and the resulting graphics is minimized and automatically specified for the upload.  The upload will then happen using the protocol accepted by the provider, which in most cases will be anonymous FTP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
#include &amp;lt;knewstuff/knewstuffgeneric.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/engine.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/uploaddialog.h&amp;gt;&lt;br /&gt;
// ...&lt;br /&gt;
QString file, previewfile;&lt;br /&gt;
KNewStuffGeneric *ns = new KNewStuffGeneric(&amp;quot;myapp/templates&amp;quot;, this);&lt;br /&gt;
ns-&amp;gt;upload(file.name(), previewfile.name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Sharing creativity should become a default property of modern desktops, and KDE once again leads the pack by providing both upload and download facilities. If enough applications of different areas make use of them, it helps users to be more productive and have more fun with their computer.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff</id>
		<title>Development/Tutorials/Introduction to Get Hot New Stuff</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Introduction_to_Get_Hot_New_Stuff"/>
				<updated>2007-01-12T03:24:15Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Introduction ==&lt;br /&gt;
Similar to how programming languages shifted focus from algorithms to data structures in the 70s, desktop application development emphasizes more and more on user data, i.e. data intentionally produced or consumed by the user. Both on the internet and in corporate intranets, sharing this data is considered an easy way to customize desktops and to advertise one's creativity. The 'Get Hot New Stuff' (GHNS) framework in KDE exists to support this approach, and the KNewStuff library is the key for application authors to enable GHNS.&lt;br /&gt;
&lt;br /&gt;
== Preparations ==&lt;br /&gt;
The first steps are usually made in preparing the usage of KNewStuff. For this matter, the library must be available (a task which could be done using autoconf, but since it's part of kdelibs, we simply assume it's available with any recent KDE installation.) Authors of 3rd pary applications can ensure the availability as part of kdepim-libs in KDE 3.2 using the AC_KNEWSTUFF macro. It must also be included in the set of libraries against which the application is linked, so modifying the Makefile.am and reconfiguring the application are to be done.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
          bin_PROGRAMS = myapp&lt;br /&gt;
          myapp_LDADD = $(LIB_KDECORE) ... -lknewstuff&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The header files are installed under $kdedir/include/knewstuff/, so in the relevant files, they're included with statements such as:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
          #include &amp;lt;knewstuff/downloaddialog.h&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
          &lt;br /&gt;
The following header files are provided by KNewStuff:&lt;br /&gt;
* downloaddialog.h: Easy to use download dialog&lt;br /&gt;
* engine.h: Access to the complex, but customizable background operations&lt;br /&gt;
* entry.h: (internal) Data fields of entries, such as Author or Title&lt;br /&gt;
* ghns.h: [not installed]&lt;br /&gt;
* knewstuffgeneric.h: Easy to use installation handler for the downloaded files&lt;br /&gt;
* knewstuff.h: Main knewstuff functionality&lt;br /&gt;
* providerdialog.h: Preconfigured dialog for provider selection&lt;br /&gt;
* provider.h: Provider entries, and ProviderLoader&lt;br /&gt;
* testnewstuff.h: [not installed]&lt;br /&gt;
* uploaddialog.h: Easy to use upload dialog&lt;br /&gt;
&lt;br /&gt;
For more information on the background processes, please have a look at the information provided by [http://www.kstuff.org/docs/ kstuff.org]. However application authors should only need a basic understanding of those. &lt;br /&gt;
&lt;br /&gt;
== Downloading Data ==&lt;br /&gt;
&lt;br /&gt;
Depending on the application, providing additional data can be accomplished using the 'File Import' dialog, 'Internet Level' menu item, or just an 'Update now' KAction. All of those have in common that they invoke a slot which will contain the actual KNewStuff calls. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void MyApp::slotDownload()&lt;br /&gt;
{&lt;br /&gt;
  KNewStuff::DownloadDialog::open(&amp;quot;myapp/templates&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This is all. If desired, more control can be exercised on the whole download process, as outlined below. For the beginning, the above is already fully functional, and should be used at first. &lt;br /&gt;
&lt;br /&gt;
== Downloading in Detail ==&lt;br /&gt;
The example above implicitely constructs an internal Engine object, retrieves the directory list, fetches the provider lists specified in the directory, and the entries in each of the provider lists, compares them to the data files previously installed, and displays them in the download dialog. This dialog in turn handles all the installation issues. Of course there is no magic involved, and for more control about the subtasks, the following is recommended: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
(to be precised)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Installation ==&lt;br /&gt;
&lt;br /&gt;
Similar to the provider list, the installation procedures are described in the application's configuration file. The default (if these entries are missing) is to just download the file to a temporary location, which is not useful in most of the cases. There are two entries: target location, and post-installation command. The target location can either be StandardResource, matching the KDE resource types, or TargetDir, matching an application directory under $KDEHOME/share/apps/appname. The post installation command can be a binary with '%f' as parameter (note the single quotes to prevent string format attacks), but it can as well be a DCOP call, so the application can directly work with the data. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[KNewStuff]&lt;br /&gt;
StandardResource=wallpaper&lt;br /&gt;
InstallationCommand=dcop kdesktop KBackgroundIface setWallpaper '%f' 2&lt;br /&gt;
&lt;br /&gt;
TargetDir=kamikaze&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Uploads ==&lt;br /&gt;
&lt;br /&gt;
The beginning of the upload process works similar to downloads. A MasterServer or ProvidersUrl is used to retrieve the provider list, and one of the providers is selected by the user. Only providers which allow uploads are taken into account. After this selection however, the differences begin. The user has to fill in the necessary information such as title, author name or version number into the upload dialog. Also, the payload and preview files have to be selected, this however will in most cases be the application's task.  In Kamikaze, the level file is pre-rendered to an invisible QCanvas, and the resulting graphics is minimized and automatically specified for the upload.  The upload will then happen using the protocol accepted by the provider, which in most cases will be anonymous FTP.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
#include &amp;lt;knewstuff/knewstuffgeneric.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/engine.h&amp;gt;&lt;br /&gt;
#include &amp;lt;knewstuff/uploaddialog.h&amp;gt;&lt;br /&gt;
// ...&lt;br /&gt;
QString file, previewfile;&lt;br /&gt;
KNewStuffGeneric *ns = new KNewStuffGeneric(&amp;quot;myapp/templates&amp;quot;, this);&lt;br /&gt;
ns-&amp;gt;upload(file.name(), previewfile.name());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Conclusion ==&lt;br /&gt;
&lt;br /&gt;
Sharing creativity should become a default property of modern desktops, and KDE once again leads the pack by providing both upload and download facilities. If enough applications of different areas make use of them, it helps users to be more productive and have more fun with their computer.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T03:15:50Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Progress Dialogs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
Original - http://developer.kde.org/documentation/tutorials/kdialog/t1.html&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename. In the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
&lt;br /&gt;
The return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses ''Cancel'', no output is sent.&lt;br /&gt;
&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the ''--separate-output'' to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for the menu example, the return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
&lt;br /&gt;
The dialog to select a file to open is invoked with ''--getopenfilename'' or ''--getopenurl''. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
&lt;br /&gt;
As for previous examples, the return value depends on the button used. ''OK'' returns '''0'''. Cancel returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --getopenfilename .&lt;br /&gt;
/home/watson/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[watson@bakerst]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/watson/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the user can only select an existing file with these options. When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labeling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename ~/doc/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
&lt;br /&gt;
The ''--getsavefilename'' and ''--getsaveurl'' commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist. As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the ''--getexistingdirectory'' type, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
&lt;br /&gt;
''--getexistingdirectory'' does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
&lt;br /&gt;
A simple use of the ''--progressbar'' command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T03:14:08Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* File Selection Dialogs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
Original - http://developer.kde.org/documentation/tutorials/kdialog/t1.html&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename. In the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
&lt;br /&gt;
The return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses ''Cancel'', no output is sent.&lt;br /&gt;
&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the ''--separate-output'' to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for the menu example, the return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
&lt;br /&gt;
The dialog to select a file to open is invoked with ''--getopenfilename'' or ''--getopenurl''. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
&lt;br /&gt;
As for previous examples, the return value depends on the button used. ''OK'' returns '''0'''. Cancel returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --getopenfilename .&lt;br /&gt;
/home/watson/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[watson@bakerst]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/watson/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that the user can only select an existing file with these options. When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labeling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename ~/doc/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
&lt;br /&gt;
The ''--getsavefilename'' and ''--getsaveurl'' commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist. As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the ''--getexistingdirectory'' type, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
&lt;br /&gt;
''--getexistingdirectory'' does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T03:08:53Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Menu and Selection Dialogs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
Original - http://developer.kde.org/documentation/tutorials/kdialog/t1.html&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename. In the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
&lt;br /&gt;
The return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses ''Cancel'', no output is sent.&lt;br /&gt;
&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the ''--separate-output'' to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
As for the menu example, the return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:57:11Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Displaying files */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
Original - http://developer.kde.org/documentation/tutorials/kdialog/t1.html&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename. In the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
&lt;br /&gt;
The return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses ''Cancel'', no output is sent.&lt;br /&gt;
&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:56:02Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
Original - http://developer.kde.org/documentation/tutorials/kdialog/t1.html&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename. In the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
&lt;br /&gt;
The return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses ''Cancel'', no output is sent.&lt;br /&gt;
&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:54:50Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* User Input dialogs */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename. In the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
&lt;br /&gt;
The return value depends on the button used. ''OK'' returns '''0'''. ''Cancel'' returns '''1'''.&lt;br /&gt;
&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses ''Cancel'', no output is sent.&lt;br /&gt;
&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:49:03Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Suppressing the display of a dialog */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename. In the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
An input dialog box is shown below.&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
An input dialog box with initial default text is shown below.&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
The return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses Cancel, no output is sent.&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:46:38Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* More Message Boxes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A ''Yes'', ''OK'' or ''Continue'' returns '''0'''. A ''No'' returns '''1'''. A ''Cancel'' returns '''2'''.&lt;br /&gt;
&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
A typical information level message box, with --dontagain is shown below.&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename, entry tuple (in the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
An input dialog box is shown below.&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
An input dialog box with initial default text is shown below.&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
The return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses Cancel, no output is sent.&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:44:10Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Non-Interrupting Notifications */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
A Yes/No message box is shown below.&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
A Yes/No warning box is shown below.&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
A Continue/Cancel warning box is shown below.&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
A Yes/No/Cancel message box is shown below.&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
A Yes/No/Cancel warning message box is shown below.&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A Yes, OK or Continue returns zero. A No returns one. A Cancel returns two.&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
A typical information level message box, with --dontagain is shown below.&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename, entry tuple (in the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
An input dialog box is shown below.&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
An input dialog box with initial default text is shown below.&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
The return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses Cancel, no output is sent.&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:43:12Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Basic message boxes */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
A passive popup is shown below.&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
A Yes/No message box is shown below.&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
A Yes/No warning box is shown below.&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
A Continue/Cancel warning box is shown below.&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
A Yes/No/Cancel message box is shown below.&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
A Yes/No/Cancel warning message box is shown below.&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A Yes, OK or Continue returns zero. A No returns one. A Cancel returns two.&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
A typical information level message box, with --dontagain is shown below.&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename, entry tuple (in the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
An input dialog box is shown below.&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
An input dialog box with initial default text is shown below.&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
The return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses Cancel, no output is sent.&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:37:08Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&lt;br /&gt;
The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result?&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Dialog Types ==&lt;br /&gt;
&lt;br /&gt;
The password dialog is just one of the many dialogs that kdialog can provide. This section provides an overview of each type, and describes the arguments you need to provide for each dialog type.&lt;br /&gt;
&lt;br /&gt;
=== Basic message boxes ===&lt;br /&gt;
Basic message boxes are intended to provide status type information. There are variations to indicate the importance of the information (information, warnings, or errors). In each case, the argument is the text to provide, as shown in the following examples.&lt;br /&gt;
Example 8. Information level message box&lt;br /&gt;
kdialog --msgbox &amp;quot;Password correct.\n About to connect to server&amp;quot;&lt;br /&gt;
A typical information level message box is shown below.&lt;br /&gt;
Figure 3. Information level message box screenshot&lt;br /&gt;
Example 9. Sorry level message box&lt;br /&gt;
kdialog --sorry &amp;quot;Password incorrect.\n Will not connect to server&amp;quot;&lt;br /&gt;
A typical sorry level message box is shown below.&lt;br /&gt;
Figure 4. Sorry level message box screenshot&lt;br /&gt;
Example 10. Error level message box&lt;br /&gt;
kdialog --error &amp;quot;Server protocol error.&amp;quot;&lt;br /&gt;
A typical error level message box is shown below.&lt;br /&gt;
Figure 5. Error level message box screenshot&lt;br /&gt;
The return value for these basic message boxes is zero.&lt;br /&gt;
While not used in these examples, you can use the --title to set the window title as well. This option can be used with any of the dialog types.&lt;br /&gt;
=== Non-Interrupting Notifications ===&lt;br /&gt;
kdialog supports the concept of a popup dialog that does not grab focus, called a passive popup.&lt;br /&gt;
--passivepopup takes a text label to display, and a timeout. The display will be automatically removed when the timeout (which is in seconds) has elapsed, or when the user clicks on the popup.&lt;br /&gt;
Example 11. --passivepopup dialog box&lt;br /&gt;
kdialog --title &amp;quot;This is a passive popup&amp;quot; --passivepopup \&lt;br /&gt;
&amp;quot;It will disappear in about 10 seconds&amp;quot; 10&lt;br /&gt;
A passive popup is shown below.&lt;br /&gt;
Figure 6. --passivepopup dialog box screenshot&lt;br /&gt;
=== More Message Boxes ===&lt;br /&gt;
Sometimes you need more than the basic message box allows. Perhaps you have a potentially dangerous action, and you need to give the user a second chance. Or perhaps you just need a decision based on some information. kdialog provides some of the tools you might need.&lt;br /&gt;
A --yesno type dialog is probably the simplest of this type, as shown below. Like the simple message boxes previously, it requires a text string, which is shown in the message box.&lt;br /&gt;
Example 12. --yesno message box&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo dialog&amp;quot; --yesno &amp;quot;System is not \&lt;br /&gt;
currently connected.\n Do you want to connect now?&amp;quot;&lt;br /&gt;
A Yes/No message box is shown below.&lt;br /&gt;
Figure 7. --yesno message box screenshot&lt;br /&gt;
A variation on the --yesno dialog type is the --warningyesno, which modifies the dialog box appearance a bit.&lt;br /&gt;
Example 13. --warningyesno message box&lt;br /&gt;
kdialog --title &amp;quot;Example YesNo warning dialog&amp;quot; --warningyesno &amp;quot;Are \&lt;br /&gt;
you sure you want to delete all that hard work?&amp;quot;&lt;br /&gt;
A Yes/No warning box is shown below.&lt;br /&gt;
Figure 8. --warningyesno warning screenshot&lt;br /&gt;
A further variation is to use a --warningcontinuecancel dialog type, which has the same usage, but has different button labels, and may fit some situations better.&lt;br /&gt;
Example 14. --warningcontinuecancel message box&lt;br /&gt;
kdialog --title &amp;quot;Example ContinueCancel warning dialog&amp;quot; \&lt;br /&gt;
--warningcontinuecancel &amp;quot;Are you sure you want to delete all that \&lt;br /&gt;
hard work?&amp;quot;&lt;br /&gt;
A Continue/Cancel warning box is shown below.&lt;br /&gt;
Figure 9. --warningcontinuecancel warning screenshot&lt;br /&gt;
Another variation on the --yesno dialog type is to add a third option, as shown in the --yesnocancel dialog type.&lt;br /&gt;
Example 15. --yesnocancel message box&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel dialog&amp;quot; --yesnocancel &amp;quot;About to exit.\n \&lt;br /&gt;
Do you want to save the file first?&amp;quot;&lt;br /&gt;
A Yes/No/Cancel message box is shown below.&lt;br /&gt;
Figure 10. --yesnocancel message box screenshot&lt;br /&gt;
There is also a --warningyesnocancel variation, as shown below.&lt;br /&gt;
Example 16. --warningyesnocancel message box&lt;br /&gt;
kdialog --title &amp;quot;YesNoCancel warning dialog&amp;quot; --warningyesnocancel \&lt;br /&gt;
&amp;quot;About to exit.\n Do you want to save the file first?&amp;quot;&lt;br /&gt;
A Yes/No/Cancel warning message box is shown below.&lt;br /&gt;
Figure 11. --warningyesnocancel message box screenshot&lt;br /&gt;
The return value ($?) from all these dialog boxes follows a common pattern. A Yes, OK or Continue returns zero. A No returns one. A Cancel returns two.&lt;br /&gt;
=== Suppressing the display of a dialog ===&lt;br /&gt;
Sometimes you will be using kdialog in a loop, or other situation where a message may be repeated. For example, you might be iterating through a list of files, and you raise an error for each file you cannot open because of permission problems. This can produce a really bad user experience because the error is repeated over and over.&lt;br /&gt;
The normal KDE way to deal with this is to allow the user to suppress the display of a message in the future by selecting a checkbox, and kdialog allows you to do this with the --dontagain option. This option takes a file name and an entry name, and if the user selects the checkbox, then an entry is written to the specified file, with the specified entry name.&lt;br /&gt;
As an example, consider an information level message box for display of a file missing message.&lt;br /&gt;
Example 17. Information level message box, with --dontagain&lt;br /&gt;
kdialog --dontagain myscript:nofilemsg --msgbox &amp;quot;File not found.&amp;quot;&lt;br /&gt;
A typical information level message box, with --dontagain is shown below.&lt;br /&gt;
Figure 12. Information level message box, with --dontagain, screenshot&lt;br /&gt;
As noted above, an entry is written to a file when the user selects the checkbox.&lt;br /&gt;
Example 18. --dontagain file listing&lt;br /&gt;
$ cat ~/.kde/share/config/myscript&lt;br /&gt;
[Notification Messages]&lt;br /&gt;
nofilemsg=false&lt;br /&gt;
The effect of this entry is to suppress future display of dialogs using that filename, entry tuple (in the example above, this means myscript:nofilemsg. This will take effect across all KDE applications, so be careful of the filename you use.&lt;br /&gt;
=== User Input dialogs ===&lt;br /&gt;
There are two basic free-form user input dialog types - the --inputbox type and the --password type. The password dialog was covered in depth in a previous section - see the Section called kdialog Usage.&lt;br /&gt;
The --inputbox dialog type requires at least one parameter, which is used as the text in the dialog box.&lt;br /&gt;
Example 19. --inputbox dialog box&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot;&lt;br /&gt;
An input dialog box is shown below.&lt;br /&gt;
Figure 13. --inputbox dialog box screenshot&lt;br /&gt;
Sometimes you want to provide a default text string in the input dialog. You can do this by providing that string as the optional second parameter, as shown below:&lt;br /&gt;
Example 20. --inputbox dialog box with default parameter&lt;br /&gt;
kdialog --title &amp;quot;Input dialog&amp;quot; --inputbox &amp;quot;What name would you like to&lt;br /&gt;
use&amp;quot; &amp;quot;default Name&amp;quot;&lt;br /&gt;
An input dialog box with initial default text is shown below.&lt;br /&gt;
Figure 14. --inputbox dialog box screenshot showing default text&lt;br /&gt;
The return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The string that is entered (or modified / accepted if default text is used) is returned on standard output. If the user chooses Cancel, no output is sent.&lt;br /&gt;
=== Displaying files ===&lt;br /&gt;
A common requirement for shell scripts is the ability to display a file. kdialog supports this with the --textbox dialog type. This dialog type has one mandatory parameter, which is the name of the file to be displayed. There are also two optional parameters which specify the width and height of the dialog box in pixels. If these are not specified, 100 pixels by 100 pixels is used.&lt;br /&gt;
Example 21. --textbox dialog box&lt;br /&gt;
kdialog --textbox Makefile&lt;br /&gt;
Figure 15. --textbox dialog box&lt;br /&gt;
Example 22. --textbox dialog box with dimensions&lt;br /&gt;
kdialog --textbox Makefile 440 200&lt;br /&gt;
Figure 16. --textbox dialog box with dimensions&lt;br /&gt;
=== Menu and Selection Dialogs ===&lt;br /&gt;
This section covers simple menus, checklists, radio buttons and combo-boxes. These are typically used for providing a choice of options.&lt;br /&gt;
The menu is used to select one of a range of options. Each option is defined using two arguments, which you might like to think of as a key and a label. An example of the usage is shown below.&lt;br /&gt;
Example 23. --menu dialog box&lt;br /&gt;
kdialog --menu &amp;quot;Select a language:&amp;quot; a &amp;quot;American English&amp;quot; b French d &amp;quot;Oz' English&amp;quot;&lt;br /&gt;
Figure 17. --menu dialog box&lt;br /&gt;
If you select the first option (in this case American English and press OK, then kdialog will send the associated key (in this case the letter a) to standard output. Note that the keys do not need to be lower case letters - you can equally use numbers, upper case letters, strings or the contents of shell variables.&lt;br /&gt;
As with the other examples we've seen, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
A checklist is similar to a menu, except that the user can select more than one option. In addition, a reasonable set of default selections can be provided. To do this, each option is defined using three arguments, which you might like to think of as a key, a label and a default state. An example of the usage is shown below.&lt;br /&gt;
Example 24. --checklist dialog box&lt;br /&gt;
kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2 French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 18. --checklist dialog box&lt;br /&gt;
Clearly the result can contain more than one string, since the user can select more than one label. By default, the results are returned on a single line, however you can use the --separate-output to get a carriage return between each result. These two cases are shown in the example below, where all of the options were selected in each case.&lt;br /&gt;
Example 25. --checklist dialog box&lt;br /&gt;
$ kdialog --checklist &amp;quot;Select languages:&amp;quot; 1 &amp;quot;American English&amp;quot; off \&lt;br /&gt;
2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
&amp;quot;1&amp;quot; &amp;quot;2&amp;quot; &amp;quot;3&amp;quot;&lt;br /&gt;
$ kdialog --separate-output --checklist &amp;quot;Select languages:&amp;quot; \&lt;br /&gt;
1 &amp;quot;American English&amp;quot; off 2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
1&lt;br /&gt;
2&lt;br /&gt;
3&lt;br /&gt;
As for the menu example, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
The radiolist is very similar to the checklist, except that the user can only select one of the options. An example is shown below:&lt;br /&gt;
Example 26. --checklist dialog box&lt;br /&gt;
$ kdialog --radiolist &amp;quot;Select a default language:&amp;quot; 1 &amp;quot;American \&lt;br /&gt;
English&amp;quot; off  2  French on 3 &amp;quot;Oz' English&amp;quot; off&lt;br /&gt;
Figure 19. --checklist dialog box&lt;br /&gt;
Note that if you try to turn on more than one option by default, only the last option turned on will be selected. If you don't turn on any of the options, and the user doesn't select any, kdialog will raise an assertion, so don't do this.&lt;br /&gt;
A combo-box is slightly different to the previous menu options, in that it doesn't use keys, but instead just returns the selected text. An example is shown below:&lt;br /&gt;
Example 27. --combobox dialog box&lt;br /&gt;
$ kdialog --combobox &amp;quot;Select a flavour:&amp;quot; &amp;quot;Vanilla&amp;quot; &amp;quot;Chocolate&amp;quot; &amp;quot;Strawberry&amp;quot; &amp;quot;Fudge&amp;quot;&lt;br /&gt;
Chocolate&lt;br /&gt;
Figure 20. --combobox dialog box&lt;br /&gt;
=== File Selection Dialogs ===&lt;br /&gt;
This section covers dialogs to select files to open and save. These dialogs access the power of the underlying KDE dialogs, including advanced filtering techniques and can provide either paths or URLs.&lt;br /&gt;
The dialog to select a file to open is invoked with --getopenfilename or --getopenurl. These two commands are used in the same way - only the format of the result changes, so every example shown here can be applied for either format. You have to specify a starting directory, and can optionally provide a filter. Here is a simple example that doesn't provide any filtering, and accesses the current directory:&lt;br /&gt;
Example 28. --getopenfilename dialog box&lt;br /&gt;
kdialog --getopenfilename .&lt;br /&gt;
Figure 21. --getopenfilename dialog box&lt;br /&gt;
As for previous examples, the return value depends on the button used. OK returns zero. Cancel returns one.&lt;br /&gt;
As mentioned previously, the result format varies between the two variations. This is shown below, in each case selecting the same file:&lt;br /&gt;
Example 29. --getopenfilename dialog box&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenfilename .&lt;br /&gt;
/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
[bradh@rachel kdialog]$ kdialog --getopenurl .&lt;br /&gt;
file:/home/bradh/coding/cvs-vers/kde-head/kdebase/kdialog/Makefile.am&lt;br /&gt;
Note that the user can only select an existing file with these options.&lt;br /&gt;
When you doing a lot of opening of files, it can be useful to open the dialog in the directory that was navigated to last time. While you can potentially do this by extracting the directory from the filename, you can use a special KDE feature based on labels, as shown below:&lt;br /&gt;
Example 30. --getopenfilename dialog box with directory support&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
kdialog --getopenfilename :label1&lt;br /&gt;
Each time you use the same label (with the colon notation), the last used directory will be used as the starting directory. This will normally improve the user experience. If that label hasn't been used before, the user's home directory will be used.&lt;br /&gt;
Note that the colon notation selects the last used directory for that label for the kdialog application. If you use two colons instead of one, the labelling scope becomes global and applies to all applications. This global scope is rarely what you want, and is mentioned only for completeness.&lt;br /&gt;
Since not all files are applicable, it can be useful to restrict the files displayed. This is done using the optional filter argument. The best way to do this is with MIME types, as shown below:&lt;br /&gt;
Example 31. --getopenfilename dialog box with MIME filter&lt;br /&gt;
kdialog --getopenfilename ~/doco/ethereal-userguide &amp;quot;image/png text/html text/plain&amp;quot;&lt;br /&gt;
Figure 22. --getopenfilename dialog box with MIME filter&lt;br /&gt;
If it isn't possible to use MIME types, you can specify a range of wildcards and an optional label, as shown below:&lt;br /&gt;
Example 32. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
kdialog --getopenfilename . &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Figure 23. --getopenfilename dialog box with wildcard filter&lt;br /&gt;
The --getsavefilename and --getsaveurl commands are directly analogous to the file opening dialogs. A simple example is shown below:&lt;br /&gt;
Example 33. --getsavefilename dialog box&lt;br /&gt;
kdialog --getsavefilename .&lt;br /&gt;
Figure 24. --getsavefilename dialog box&lt;br /&gt;
Unlike the file opening dialogs, the file saving dialogs allow to user to specify a filename that doesn't yet exist.&lt;br /&gt;
As for the file opening dialogs, the file saving dialogs allow use of the colon notation, and also allow filtering using MIME types and wildcards, as shown below:&lt;br /&gt;
Example 34. --getsavefilename dialog box with filter&lt;br /&gt;
kdialog --getsavefilename :label1 &amp;quot;*.cpp *.cc *.c |C and C++ Source Files&amp;quot;&lt;br /&gt;
Sometimes you don't want to specify a filename, but instead need a directory. While you can specify a &amp;quot;inode/directory&amp;quot; filter to a file open dialog, it is sometimes better to use the --getexistingdirectory type, as shown below:&lt;br /&gt;
Example 35. --getexistingdirectory dialog box&lt;br /&gt;
kdialog --getexistingdirectory .&lt;br /&gt;
Figure 25. --getexistingdirectory dialog box&lt;br /&gt;
--getexistingdirectory does not provide any filtering, but it does provide the same starting directory options, including the colon notation.&lt;br /&gt;
=== Progress Dialogs ===&lt;br /&gt;
A progress bar dialog is a useful GUI element when you have a process that will take a long time, and you want to reassure the user that things are happening correctly, rather than having the user believe that the machine may have locked up. If you ever find yourself thinking about writing an information dialog that says something like &amp;quot;..., this may take a while&amp;quot;, it may be appropriate to use a progress bar dialog.&lt;br /&gt;
Because you need to make the progress bar change, you can't use kdialog in the normal way. Instead, you set up the dialog, and use the dcop to make the required changes.&lt;br /&gt;
A simple use of the --progressbar command is shown below. Because it is fairly long, I've numbered the lines. The numbers aren't part of the script you would type in - they are purely for reference in the explanation.&lt;br /&gt;
Example 36. --progressbar dialog box example&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Initialising&amp;quot; 4`&lt;br /&gt;
     2  dcop $dcopRef setProgress 1&lt;br /&gt;
     3  dcop $dcopRef setLabel &amp;quot;Thinking really hard&amp;quot;&lt;br /&gt;
     4  sleep 2&lt;br /&gt;
     5  dcop $dcopRef setProgress 2&lt;br /&gt;
     6  sleep 2&lt;br /&gt;
     7  dcop $dcopRef setLabel &amp;quot;Thinking some more&amp;quot;&lt;br /&gt;
     8  dcop $dcopRef setProgress 3&lt;br /&gt;
     9  sleep 2&lt;br /&gt;
    10  dcop $dcopRef setProgress 4&lt;br /&gt;
    11  sleep 2&lt;br /&gt;
    12  dcop $dcopRef close&lt;br /&gt;
I'll work through each line in turn. Line 1 runs kdialog, with an initial label of Initialising, and a progress bar with four elements. We capture the return value in a variable (which can be named just about anything - I chose dcopRef) for later use with the dcop command. Line 2 sets the bar to one stage along, and line 3 changes the label to Thinking really hard. Line 4 is just a delay (which would be when your script would perform the first part of the lengthy task in a real application). Line 5 then increases the progress bar, followed by another delay (representing more processing) in line 6. Line 7 changes the label, while lines 8 through 11 further increase the progress bar over a few seconds. Line 12 closes the progress bar dialog - without this, it will remain displayed. If you'd prefer that the progress bar dialog closed as soon as the bar gets to 100%, you can use the setAutoClose true argument to dcop.&lt;br /&gt;
If a task is taking a very long time, the user may decide that it is better cancelled. kdialog can assist with this too, as shown in the example below.&lt;br /&gt;
Example 37. --progressbar dialog box example, with Cancel&lt;br /&gt;
     1  dcopRef=`kdialog --progressbar &amp;quot;Press Cancel at Any time&amp;quot; 10`&lt;br /&gt;
     2  dcop $dcopRef showCancelButton true&lt;br /&gt;
&lt;br /&gt;
     3  until test &amp;quot;true&amp;quot; == `dcop $dcopRef wasCancelled`; do&lt;br /&gt;
     4    sleep 1&lt;br /&gt;
     5    inc=$((`dcop $dcopRef progress` + 1))&lt;br /&gt;
     6    dcop $dcopRef setProgress $inc;&lt;br /&gt;
     7  done&lt;br /&gt;
&lt;br /&gt;
     8  dcop $dcopRef close&lt;br /&gt;
As in the previous example, the first line executes kdialog with some initial text, this time with 10 segments; and again we capture the return value in a variable for later use with dcop. Line 2 turns on the display of the Cancel button, which is off by default.&lt;br /&gt;
Lines 3 through 7 are a loop. Line three runs dcop to check if the Cancel button has been pressed, and if it hasn't been pressed yet, runs line 4 through 6. Line 4 is again a delay, representing processing in a real application. Line 5 runs dcop to get the current progress bar setting, and adds one to the count (I could have just kept a counter variable, but this approach shows another dcop usage). Line 6 then sets the progress bar to the incremented value. Line 8 closes the progress bar dialog if the Cancel button has been pressed.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:17:19Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Example 5: Password Dialog Showing Redirection */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button. The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result? For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable ===&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs</id>
		<title>Development/Tutorials/Shell Scripting with KDE Dialogs</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Shell_Scripting_with_KDE_Dialogs"/>
				<updated>2007-01-12T02:08:57Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Created Page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Improve}}&lt;br /&gt;
&lt;br /&gt;
== Introduction and Scope ==&lt;br /&gt;
There are some misconceptions that KDE is only a graphical environment. While it is true that KDE is an outstanding desktop environment, the Unix heritage of command line and scripting is also well supported by KDE. In particular, KDE applications can be controlled from the command line, and shell scripts can make use of some of the KDE widget set.&lt;br /&gt;
&lt;br /&gt;
To use this tutorial, you'll need to have some basic familiarity with command line fundamentals, and be at least aware of shell scripting. Like any other programming environment, effective shell scripting requires solid knowledge of the environment. However, you should be able to make sense of the examples with only basic understanding. The downside to this is that if you are very familiar with shell scripting, some of the explanation is likely to be redundant.&lt;br /&gt;
&lt;br /&gt;
This tutorial assumes that you are using the GNU bash shell, or something directly compatible. Users of other shells (especially csh and variants) may need to modify the examples.&lt;br /&gt;
&lt;br /&gt;
Shell scripting techniques and usage varies a lot. Sometimes a script is only meant to be run by the system (e.g. as cron job), and other times scripts are really applications intended to be run by users. KDE includes features that allow you to use some KDE functionality from a shell script, which can save work, and can also make your script feel like it is part of a nicely integrated application set.&lt;br /&gt;
&lt;br /&gt;
As an example, consider something like a password dialog. If you need a user to enter a password, you can easily generate a dialog from your script that looks like the following:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png]]&lt;br /&gt;
&lt;br /&gt;
== kdialog Usage ==&lt;br /&gt;
The key to using KDE dialogs in shell scripts is an application named ''kdialog''. To generate a password dialog as shown in above, you could use the following command line.&lt;br /&gt;
&lt;br /&gt;
=== Example 1: Password Dialog ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Let's look at the code in a bit more detail. The arguments to kdialog are used to control the type of dialog that is produced and the parameter or parameters of that dialog box. In the case of the password dialog, you use --password to specify the dialog type, and then follow that with the parameter, which is the text that appears in the dialog box.&lt;br /&gt;
&lt;br /&gt;
Each time you run kdialog (or any other application), there is a return value that indicates whether the application ran as expected, or failed in some way. You can access this return value as $?, as shown in the following example.&lt;br /&gt;
&lt;br /&gt;
=== Example 2: Shell Script Return Values ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Some Text&amp;quot;&lt;br /&gt;
hello&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
0&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* Note - The $? variable is updated when each foreground process exits. If you need to use that variable later, you need to save it away.&lt;br /&gt;
&lt;br /&gt;
In this example, the return value is zero. It would be one if the ''Cancel'' button had been selected instead of the ''OK'' button. The convention is that negative numbers indicate failure, however the shell normally subtracts them from 256. This means that if you fail to specify a required argument, the system returns -2, and $? returns 254.&lt;br /&gt;
&lt;br /&gt;
* Note - This is different to the convention used by the underlying widgets. If you are familiar with the underlying Qt widgets, this might be a bit confusing, however it is important to conform to the standard approach to shell scripting.&lt;br /&gt;
&lt;br /&gt;
=== Example 3:  Shell Script Return Value with Error ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password&lt;br /&gt;
kdialog: '&amp;lt;text&amp;gt;' missing.&lt;br /&gt;
kdialog: Use --help to get a list of available command line options.&lt;br /&gt;
[watson@bakerst]$ echo $?&lt;br /&gt;
254&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In a shell script, you might choose to test the return value after each invocation.&lt;br /&gt;
&lt;br /&gt;
=== Example 4: Password Dialog, with Return Value Check ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    kdialog --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
    if [ $? = 0 ]; then&lt;br /&gt;
            echo &amp;quot; you selected: OK&amp;quot;&lt;br /&gt;
    else&lt;br /&gt;
            echo &amp;quot; you selected: Cancel&amp;quot;&lt;br /&gt;
    fi&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In addition to the return value, you also get the password itself (assuming that you selected OK). After all, what is the point of a password dialog unless you can use the result? For the password dialog, and other kdialog dialogs that provide input capabilities, the output is sent to standard output. This allows you to redirect the input to a file, or pipe it to another program. In the case of the password dialog, the text that is entered will be echoed as shown in [[#Example 2|Example 2]], unless you redirect it.&lt;br /&gt;
&lt;br /&gt;
=== Example 5: Password Dialog Showing Redirection ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ kdialog --password &amp;quot;Enter the password&amp;quot; &amp;gt; password.file&lt;br /&gt;
[watson@bakerst]$ cat password.file&lt;br /&gt;
Secrter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Instead of saving the result in a file, you can also use a shell variable. Note that you need to use the &amp;quot;backtick&amp;quot; notation - this key is normally found on the top left of English (British or American) layout keyboards, above the &amp;quot;7&amp;quot; key on French layout keyboards, and on the top right of German layout keyboards.&lt;br /&gt;
&lt;br /&gt;
=== Example 6: Password Dialog Using a Shell Variable&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
[watson@bakerst]$ password=`kdialog --password &amp;quot;Enter the password&amp;quot;`&lt;br /&gt;
[watson@bakerst]$ echo $password&lt;br /&gt;
Secreter&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Example 7: Password Dialog with Title ===&lt;br /&gt;
While not shown in the previous examples, you can also use the --title option to specify the title of the dialog box, as shown in the following example.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
kdialog --title &amp;quot;ACAP entry&amp;quot; --password &amp;quot;Please enter the server access code:&amp;quot;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Which results in:&lt;br /&gt;
&lt;br /&gt;
[[Image:Shell Scripting with KDE Dialogs-Password Dialog with Title.png]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/File:Shell_Scripting_with_KDE_Dialogs-Password_Dialog_with_Title.png</id>
		<title>File:Shell Scripting with KDE Dialogs-Password Dialog with Title.png</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/File:Shell_Scripting_with_KDE_Dialogs-Password_Dialog_with_Title.png"/>
				<updated>2007-01-12T02:06:22Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Shell Scripting with KDE Dialogs-Password Dialog with Title

Should be updated to show new look&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Shell Scripting with KDE Dialogs-Password Dialog with Title&lt;br /&gt;
&lt;br /&gt;
Should be updated to show new look&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/File:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png</id>
		<title>File:Shell Scripting with KDE Dialogs-Password Dialog.png</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/File:Shell_Scripting_with_KDE_Dialogs-Password_Dialog.png"/>
				<updated>2007-01-12T01:48:55Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Shell Scripting with KDE Dialogs - Example Password Dialog.

Should be updated to show a newer look.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Shell Scripting with KDE Dialogs - Example Password Dialog.&lt;br /&gt;
&lt;br /&gt;
Should be updated to show a newer look.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:Jstaniek</id>
		<title>User talk:Jstaniek</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:Jstaniek"/>
				<updated>2007-01-11T20:36:57Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* KDElibs.com and developernew.kde.org coexistence */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__TOC__&lt;br /&gt;
&lt;br /&gt;
== TODOs ==&lt;br /&gt;
*Check [[Development/Tutorials/Localization/Unicode]] content against the Qt4 API, check the theory against Wikipedia's Unicode page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== KDElibs.com and developernew.kde.org coexistence ==&lt;br /&gt;
* Mind if I copy the build info over from kdelibs.com to here under Getting_Started/Build/Unstable_Version-Windows, and then could you review it for current correctness? Thanks --[[User:CuCullin|CuCullin]] 16:13, 11 January 2007 (CET)&lt;br /&gt;
**I do not recommend making redundant copies of http://www.kdelibs.com. The content there is under heavy development now. I won't be able to maintain another wiki (I already have FOUR :) ). '''We can make a move (not a copy) to kdelibs once KDE4 buildsystem is stable.''' Why? Because many steps are common and we want to share them between targets. For now the instructions are even splitted between msvc and mingw compilers, what's not optimal for maintenance. &amp;lt;br&amp;gt;'''According to my vision: eventually, kdelibs.com will be more ISVs-oriented while *.kde.org stays oriented at the community in general.''' -- [[User:Jstaniek|jstaniek]] 17:27, 11 January 2007 (CET)&lt;br /&gt;
*** Moving once its settled in sounds good. As long as at some point we have all our information in one place we should be good. The issue of kdelibs.com becoming an ISV portal raises a question with regards to the ISV section on this website. We don't need two of them IMHO, it'll only split resources and give opportunity for confusion to those looking for ISV info. Jaroslaw: i'll see if i can find you on irc to discuss kdelibs.com a bit since that's a bit off-topic here. =) --[[User:Aseigo|Aseigo]] 20:43, 11 January 2007 (CET)&lt;br /&gt;
****In fact, kdelibs.com is planned as a web site about kdelibs technology only (or mostly), as it sounds, and how to use it for developemnt and deployment. Among other plans I think the web site will have a variation of kde.org's look&amp;amp;feel, with some &amp;quot;commercial&amp;quot; touch. Something like trolltech.com is for Qt while there exist various forums devoted Qt, I'd risk such comparison. Companies/organizations having multiple web sites, one per orthogonal topic, are not unusual these days... These are random thoughts for now. ---[[User:Jstaniek|jstaniek]] 21:08, 11 January 2007 (CET)&lt;br /&gt;
*** I'm not wanting to move all of it - specifically, what I'd like to do is just get basic build information onto this wiki and also a working windows version of the &amp;quot;hello world&amp;quot; for KDE 4 tutorial posted.  This is partially to coordinate with something upcoming.... if you're available, I'm on freenode to chat about it further. --[[User:CuCullin|CuCullin]] 21:36, 11 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User_talk:Jstaniek</id>
		<title>User talk:Jstaniek</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User_talk:Jstaniek"/>
				<updated>2007-01-11T15:13:39Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* TODOs */  Getting_Started/Build/Unstable_Version-Windows Question...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== TODOs ==&lt;br /&gt;
*Check [[Development/Tutorials/Localization/Unicode]] content against the Qt4 API, check the theory against Wikipedia's Unicode page.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
* Mind if I copy the build info over from kdelibs.com to here under Getting_Started/Build/Unstable_Version-Windows, and then could you review it for current correctness? Thanks --[[User:CuCullin|CuCullin]] 16:13, 11 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Installing_third_party_softwares_in_terminal/Build/KDE4/Mac_OS_X</id>
		<title>Talk:Installing third party softwares in terminal/Build/KDE4/Mac OS X</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Installing_third_party_softwares_in_terminal/Build/KDE4/Mac_OS_X"/>
				<updated>2007-01-10T19:51:10Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Once a KDE-Darwin person has reviewed this for accuracy, I'd like to post a link under Getting Started/Build, at &amp;quot;KDE 4 (Unstable version, trunk), For OSX, For Windows&amp;quot; or some such.  However, I don't even have a mac to try this on, so if someone could that would be great :) --[[User:CuCullin|CuCullin]] 16:49, 10 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
:I'm all for it. We also need to propagate [http://www.kdelibs.com the windows] build (and maybe also [http://solaris.kde.org/ solaris]. --[[User:Dhaumann|Dhaumann]] 18:41, 10 January 2007 (CET)&lt;br /&gt;
&lt;br /&gt;
::I'm right now waiting for explicit permission to copy the existing tutorial on kdelibs.com over here.  I doubt it will be an issue, but I always ask on any non kde.org site :) --[[User:CuCullin|CuCullin]] 20:51, 10 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Talk:Installing_third_party_softwares_in_terminal/Build/KDE4/Mac_OS_X</id>
		<title>Talk:Installing third party softwares in terminal/Build/KDE4/Mac OS X</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Talk:Installing_third_party_softwares_in_terminal/Build/KDE4/Mac_OS_X"/>
				<updated>2007-01-10T15:49:56Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: For review &amp;amp; Getting Started/Build link&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Once a KDE-Darwin person has reviewed this for accuracy, I'd like to post a link under Getting Started/Build, at &amp;quot;KDE 4 (Unstable version, trunk), For OSX, For Windows&amp;quot; or some such.  However, I don't even have a mac to try this on, so if someone could that would be great :) --[[User:CuCullin|CuCullin]] 16:49, 10 January 2007 (CET)&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/KDE3/Qt_Designer_and_KDevelop_3.0_for_Beginners</id>
		<title>Development/Tutorials/KDE3/Qt Designer and KDevelop 3.0 for Beginners</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/KDE3/Qt_Designer_and_KDevelop_3.0_for_Beginners"/>
				<updated>2007-01-10T03:11:44Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Having an issue uploading images - if someone could do that it would be great!&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
{{KDE3}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
To get us started doing something useful with [http://www.trolltech.com/products/qt/features/designer Qt Designer], we are going to build a simple program that will show you the power of Qt Designer and [http://www.kdevelop.org/ KDevelop]. I hope that this will help you to create your first &amp;quot;real&amp;quot; KDE application.&lt;br /&gt;
&lt;br /&gt;
[http://www.trolltech.com/products/qt/features/designer KDevelop] will help you to build a complete KDE application. The KDE project uses the autoconf and automake tools for KDE 3.x, and [http://www.kdevelop.org/ KDevelop] will provide you with all the necessary files (admin directory, Makefile.cvs, Makefile.am,...).&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
===How to Get Qt Designer===&lt;br /&gt;
====From your Distribution====&lt;br /&gt;
Qt Designer is part of the qt-3.2.x package and above. If you have an older Qt on your system, you should get at least this version. At the time of writing, Qt latest version is 3.3.2.&lt;br /&gt;
&lt;br /&gt;
Please remember to check if you have all the qt-related packages installed. You need the qt headers in order to compile this tutorial application. These headers usually come in the ''devel'' package. You also need to be sure you have designer. In some distributions, it comes in a separate package.&lt;br /&gt;
&lt;br /&gt;
To check if you have everything, do a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;locate qstring.h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you get something like ''/usr/lib/qt3/include/qstring.h'' then you can set your ''QTDIR'' variable to ''/usr/lib/qt3/''. In bash environment, this is done by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export QTDIR= /usr/lib/qt3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Tarball or Anonymous Subversion====&lt;br /&gt;
You can download the tarball from the [http://www.trolltech.com/download/qt/x11.html Trolltech website], or get the ''qt-copy'' module from SVN. Please note that Qt for [http://www.kernel.org/ Linux] is [http://www.gnu.org/copyleft/gpl.html GPL].&lt;br /&gt;
&lt;br /&gt;
For an explanation for how to use anonymous SVN, get the ''qt-copy'' and ''kde'' modules and compile them, please see a great documentation at [[Getting_Started/Sources/Using Subversion with KDE|Using Subversion with KDE]].&lt;br /&gt;
&lt;br /&gt;
You must then set the ''QTDIR'' environment variable. This should point to the directory into which you installed Qt. In bash, for example, you would type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export QTDIR= /usr/local/qt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
provided that ''/usr/local/qt'' is the directory into which you installed Qt. Please read the INSTALL file for more details.&lt;br /&gt;
&lt;br /&gt;
You then compile by issuing the following commands, here is the recommended compile line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure -system-zlib -qt-gif -system-libpng -system-libjpeg \&lt;br /&gt;
-plugin-imgfmt-mng -thread -no-exceptions -debug -fast&lt;br /&gt;
make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The command ''make install'' is not needed.&lt;br /&gt;
&lt;br /&gt;
Qt Designer is located in the ''bin'' directory of your Qt installation directory. You can run it by typing:&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/qt/bin/designer&amp;lt;/code&amp;gt;&lt;br /&gt;
in a console.&lt;br /&gt;
&lt;br /&gt;
To compile Qt from source, please see [http://www.trolltech.com/ Trolltech]'s [http://www.trolltech.com/developer/downloads/qt/x11 Qt/X11 Open Source Edition] page.&lt;br /&gt;
&lt;br /&gt;
===How to get KDevelop 3===&lt;br /&gt;
====From your Distribution====&lt;br /&gt;
KDevelop 3 should be part of your distribution. Pre 3 versions of KDevelop were nicknamed Gideon, but they are obsolete now.&lt;br /&gt;
&lt;br /&gt;
====From Tarball====&lt;br /&gt;
KDevelop can be downloaded from the [http://www.kdevelop.org KDevelop website], under the '''Quick download''' heading.&lt;br /&gt;
&lt;br /&gt;
To compile KDevelop 3, you need qt-3.1.0 or higher and kdelibs-3.1.0 or higher. The environment variables ''QTDIR'' and ''KDEDIR'' should point to those directories.&lt;br /&gt;
&lt;br /&gt;
Don't forget to set up the KDE and Qt paths. The most common errors while using KDevelop come from the environment variables not set up properly. Check in a console by issuing the command '''set''' to see all your environment variables. You should set your ''PATH'' variable as follow as well as your ''LD_LIBRARY_PATH'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export PATH=$QTDIR/bin:$KDEDIR/bin:$PATH&lt;br /&gt;
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have any problem getting KDevelop running, please refer to the [http://www.kdevelop.org/phorum5/ KDevelop Forum] to find the answer to your problem.&lt;br /&gt;
&lt;br /&gt;
If you never used KDevelop before, try to create a new project and to compile it to get used to the interface and the icons. &lt;br /&gt;
&lt;br /&gt;
====KDevelop 3.4====&lt;br /&gt;
Please refer to [http://www.kdevelop.org/index.html?filename=3.4/download.html Downloading KDevelop 3.4] and [http://www.kdevelop.org/index.html?filename=3.4/branches_compiling.html Compiling KDevelop 3.4].&lt;br /&gt;
&lt;br /&gt;
===Lexicon===&lt;br /&gt;
* '''Widget''': a widget is an element of an graphical interface such as a container window, a button or a field for entering text.&lt;br /&gt;
* '''Layout management''': this term describes the way in which widgets are arranged in a window. In its simplest form, an element may be placed at a specific position and given a specific height and width. But when the user resizes the window, the widgets should stay in their position and change their size accordingly. Linux allows to do that by using layouts to place the widgets in.&lt;br /&gt;
* '''Signal and Slots''': Signals and slots are used for communication between objects. The signal/slot mechanism is a central feature of Qt. Signals are emitted by objects when they change their state in a way that may be interesting to the outside world. Slots can be used for receiving signals, but they are normal member functions. You can connect as many signals as you want to a single slot, and a signal can be connected to as many slots as you desire. Please see the [http://doc.trolltech.com/3.3/signalsandslots.html TrollTech documentation on signals and slots] for more details. In the excellent online documentation that comes with Qt, you'll find the signals and the public slots that go with each class. You can then implement your own slots. &lt;br /&gt;
&lt;br /&gt;
==Creating the Application==&lt;br /&gt;
===Starting the project===&lt;br /&gt;
====Creating the framework with KDevelop====&lt;br /&gt;
&lt;br /&gt;
The framework in which our program will sit in (i.e. the main window) can be done easily and quickly by using KDevelop. Start KDevelop and select ''New Project'' in the Project menu. The Application Wizard appears then. Choose a ''C++ -&amp;gt; KDE -&amp;gt; Simple KDE Application''. Fill in the blank lines with the project name '''SigCreate''', your name as author, and your email.  Refer to [[:Image:KDevelop3-CreateNewProject.png|this screen shot]] as a reference.&lt;br /&gt;
&lt;br /&gt;
Click on ''Next''. Have a look to the CVS option and the header templates. Then click on ''Finish'' on the last screen. KDevelop creates all the files that you need to compile your project. You can use the file selector to view the code of the 3 files which are main.cpp, sigcreate.cpp and sigcreate.h, as shown [[:Image:KDevelop3-FileSelector.png|here]].&lt;br /&gt;
&lt;br /&gt;
Once the ''Application Wizard'' has created your application, compile it to ensure that everything is fine. To do that, select '''Build -&amp;gt; Run automake &amp;amp; friends''' then '''Build -&amp;gt; Run configure'''. The ''Messages output window'' should say&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot; Good - your configure finished. Start make now&lt;br /&gt;
*&lt;br /&gt;
* *** Success ***&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
so you can run ''make'' with '''Build -&amp;gt; Build Project''' (or using the F8 shortcut). Then '''Build -&amp;gt; Install'''. Then '''Build -&amp;gt; Execute program''' (or F9). The result is shown [[:Image:KDevelop-SigCreate.png|here]].&lt;br /&gt;
&lt;br /&gt;
*'''NOTE''' - If KDevelop does not recognize your ''QTDIR'' and ''KDEDIR'' variables, you can set them in '''Project -&amp;gt; Project Options...''' in ''Configure Options'', as [[:Image:KDevelop3-ConfigureOptions.png|shown]].&lt;br /&gt;
&lt;br /&gt;
====Using Qt Designer====&lt;br /&gt;
Qt Designer is a tool for designing and implementing user interfaces. It helps you arranging your widgets on a form and adding a proper layout so your interface can be resized properly. I recommend that you read the [http://doc.trolltech.com/3.3/designer-manual.html Qt Designer manual] to know everything about Qt Designer. Qt Designer includes a code editor but we'll use KDevelop to edit and modify all code.&lt;br /&gt;
&lt;br /&gt;
We will now create the interface of our application using Qt Designer. A form from Qt Designer is saved with a .ui extension because it is then processed by the uic program to generate a .h and .cpp files. KDevelop takes care of that, the only thing we need to do is to create the form.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - Each time you add or remove a file (now we will add a .ui file) in your KDevelop project, the Makefile.am will be changed. KDevelop does that itself but you will need to ''Run automake &amp;amp; friends'' after such changes.&lt;br /&gt;
&lt;br /&gt;
In KDevelop, click on '''File -&amp;gt; New''' and fill the dialog window that appears. First write the file name: ''sigcreatedlg'' and select what new file you want in the combobox: here we want a ''Widget (.ui)''. Please be sure that '''Add to project''' is checked, this ensures that the Makefile.am is updated. Refer to [[:Image:KDevelop3-NewFile-Widget.png|this screen shot]].&lt;br /&gt;
&lt;br /&gt;
Click the ''OK'' button. The [[:Image:KDevelop3-AutomakeManagerDialog.png|Automake manager dialog]] then pops up.  Click the ''OK'' button for this dialog as well.&lt;br /&gt;
&lt;br /&gt;
If the new file ''sigcreatedlg.ui'' is not open in Qt Designer, open the ''Automake Manager'', right-click on the file and select ''Open With'', then ''Qt Designer''. Qt Designer will open.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - About the names: it is a good idea to finish a dialog name or a form name by ''dlg'' to ensure a nice visibility for people who want to have a look at the code. ''sigcreatedlg'' says that it is a dialog, i.e an interface class, only.&lt;br /&gt;
&lt;br /&gt;
The [[:Image:QtDesigner3-Interface.png|Qt Designer interface]] is essentially split into three areas. On the left is the '''toolbox''', where you can select your widgets. On the right, several dialogs can be selected. I'll keep only the '''Property Editor''' dialog (I close the 2 others). Your widgets can be fine tuned to behave how you want them to. You can choose the size of the widget, its background color (palette), and so on. Between those 2 windows is the '''Form''', your program window, within which you will design your user interface.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - After adding the ''sigcreatedlg.ui'' file, you will have to run ''Automake &amp;amp; friends'' and ''Run configure'' before building the program. This ensures that the updated ''Makefile.am'' is now read. &lt;br /&gt;
&lt;br /&gt;
===Designing the Program===&lt;br /&gt;
&lt;br /&gt;
Each time you want to use Qt Designer, you should have a precise visual idea of the design of your interface. You can see in [[:Image:KDevelop3-SigCreateDialog.png|this picture]] what the program will be like. It is a window with a number of different items (or widgets) on it, designed so that the user puts the right information in the right boxes. You should always design your program from the user's point of view, as it must be easy to use.&lt;br /&gt;
&lt;br /&gt;
This application creates an email signature, which is then displayed on the screen. The user should enter her/his name, email address, and then select one of three comments. When you click the '''Create!''' button, the generated signature is shown in a ''MultiLineEdit''. When you click '''Cancel''', the program quits.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - Note that this project is meant as a tutorial, so this is somewhat far away from practical use.&lt;br /&gt;
&lt;br /&gt;
Go back to the Qt Designer window with the new dialog open. You will see that the property editor has been filled with details about the form you have created. The first line in the '''Property Editor''' [[:Image:QtDesigner3-PropertyEditor.png|shows]] the name of the form which is Form1. Click on the field with this name to change it and type SigCreateDlg. This will form the class name of the dialog so you should name it something useful.&lt;br /&gt;
&lt;br /&gt;
To change properties, select the property you wish to change, then alter its setting on the right. Change the '''Caption''' property to &amp;quot;SigCreateDlg v.01&amp;quot;.   We will now begin to add widgets on our dialog.&lt;br /&gt;
&lt;br /&gt;
===Adding Widgets===&lt;br /&gt;
&lt;br /&gt;
To start, we will insert the text at the top of the program window, which can be seen [[:Image:KDevelop3-NewFile-Widget.png|here]]. This text tells the user how to operate the program. This type of widget is called a ''Label'' and you can put one on your program like this:&lt;br /&gt;
&lt;br /&gt;
# Select the dialog in ToolBox called '''Common Widgets-&amp;gt;TextLabel''', or from the menubar '''Tools-&amp;gt;Display-&amp;gt;TextLabel'''&lt;br /&gt;
# The cursor will become a crosshair over the form. Draw a box for the label, just as you would in a paint program, and you will see that the label is created with some dummy text in it.&lt;br /&gt;
# To change this text, double click on the label and type in the text, instead of ''TextLabel1''. The text you should type is ''This program will create an email signature for you. Just fill in the boxes and hit the Create! button.'' Select '''Align Center'' to have the text positioned nicely.  Refer to this [[:Image:QtDesigner3-TextEditDialog.png|screenshot]].&lt;br /&gt;
# Finally, resize the widget using the handles so it is the correct size and at the top of the box. Try to center the label by moving it with the mouse. This is just a temporary measure. Later on we will look at a more elegant layout management technique. You may refer to [[:Image:QtDesigner3-ResizingBox.png|this screenshot]].&lt;br /&gt;
&lt;br /&gt;
You follow pretty much the same procedure for embedding any type of widget that is supported by Qt Designer; select it, drag it, and finally, change its properties and size.&lt;br /&gt;
&lt;br /&gt;
An interesting concept in Qt Designer is that widgets can act as containers for other widgets. This will be demonstrated in our next task, which is to create the input fields inside the frame. You can see that in Picture 8 we have a bunch of labels and text boxes inside a frame. This frame is called a Group Box and acts as a container for the labels and text boxes inside it. Let's first create the frame by selecting the GroupBox in the '''Toolbox dialog-&amp;gt;Containers''' or '''Tools-&amp;gt;Containers-&amp;gt;GroupBox''' from the menubar. You can drag the mouse to create the box just below the Label you put before. In the ''Property Editor'' you can change the title property to alter the text in the frame. Put ''Details'' in the title text field. You may notice a + symbol in this entry in the ''Property Editor''. This indicates that the property has subproperties that can also be changed.&lt;br /&gt;
&lt;br /&gt;
Once you have created the frame (i.e the GroupBox), create three more labels as before but when you draw them, draw them inside the GroupBox frame. You can then see in the Object Explorer box ('''Windows menu -&amp;gt; Views -&amp;gt; Object Explorer''') to the right that the labels have become children of the GroupBox frame. See [[:Image:QtDesigner3-EditingTheDialog.png|this image]].&lt;br /&gt;
&lt;br /&gt;
Change the text of labels by double-clicking on it.&lt;br /&gt;
&lt;br /&gt;
Once you have done this you can then create the text boxes. They will allow the user to type in text like his(her) name and email address. We use the simplest type of text boxes: a widget called QLineEdit which allows the user to enter one line of text only. You have to create two QLineEdit widgets for the name and the email address. You choose the menu Tools then the entry Input then LineEdit and you draw it beside the 'Your Name' Label. Do the same below for the address.&lt;br /&gt;
&lt;br /&gt;
The witty comment will be selected by the user. We use a ComboBox which will present the user with three comments. Click on the ComboBox icon or select it via the Tools-&amp;gt; Input-&amp;gt; ComboBox menu. Draw it beside the Witty Comment label. Then double-click on it. You will be presented with a box into which you can add the contents of the combo box. Click on the 'New Item' button and type in your comment in the text box at the right. Then click again on 'New Item' for the second and third comments. Click on OK when you have finished.&lt;br /&gt;
&lt;br /&gt;
Adjust the size of the different widgets so they are nicely placed.&lt;br /&gt;
&lt;br /&gt;
Up to now, we have not named any of the widgets that are being placed in our program. It is useful to set an internal name for widgets so we can call them after in the program. Labels don't perform any action so they don't need to be named but other widgets do. It is the case now for our text boxes. We'll need to manipulate the data from the three input widgets (i.e. read the text) so we should give them a name. Names should be easily recognized later and they should make sense. The names are assigned via the name property on the top of the Property Editor. We name the top LineEdit nameBox and the second one mailBox. We name the ComboBox commBox. This will allow us to access the comments. So click on each LineEdit and then besides Name in the Property Editor write nameBox and mailBox. Then click on the ComboBox and name it commBox.&lt;br /&gt;
&lt;br /&gt;
We finish the graphical design by adding a label with 'Generated Signature' as text. Below it, we put a TextEdit ('''Tools-&amp;gt;Input-&amp;gt;TextEdit'''') where the generated signature will be displayed. We name it 'sigBox'. And then we add two PushButtons at the bottom ('Create!' and 'Cancel'). They don't need names but you can give them some if you want.&lt;br /&gt;
&lt;br /&gt;
Save your form. You can now have a quick preview by selecting the menu '''Preview-&amp;gt; Preview Form'''.  [[:Image:QtDesigner3-BeforeLayoutManagement.png|This]] is the form ''before'' layout management.&lt;br /&gt;
&lt;br /&gt;
===Getting Spaced Out===&lt;br /&gt;
This section describes the layout management. If you resize the preview window you will then notice that the widgets do not adjust appropriately. They are not resized. To improve things, we need to use a feature in Qt called spacers. Spacers are like virtual springs that push the widgets on each side apart.&lt;br /&gt;
* '''Note''' - Having a good layout is essential for your application, as when the strings are translated, they might be longer than the English ones and they need to fit on your widgets. The geometry of the widgets has to be nice if the user can resize your window application. Layouts are done by trial and error so use '''Preview-&amp;gt;Preview Form''' to see the result of your layout management and to achieve the best layout.&lt;br /&gt;
&lt;br /&gt;
The use of spacers and layout management is a skill that is developed through trial and error. The main thing to remember when dealing with spacers is that you work horizontally first and then vertically.&lt;br /&gt;
&lt;br /&gt;
We will first use spacers to center the text in the top box. Resize your label so that it only get the size of the text. Then we add two spacers, one at each side. Choose the 'spring' icon or menu '''Layout-&amp;gt; Add Spacer'''. You adjust each of the spacers horizontally. Click the space to the left of the text and the blue spacer will appear . Repeat the same procedure for the right. Then add a spacer on the right of the 'Generated Signature' label, and a last one on the left of the the 'Create!' pushbutton. Please use [[:Image:QtDesigner3-AddingTheSpacers.png|this image]] as a reference.&lt;br /&gt;
&lt;br /&gt;
Now that we have spacers to fill blank space, we need a proper layout management. This will allow the widgets to be nicely resized whenever the main window is resized. It is really compulsory to have good layout management. Again, try to resize several times to see if everything is in place. We can use Vertical or horizontal layout or grid management. The top row of widget is horizontal (spacer + label + spacer) so we need Horizontal management. We need to select the three widgets alltogether: click on the first spring, then click on the label while holding down ''Shift'', then on the second spring while holding down ''Shift''. Then click on the Horizontal Layout icon or menu '''Layout-&amp;gt; Lay Out Horizontally'''. You will then see a resizable red line around the three objects to indicate that their layout is being managed. Resize the red box if it needs to.&lt;br /&gt;
&lt;br /&gt;
We can now repeat this procedure for the three labels inside the GroupBox, this time using vertical layout management. The same vertical management for the two LineEdit and the ComboBox. It is better to use vertical management to keep the object aligned. If we use horizontal management for each label + text box then they will not stay aligned and equally sized. Horizontal management is needed for the label with the spacer and another one for the two pushbuttons and the spacer.&lt;br /&gt;
&lt;br /&gt;
To finish the layout, we need to let the form look after the laid-out boxes. We put everything in a grid. This is done by right clicking the form and selecting &amp;quot;Lay Out in a Grid&amp;quot; from the menu. The final design with layout lines should resemble something similar to [[:Image:QtDesigner3-CompleteLayoutManagement.png|this image]].&lt;br /&gt;
&lt;br /&gt;
===Signals and Slots===&lt;br /&gt;
&lt;br /&gt;
[http://doc.trolltech.com/3.0/signalsandslots.html Signals and Slots] are used for communication between Qt objects. The signal/slot mechanism is a central feature of Qt and probably the part that differs most from other toolkits which often use callbacks. In Qt, a signal is emitted by a widget when a particular event occurs, very often triggered by the user like for example pressing a button or writing something in a LineEdit. A slot is simply a function that is called in reponse to a particular signal.&lt;br /&gt;
&lt;br /&gt;
Now the widgets are implemented and the layout is arranged the final thing we need to do in the design stage of the form is to create the signal/slot connections. To do this manually requires a ''connect()'' function but Qt Designer provides a simple yet effective solution. To create the signal/slot connections we need to use the connecting tool. To do this either select the icon (it looks like a red arrow going into a green square) or select '''Tools-&amp;gt; Connect Signals/Slots''' from the menu (or use the F3 shortcut key). To create a connection, click on the form on the widget that is going to be dealing with the slot, drag the line off the form and release the mouse button.&lt;br /&gt;
&lt;br /&gt;
Let's deal first with the Create! button. Click first on the '''Connect Signal/Slot''' icon or select it from the Tools menu or use the F3 key. Then click on the Create! button with the crosshair and drag the line off the form completely. When you have released the mouse button you will see the connections tool shown [[:Image:QtDesigner3-CreateSlot.png|here]].&lt;br /&gt;
&lt;br /&gt;
What we want to do is to create a slot that will create our signature when the user clicks on the Create! button. The signal will be clicked() (you may choose among five signals for a QPushButton) and we need to create the slot then make the connection.&lt;br /&gt;
&lt;br /&gt;
To create the slot we need to click on the '''Edit Slots''' button. The slot creation box then appears. See [[:Image:QtDesigner3-CreateSlot.png|this example]]. Now click on the '''New Function''' button and a slot will appear in the box. Instead of ''new_slot()'' rename it to ''slotCreateSig()'' and leave the access specifier as public. When you click on ''OK'' you will be returned to the connections box and you will see your new slot in the Slots section of the box.&lt;br /&gt;
&lt;br /&gt;
To [[:Image:QtDesigner3-ViewandEditConnections.png|make a connection]] you simply select the appropriate signal (which is ''clicked()'' in our case) and then select the slot (which is our new slot ''slotCreateSig()''). When you have selected both signal and slot you will see the connection made at the bottom of the screen. After you are finished click OK.&lt;br /&gt;
&lt;br /&gt;
Repeat the procedure for the Cancel button by using the clicked() signal and the close() slot. You are now done with the signals and slots.&lt;br /&gt;
* '''Warning''' - Don't forget to save your form!&lt;br /&gt;
&lt;br /&gt;
===Generating the Source===&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we use KDevelop subclassing tool in Automake Manager. If you have KDevelop version which has not that capability, then please go to Chapter 7 where I explain this step without the subclass tool.&lt;br /&gt;
&lt;br /&gt;
Here we start with the KDE simple project named SigCreate and the sigcreatedlg.ui that we have added in our project. In the Automake Manager, in the section sigcreate (Program in bin) you must have three files: sigcreatedlg.ui, sigcreate.cpp and main.cpp. The project must compile and give the main window as in picture 3 (creating.html).&lt;br /&gt;
&lt;br /&gt;
As the sigcreate class is no use for us, we will remove it and use it for subclassing the sigcreatedlg.ui file. In the Automake Manager, right click on sigcreate.cpp and select Remove and a dialog pops up. Please check 'Also Remove it from disk'. Then do the same with sigcreate.h. This is the way to remove obsolete files from your project and the Makefile.am will be updated. Remember to run automake &amp;amp; friends and configure before compiling your project again. We will not do it right now because we will make other changes. We will now use the class name SigCreate for the subclass.&lt;br /&gt;
&lt;br /&gt;
In the Automake Manager, in sigcreate (program in bin), right click on sigcreatedlg.ui and choose Subclass Widget... from the context menu that appears. Then fill in the subclass name which is SigCreate. Check the box: Reformat source and click on OK. Say No then about adding these files in cvs as we did not enable this in our project.&lt;br /&gt;
Note&lt;br /&gt;
You can see that the slot we created in designer is listed here and checked, the method will be implemented in the generated files. If you uncheck it, the code will not be generated in your class.&lt;br /&gt;
&lt;br /&gt;
(The subclass dialog Image)&lt;br /&gt;
&lt;br /&gt;
We have to suppress some lines in main.cpp as the KDE simple project template refers to a KMainWindow which is usually the base class used. But here, SigCreate is based on QWidget. You have to remove all the lines between KApplication app; and return app.exec(); except the ones I keep here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SigCreate *mainWin = 0;&lt;br /&gt;
&lt;br /&gt;
mainWin = new SigCreate();&lt;br /&gt;
app.setMainWidget( mainWin );&lt;br /&gt;
mainWin-&amp;gt;show();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Implementing the Slot===&lt;br /&gt;
&lt;br /&gt;
Then you implement the slot by adding the following lines in the parenthesis of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void SigCreate::slotCreateSig()&lt;br /&gt;
{}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to implement the slot&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	sigBox-&amp;gt;append(&amp;quot;\n--&amp;quot;);&lt;br /&gt;
 	sigBox-&amp;gt;append(nameBox-&amp;gt;text());&lt;br /&gt;
 	sigBox-&amp;gt;append(mailBox-&amp;gt;text());&lt;br /&gt;
 	sigBox-&amp;gt;append(commBox-&amp;gt;currentText());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and also the corresponding headers of course:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 #include &amp;lt;qlineedit.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;qcombobox.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;qmultilineedit.h&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;lt;&lt;br /&gt;
Run ''Build -&amp;gt; Run automake &amp;amp; friends'', ''Build-&amp;gt; Run Configure'', ''Build -&amp;gt; Build Project'', ''Build -&amp;gt; Install'' (or ''Build-&amp;gt;Install as root user''), ''Build -&amp;gt; Execute Program''. That's it! The program is working!&lt;br /&gt;
&lt;br /&gt;
(Picture 20)&lt;br /&gt;
&lt;br /&gt;
A few more words about signals and slots. The signals and slots mechanism is type safe: the signature of a signal must match the signature of the receiving slot (for example, you will connect valueChanged(int) with a slot having an int as argument). And another thing to keep in mind is that all classes that inherit from QObject or one of its subclasses (e.g. QWidget) can contain signals and slots.&lt;br /&gt;
&lt;br /&gt;
All the strings used in KDE program must be wrapped in the i18n() function (klocale.h as header) because all KDE projects are translated. Please see the KDE Translation HowTo to learn more about i18n to make translations for an application.&lt;br /&gt;
&lt;br /&gt;
==In Short==&lt;br /&gt;
&lt;br /&gt;
This is a short resume on how to work with KDevelop and QtDesigner.&lt;br /&gt;
* In the KDevelop menu File-&amp;gt;New, select a Widget (.ui) file and give it a name (kprojectdlg for that example), check add to Project. Click OK.&lt;br /&gt;
* Qt Designer starts. Work on your form in Qt Designer then save your file and close designer. The designer file appears then in KDevelop under User Interface (kprojectdlg.ui).&lt;br /&gt;
* Create a new class (KProject as name for example) (Project menu then New class...) that inherits from your dialog file (kprojectdlg) and is a QWidget-childclass.&lt;br /&gt;
* Add your slots and others signals or member functions in the inherited class KProject. &lt;br /&gt;
&lt;br /&gt;
== Make the Translations for a Simple KDE Project==&lt;br /&gt;
&lt;br /&gt;
When your own project is finished, you may like to have one or several translations for the GUI. Here is how you can do that.&lt;br /&gt;
&lt;br /&gt;
=== Install gettext Patched for KDE ===&lt;br /&gt;
&lt;br /&gt;
Install a patched gettext that you can find on developer.kde.org and install it in your home directory. The patched gettext can be found there : http://public.kde.planetmirror.com/pub/kde/devel/gettext-kde/&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 $ tar xvzf gettext-0.10.35-kde.tar.gz&lt;br /&gt;
 $ cd gettext-0.10.35-kde&lt;br /&gt;
 $ ./configure&lt;br /&gt;
 $ make&lt;br /&gt;
 $ mkdir -p ~/bin&lt;br /&gt;
 $ cp src/gettext src/xgettext ~/bin # copy gettext and xgettext into your HOME/bin directory&lt;br /&gt;
 $ export PATH=~/bin:$PATH&lt;br /&gt;
&amp;lt;code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
=== Prepare the Translations ===&lt;br /&gt;
&lt;br /&gt;
Then, go into your project directory :&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 $ cd /path/to/myproject&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Set KDEDIR to match your kde installation - on my Mandrake it is /usr This path can also be found by doing &amp;quot;kde-config --prefix&amp;quot;&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 $ export KDEDIR=`kde-config --prefix` # or export KDEDIR=/usr&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Then create the translations files :&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 $ make -f admin/Makefile.common package-messages&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Make the Translations ===&lt;br /&gt;
&lt;br /&gt;
Translate the .po files using kbabel These files are in the po directory of your project.&lt;br /&gt;
* Warning - Do not touch the .pot file!&lt;br /&gt;
&lt;br /&gt;
=== Compile and Install the Translations Files ===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 $ make package-messages&lt;br /&gt;
 $ sudo make install&lt;br /&gt;
&amp;lt;/code&amp;gt; &lt;br /&gt;
&lt;br /&gt;
==General Tips==&lt;br /&gt;
===General Hints===&lt;br /&gt;
==== Your Application Name ====&lt;br /&gt;
&lt;br /&gt;
KDE application names generally start with the letter K followed by a name suggesting what the program does. For example, KMail is very simple and tells the user that this is indeed a KDE application and about email. A good practice is to choose an english name for the name that follows the K. Of course, this is just an indication and you are free to do what you want. But a good name can help to get your program known quicker.&lt;br /&gt;
&lt;br /&gt;
* Note - Run a search in Google (in Konqueror, write gg:your_app_name) to see if the name you want to use is not the name of a copyrighted program. If this is the case or if in doubt, change it.&lt;br /&gt;
&lt;br /&gt;
==== Coding Practice ====&lt;br /&gt;
&lt;br /&gt;
Comments should be in English as it is really easier if someone else has a look at your code.&lt;br /&gt;
&lt;br /&gt;
Class names usually are also in English and the names must indicate what the class does. Good examples: TopLevel, CursorInterface, TaskManager. Note the upper case letters and remember that C++ is case-sensitive.&lt;br /&gt;
&lt;br /&gt;
Function names usually begin with a lower case letter and here are examples of good names:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void activateRaiseOrIconify();&lt;br /&gt;
void toDesktop(int);&lt;br /&gt;
void windowAdded(WId);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Code indentation can be whatever you like as long as the code is visible for other developers. Always keep in mind that other people will have a look in your code and try to make it easy to read. &lt;br /&gt;
&lt;br /&gt;
=== Importing your project in KDE CVS ===&lt;br /&gt;
&lt;br /&gt;
Your program interests people, you feel you have time to really work on it, you need more feedback and help for improving it. You also agree to release it under the GPL license or equivalent. You can ask for a cvs account to import it in kdenonbeta. The kdenonbeta module is quite big and is not distributed with the official KDE. It is not packaged nor translated and feature freeze does not apply to kdenonbeta. Its purpose is to allow other developers to work on your application and to test it. Of course, you will need qt-copy, arts and kdelibs from cvs HEAD at least. Please see a tutorial here on how to get started for compiling KDE from cvs HEAD.&lt;br /&gt;
Note&lt;br /&gt;
When your application has the most important features, when it's totally KDE compatible (i18n, xml GUI, ect.), you will be able to ask for moving it in a KDE official package.&lt;br /&gt;
&lt;br /&gt;
In order to get a cvs account, please follow theses instructions. Send a mail to sysadmin (at) office (dot) kde (dot) org to justify why you need cvs access. Tell that you want to import your application (app_name) in the kdenonbeta module. Make sure to specify your full name and e-mail address, if the From field in your mails doesn't specify them. You can also choose a nickname for your user login. You can currently choose between the standard non-encrypted CVS protocol (pserver) and the encrypted CVS-over-ssh. If you choose pserver, send also an encrypted password (for instance using useradd dummy ; passwd dummy ; grep dummy /etc/passwd /etc/shadow). If you choose CVS-over-ssh, send a public ssh key (e.g. ~/.ssh/id_dsa.pub).&lt;br /&gt;
&lt;br /&gt;
Wait for the answer from a KDE sysadmin.&lt;br /&gt;
&lt;br /&gt;
Once you have compiled at least qt-copy, arts and kdelibs, you need to check out kdenonbeta files. Log in the cvs server with your login user and password.&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    $ cvs co -l kdenonbeta&lt;br /&gt;
    $ cd kdenonbeta&lt;br /&gt;
    $ cvs co admin  (or ln -s ../kde-common/admin .admin)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
You copy your project main dir with everything in kdenonbeta and then, in your project main dir, you issue a:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    $ make disclean&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
All the .o files must be gone. You can also remove by hand all Makefile, Makefile.in (not Makefile.am) and all kdevelop related files. Remove the admin, autom4te.cache, debug, doc, po and templates folders. You must just keep some files and the src subdir. Then, you cd .. to go back in kdenonbeta and you type:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    $ make -f Makefile.cvs&lt;br /&gt;
    $ ./configure --prefix=$KDEDIR&lt;br /&gt;
    $ cd your_project_name&lt;br /&gt;
    $ make&lt;br /&gt;
    $ su -c 'make install'&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
All these steps must go well. If there are errors, you should be able to correct them by carefully reading the error message. If you are really stuck, please go to IRC and ask on #kde or #kde-devel, someone will help you.&lt;br /&gt;
&lt;br /&gt;
then, in kdenonbeta dir:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    $ cvs add your_project_name&lt;br /&gt;
    $ cvs add your_project_name/*&lt;br /&gt;
    $ cvs add your_project_name/src&lt;br /&gt;
    $ cvs add your_project_name/src/*&lt;br /&gt;
    $ cvs commit&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You get the window (vi editor as default) where you can log your message. It's a good practice to note what your commit is about. In your case, you will say (type i first if you are in vi to get in edit mode):&lt;br /&gt;
&lt;br /&gt;
First import of your_app_name which does this and that.&lt;br /&gt;
&lt;br /&gt;
Check if all the files are added correctly. If not, cvs add filename and cvs commit.&lt;br /&gt;
&lt;br /&gt;
Each time you want to work on your project, don't forget to log in the kde server with your user login and password and do a:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
    $ cvs up&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
to be sure you have the latest version.&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/KDE3/Qt_Designer_and_KDevelop_3.0_for_Beginners</id>
		<title>Development/Tutorials/KDE3/Qt Designer and KDevelop 3.0 for Beginners</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/KDE3/Qt_Designer_and_KDevelop_3.0_for_Beginners"/>
				<updated>2007-01-10T03:03:52Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Implementing the Slot */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
{{KDE3}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
To get us started doing something useful with [http://www.trolltech.com/products/qt/features/designer Qt Designer], we are going to build a simple program that will show you the power of Qt Designer and [http://www.kdevelop.org/ KDevelop]. I hope that this will help you to create your first &amp;quot;real&amp;quot; KDE application.&lt;br /&gt;
&lt;br /&gt;
[http://www.trolltech.com/products/qt/features/designer KDevelop] will help you to build a complete KDE application. The KDE project uses the autoconf and automake tools for KDE 3.x, and [http://www.kdevelop.org/ KDevelop] will provide you with all the necessary files (admin directory, Makefile.cvs, Makefile.am,...).&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
===How to Get Qt Designer===&lt;br /&gt;
====From your Distribution====&lt;br /&gt;
Qt Designer is part of the qt-3.2.x package and above. If you have an older Qt on your system, you should get at least this version. At the time of writing, Qt latest version is 3.3.2.&lt;br /&gt;
&lt;br /&gt;
Please remember to check if you have all the qt-related packages installed. You need the qt headers in order to compile this tutorial application. These headers usually come in the ''devel'' package. You also need to be sure you have designer. In some distributions, it comes in a separate package.&lt;br /&gt;
&lt;br /&gt;
To check if you have everything, do a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;locate qstring.h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you get something like ''/usr/lib/qt3/include/qstring.h'' then you can set your ''QTDIR'' variable to ''/usr/lib/qt3/''. In bash environment, this is done by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export QTDIR= /usr/lib/qt3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Tarball or Anonymous Subversion====&lt;br /&gt;
You can download the tarball from the [http://www.trolltech.com/download/qt/x11.html Trolltech website], or get the ''qt-copy'' module from SVN. Please note that Qt for [http://www.kernel.org/ Linux] is [http://www.gnu.org/copyleft/gpl.html GPL].&lt;br /&gt;
&lt;br /&gt;
For an explanation for how to use anonymous SVN, get the ''qt-copy'' and ''kde'' modules and compile them, please see a great documentation at [[Getting_Started/Sources/Using Subversion with KDE|Using Subversion with KDE]].&lt;br /&gt;
&lt;br /&gt;
You must then set the ''QTDIR'' environment variable. This should point to the directory into which you installed Qt. In bash, for example, you would type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export QTDIR= /usr/local/qt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
provided that ''/usr/local/qt'' is the directory into which you installed Qt. Please read the INSTALL file for more details.&lt;br /&gt;
&lt;br /&gt;
You then compile by issuing the following commands, here is the recommended compile line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure -system-zlib -qt-gif -system-libpng -system-libjpeg \&lt;br /&gt;
-plugin-imgfmt-mng -thread -no-exceptions -debug -fast&lt;br /&gt;
make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The command ''make install'' is not needed.&lt;br /&gt;
&lt;br /&gt;
Qt Designer is located in the ''bin'' directory of your Qt installation directory. You can run it by typing:&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/qt/bin/designer&amp;lt;/code&amp;gt;&lt;br /&gt;
in a console.&lt;br /&gt;
&lt;br /&gt;
To compile Qt from source, please see [http://www.trolltech.com/ Trolltech]'s [http://www.trolltech.com/developer/downloads/qt/x11 Qt/X11 Open Source Edition] page.&lt;br /&gt;
&lt;br /&gt;
===How to get KDevelop 3===&lt;br /&gt;
====From your Distribution====&lt;br /&gt;
KDevelop 3 should be part of your distribution. Pre 3 versions of KDevelop were nicknamed Gideon, but they are obsolete now.&lt;br /&gt;
&lt;br /&gt;
====From Tarball====&lt;br /&gt;
KDevelop can be downloaded from the [http://www.kdevelop.org KDevelop website], under the '''Quick download''' heading.&lt;br /&gt;
&lt;br /&gt;
To compile KDevelop 3, you need qt-3.1.0 or higher and kdelibs-3.1.0 or higher. The environment variables ''QTDIR'' and ''KDEDIR'' should point to those directories.&lt;br /&gt;
&lt;br /&gt;
Don't forget to set up the KDE and Qt paths. The most common errors while using KDevelop come from the environment variables not set up properly. Check in a console by issuing the command '''set''' to see all your environment variables. You should set your ''PATH'' variable as follow as well as your ''LD_LIBRARY_PATH'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export PATH=$QTDIR/bin:$KDEDIR/bin:$PATH&lt;br /&gt;
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have any problem getting KDevelop running, please refer to the [http://www.kdevelop.org/phorum5/ KDevelop Forum] to find the answer to your problem.&lt;br /&gt;
&lt;br /&gt;
If you never used KDevelop before, try to create a new project and to compile it to get used to the interface and the icons. &lt;br /&gt;
&lt;br /&gt;
====KDevelop 3.4====&lt;br /&gt;
Please refer to [http://www.kdevelop.org/index.html?filename=3.4/download.html Downloading KDevelop 3.4] and [http://www.kdevelop.org/index.html?filename=3.4/branches_compiling.html Compiling KDevelop 3.4].&lt;br /&gt;
&lt;br /&gt;
===Lexicon===&lt;br /&gt;
* '''Widget''': a widget is an element of an graphical interface such as a container window, a button or a field for entering text.&lt;br /&gt;
* '''Layout management''': this term describes the way in which widgets are arranged in a window. In its simplest form, an element may be placed at a specific position and given a specific height and width. But when the user resizes the window, the widgets should stay in their position and change their size accordingly. Linux allows to do that by using layouts to place the widgets in.&lt;br /&gt;
* '''Signal and Slots''': Signals and slots are used for communication between objects. The signal/slot mechanism is a central feature of Qt. Signals are emitted by objects when they change their state in a way that may be interesting to the outside world. Slots can be used for receiving signals, but they are normal member functions. You can connect as many signals as you want to a single slot, and a signal can be connected to as many slots as you desire. Please see the [http://doc.trolltech.com/3.3/signalsandslots.html TrollTech documentation on signals and slots] for more details. In the excellent online documentation that comes with Qt, you'll find the signals and the public slots that go with each class. You can then implement your own slots. &lt;br /&gt;
&lt;br /&gt;
==Creating the Application==&lt;br /&gt;
===Starting the project===&lt;br /&gt;
====Creating the framework with KDevelop====&lt;br /&gt;
&lt;br /&gt;
The framework in which our program will sit in (i.e. the main window) can be done easily and quickly by using KDevelop. Start KDevelop and select ''New Project'' in the Project menu. The Application Wizard appears then. Choose a ''C++ -&amp;gt; KDE -&amp;gt; Simple KDE Application''. Fill in the blank lines with the project name '''SigCreate''', your name as author, and your email.  Refer to [[:Image:KDevelop3-CreateNewProject.png|this screen shot]] as a reference.&lt;br /&gt;
&lt;br /&gt;
Click on ''Next''. Have a look to the CVS option and the header templates. Then click on ''Finish'' on the last screen. KDevelop creates all the files that you need to compile your project. You can use the file selector to view the code of the 3 files which are main.cpp, sigcreate.cpp and sigcreate.h, as shown [[:Image:KDevelop3-FileSelector.png|here]].&lt;br /&gt;
&lt;br /&gt;
Once the ''Application Wizard'' has created your application, compile it to ensure that everything is fine. To do that, select '''Build -&amp;gt; Run automake &amp;amp; friends''' then '''Build -&amp;gt; Run configure'''. The ''Messages output window'' should say&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot; Good - your configure finished. Start make now&lt;br /&gt;
*&lt;br /&gt;
* *** Success ***&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
so you can run ''make'' with '''Build -&amp;gt; Build Project''' (or using the F8 shortcut). Then '''Build -&amp;gt; Install'''. Then '''Build -&amp;gt; Execute program''' (or F9). The result is shown [[:Image:KDevelop-SigCreate.png|here]].&lt;br /&gt;
&lt;br /&gt;
*'''NOTE''' - If KDevelop does not recognize your ''QTDIR'' and ''KDEDIR'' variables, you can set them in '''Project -&amp;gt; Project Options...''' in ''Configure Options'', as [[:Image:KDevelop3-ConfigureOptions.png|shown]].&lt;br /&gt;
&lt;br /&gt;
====Using Qt Designer====&lt;br /&gt;
Qt Designer is a tool for designing and implementing user interfaces. It helps you arranging your widgets on a form and adding a proper layout so your interface can be resized properly. I recommend that you read the [http://doc.trolltech.com/3.3/designer-manual.html Qt Designer manual] to know everything about Qt Designer. Qt Designer includes a code editor but we'll use KDevelop to edit and modify all code.&lt;br /&gt;
&lt;br /&gt;
We will now create the interface of our application using Qt Designer. A form from Qt Designer is saved with a .ui extension because it is then processed by the uic program to generate a .h and .cpp files. KDevelop takes care of that, the only thing we need to do is to create the form.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - Each time you add or remove a file (now we will add a .ui file) in your KDevelop project, the Makefile.am will be changed. KDevelop does that itself but you will need to ''Run automake &amp;amp; friends'' after such changes.&lt;br /&gt;
&lt;br /&gt;
In KDevelop, click on '''File -&amp;gt; New''' and fill the dialog window that appears. First write the file name: ''sigcreatedlg'' and select what new file you want in the combobox: here we want a ''Widget (.ui)''. Please be sure that '''Add to project''' is checked, this ensures that the Makefile.am is updated. Refer to [[:Image:KDevelop3-NewFile-Widget.png|this screen shot]].&lt;br /&gt;
&lt;br /&gt;
Click the ''OK'' button. The [[:Image:KDevelop3-AutomakeManagerDialog.png|Automake manager dialog]] then pops up.  Click the ''OK'' button for this dialog as well.&lt;br /&gt;
&lt;br /&gt;
If the new file ''sigcreatedlg.ui'' is not open in Qt Designer, open the ''Automake Manager'', right-click on the file and select ''Open With'', then ''Qt Designer''. Qt Designer will open.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - About the names: it is a good idea to finish a dialog name or a form name by ''dlg'' to ensure a nice visibility for people who want to have a look at the code. ''sigcreatedlg'' says that it is a dialog, i.e an interface class, only.&lt;br /&gt;
&lt;br /&gt;
The [[:Image:QtDesigner3-Interface.png|Qt Designer interface]] is essentially split into three areas. On the left is the '''toolbox''', where you can select your widgets. On the right, several dialogs can be selected. I'll keep only the '''Property Editor''' dialog (I close the 2 others). Your widgets can be fine tuned to behave how you want them to. You can choose the size of the widget, its background color (palette), and so on. Between those 2 windows is the '''Form''', your program window, within which you will design your user interface.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - After adding the ''sigcreatedlg.ui'' file, you will have to run ''Automake &amp;amp; friends'' and ''Run configure'' before building the program. This ensures that the updated ''Makefile.am'' is now read. &lt;br /&gt;
&lt;br /&gt;
===Designing the Program===&lt;br /&gt;
&lt;br /&gt;
Each time you want to use Qt Designer, you should have a precise visual idea of the design of your interface. You can see in [[:Image:KDevelop3-SigCreateDialog.png|this picture]] what the program will be like. It is a window with a number of different items (or widgets) on it, designed so that the user puts the right information in the right boxes. You should always design your program from the user's point of view, as it must be easy to use.&lt;br /&gt;
&lt;br /&gt;
This application creates an email signature, which is then displayed on the screen. The user should enter her/his name, email address, and then select one of three comments. When you click the '''Create!''' button, the generated signature is shown in a ''MultiLineEdit''. When you click '''Cancel''', the program quits.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - Note that this project is meant as a tutorial, so this is somewhat far away from practical use.&lt;br /&gt;
&lt;br /&gt;
Go back to the Qt Designer window with the new dialog open. You will see that the property editor has been filled with details about the form you have created. The first line in the '''Property Editor''' [[:Image:QtDesigner3-PropertyEditor.png|shows]] the name of the form which is Form1. Click on the field with this name to change it and type SigCreateDlg. This will form the class name of the dialog so you should name it something useful.&lt;br /&gt;
&lt;br /&gt;
To change properties, select the property you wish to change, then alter its setting on the right. Change the '''Caption''' property to &amp;quot;SigCreateDlg v.01&amp;quot;.   We will now begin to add widgets on our dialog.&lt;br /&gt;
&lt;br /&gt;
===Adding Widgets===&lt;br /&gt;
&lt;br /&gt;
To start, we will insert the text at the top of the program window, which can be seen [[:Image:KDevelop3-NewFile-Widget.png|here]]. This text tells the user how to operate the program. This type of widget is called a ''Label'' and you can put one on your program like this:&lt;br /&gt;
&lt;br /&gt;
# Select the dialog in ToolBox called '''Common Widgets-&amp;gt;TextLabel''', or from the menubar '''Tools-&amp;gt;Display-&amp;gt;TextLabel'''&lt;br /&gt;
# The cursor will become a crosshair over the form. Draw a box for the label, just as you would in a paint program, and you will see that the label is created with some dummy text in it.&lt;br /&gt;
# To change this text, double click on the label and type in the text, instead of ''TextLabel1''. The text you should type is ''This program will create an email signature for you. Just fill in the boxes and hit the Create! button.'' Select '''Align Center'' to have the text positioned nicely.  Refer to this [[:Image:QtDesigner3-TextEditDialog.png|screenshot]].&lt;br /&gt;
# Finally, resize the widget using the handles so it is the correct size and at the top of the box. Try to center the label by moving it with the mouse. This is just a temporary measure. Later on we will look at a more elegant layout management technique. You may refer to [[:Image:QtDesigner3-ResizingBox.png|this screenshot]].&lt;br /&gt;
&lt;br /&gt;
You follow pretty much the same procedure for embedding any type of widget that is supported by Qt Designer; select it, drag it, and finally, change its properties and size.&lt;br /&gt;
&lt;br /&gt;
An interesting concept in Qt Designer is that widgets can act as containers for other widgets. This will be demonstrated in our next task, which is to create the input fields inside the frame. You can see that in Picture 8 we have a bunch of labels and text boxes inside a frame. This frame is called a Group Box and acts as a container for the labels and text boxes inside it. Let's first create the frame by selecting the GroupBox in the '''Toolbox dialog-&amp;gt;Containers''' or '''Tools-&amp;gt;Containers-&amp;gt;GroupBox''' from the menubar. You can drag the mouse to create the box just below the Label you put before. In the ''Property Editor'' you can change the title property to alter the text in the frame. Put ''Details'' in the title text field. You may notice a + symbol in this entry in the ''Property Editor''. This indicates that the property has subproperties that can also be changed.&lt;br /&gt;
&lt;br /&gt;
Once you have created the frame (i.e the GroupBox), create three more labels as before but when you draw them, draw them inside the GroupBox frame. You can then see in the Object Explorer box ('''Windows menu -&amp;gt; Views -&amp;gt; Object Explorer''') to the right that the labels have become children of the GroupBox frame. See [[:Image:QtDesigner3-EditingTheDialog.png|this image]].&lt;br /&gt;
&lt;br /&gt;
Change the text of labels by double-clicking on it.&lt;br /&gt;
&lt;br /&gt;
Once you have done this you can then create the text boxes. They will allow the user to type in text like his(her) name and email address. We use the simplest type of text boxes: a widget called QLineEdit which allows the user to enter one line of text only. You have to create two QLineEdit widgets for the name and the email address. You choose the menu Tools then the entry Input then LineEdit and you draw it beside the 'Your Name' Label. Do the same below for the address.&lt;br /&gt;
&lt;br /&gt;
The witty comment will be selected by the user. We use a ComboBox which will present the user with three comments. Click on the ComboBox icon or select it via the Tools-&amp;gt; Input-&amp;gt; ComboBox menu. Draw it beside the Witty Comment label. Then double-click on it. You will be presented with a box into which you can add the contents of the combo box. Click on the 'New Item' button and type in your comment in the text box at the right. Then click again on 'New Item' for the second and third comments. Click on OK when you have finished.&lt;br /&gt;
&lt;br /&gt;
Adjust the size of the different widgets so they are nicely placed.&lt;br /&gt;
&lt;br /&gt;
Up to now, we have not named any of the widgets that are being placed in our program. It is useful to set an internal name for widgets so we can call them after in the program. Labels don't perform any action so they don't need to be named but other widgets do. It is the case now for our text boxes. We'll need to manipulate the data from the three input widgets (i.e. read the text) so we should give them a name. Names should be easily recognized later and they should make sense. The names are assigned via the name property on the top of the Property Editor. We name the top LineEdit nameBox and the second one mailBox. We name the ComboBox commBox. This will allow us to access the comments. So click on each LineEdit and then besides Name in the Property Editor write nameBox and mailBox. Then click on the ComboBox and name it commBox.&lt;br /&gt;
&lt;br /&gt;
We finish the graphical design by adding a label with 'Generated Signature' as text. Below it, we put a TextEdit ('''Tools-&amp;gt;Input-&amp;gt;TextEdit'''') where the generated signature will be displayed. We name it 'sigBox'. And then we add two PushButtons at the bottom ('Create!' and 'Cancel'). They don't need names but you can give them some if you want.&lt;br /&gt;
&lt;br /&gt;
Save your form. You can now have a quick preview by selecting the menu '''Preview-&amp;gt; Preview Form'''.  [[:Image:QtDesigner3-BeforeLayoutManagement.png|This]] is the form ''before'' layout management.&lt;br /&gt;
&lt;br /&gt;
===Getting Spaced Out===&lt;br /&gt;
This section describes the layout management. If you resize the preview window you will then notice that the widgets do not adjust appropriately. They are not resized. To improve things, we need to use a feature in Qt called spacers. Spacers are like virtual springs that push the widgets on each side apart.&lt;br /&gt;
* '''Note''' - Having a good layout is essential for your application, as when the strings are translated, they might be longer than the English ones and they need to fit on your widgets. The geometry of the widgets has to be nice if the user can resize your window application. Layouts are done by trial and error so use '''Preview-&amp;gt;Preview Form''' to see the result of your layout management and to achieve the best layout.&lt;br /&gt;
&lt;br /&gt;
The use of spacers and layout management is a skill that is developed through trial and error. The main thing to remember when dealing with spacers is that you work horizontally first and then vertically.&lt;br /&gt;
&lt;br /&gt;
We will first use spacers to center the text in the top box. Resize your label so that it only get the size of the text. Then we add two spacers, one at each side. Choose the 'spring' icon or menu '''Layout-&amp;gt; Add Spacer'''. You adjust each of the spacers horizontally. Click the space to the left of the text and the blue spacer will appear . Repeat the same procedure for the right. Then add a spacer on the right of the 'Generated Signature' label, and a last one on the left of the the 'Create!' pushbutton. Please use [[:Image:QtDesigner3-AddingTheSpacers.png|this image]] as a reference.&lt;br /&gt;
&lt;br /&gt;
Now that we have spacers to fill blank space, we need a proper layout management. This will allow the widgets to be nicely resized whenever the main window is resized. It is really compulsory to have good layout management. Again, try to resize several times to see if everything is in place. We can use Vertical or horizontal layout or grid management. The top row of widget is horizontal (spacer + label + spacer) so we need Horizontal management. We need to select the three widgets alltogether: click on the first spring, then click on the label while holding down ''Shift'', then on the second spring while holding down ''Shift''. Then click on the Horizontal Layout icon or menu '''Layout-&amp;gt; Lay Out Horizontally'''. You will then see a resizable red line around the three objects to indicate that their layout is being managed. Resize the red box if it needs to.&lt;br /&gt;
&lt;br /&gt;
We can now repeat this procedure for the three labels inside the GroupBox, this time using vertical layout management. The same vertical management for the two LineEdit and the ComboBox. It is better to use vertical management to keep the object aligned. If we use horizontal management for each label + text box then they will not stay aligned and equally sized. Horizontal management is needed for the label with the spacer and another one for the two pushbuttons and the spacer.&lt;br /&gt;
&lt;br /&gt;
To finish the layout, we need to let the form look after the laid-out boxes. We put everything in a grid. This is done by right clicking the form and selecting &amp;quot;Lay Out in a Grid&amp;quot; from the menu. The final design with layout lines should resemble something similar to [[:Image:QtDesigner3-CompleteLayoutManagement.png|this image]].&lt;br /&gt;
&lt;br /&gt;
===Signals and Slots===&lt;br /&gt;
&lt;br /&gt;
[http://doc.trolltech.com/3.0/signalsandslots.html Signals and Slots] are used for communication between Qt objects. The signal/slot mechanism is a central feature of Qt and probably the part that differs most from other toolkits which often use callbacks. In Qt, a signal is emitted by a widget when a particular event occurs, very often triggered by the user like for example pressing a button or writing something in a LineEdit. A slot is simply a function that is called in reponse to a particular signal.&lt;br /&gt;
&lt;br /&gt;
Now the widgets are implemented and the layout is arranged the final thing we need to do in the design stage of the form is to create the signal/slot connections. To do this manually requires a ''connect()'' function but Qt Designer provides a simple yet effective solution. To create the signal/slot connections we need to use the connecting tool. To do this either select the icon (it looks like a red arrow going into a green square) or select '''Tools-&amp;gt; Connect Signals/Slots''' from the menu (or use the F3 shortcut key). To create a connection, click on the form on the widget that is going to be dealing with the slot, drag the line off the form and release the mouse button.&lt;br /&gt;
&lt;br /&gt;
Let's deal first with the Create! button. Click first on the '''Connect Signal/Slot''' icon or select it from the Tools menu or use the F3 key. Then click on the Create! button with the crosshair and drag the line off the form completely. When you have released the mouse button you will see the connections tool shown [[:Image:QtDesigner3-CreateSlot.png|here]].&lt;br /&gt;
&lt;br /&gt;
What we want to do is to create a slot that will create our signature when the user clicks on the Create! button. The signal will be clicked() (you may choose among five signals for a QPushButton) and we need to create the slot then make the connection.&lt;br /&gt;
&lt;br /&gt;
To create the slot we need to click on the '''Edit Slots''' button. The slot creation box then appears. See [[:Image:QtDesigner3-CreateSlot.png|this example]]. Now click on the '''New Function''' button and a slot will appear in the box. Instead of ''new_slot()'' rename it to ''slotCreateSig()'' and leave the access specifier as public. When you click on ''OK'' you will be returned to the connections box and you will see your new slot in the Slots section of the box.&lt;br /&gt;
&lt;br /&gt;
To [[:Image:QtDesigner3-ViewandEditConnections.png|make a connection]] you simply select the appropriate signal (which is ''clicked()'' in our case) and then select the slot (which is our new slot ''slotCreateSig()''). When you have selected both signal and slot you will see the connection made at the bottom of the screen. After you are finished click OK.&lt;br /&gt;
&lt;br /&gt;
Repeat the procedure for the Cancel button by using the clicked() signal and the close() slot. You are now done with the signals and slots.&lt;br /&gt;
* '''Warning''' - Don't forget to save your form!&lt;br /&gt;
&lt;br /&gt;
===Generating the Source===&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we use KDevelop subclassing tool in Automake Manager. If you have KDevelop version which has not that capability, then please go to Chapter 7 where I explain this step without the subclass tool.&lt;br /&gt;
&lt;br /&gt;
Here we start with the KDE simple project named SigCreate and the sigcreatedlg.ui that we have added in our project. In the Automake Manager, in the section sigcreate (Program in bin) you must have three files: sigcreatedlg.ui, sigcreate.cpp and main.cpp. The project must compile and give the main window as in picture 3 (creating.html).&lt;br /&gt;
&lt;br /&gt;
As the sigcreate class is no use for us, we will remove it and use it for subclassing the sigcreatedlg.ui file. In the Automake Manager, right click on sigcreate.cpp and select Remove and a dialog pops up. Please check 'Also Remove it from disk'. Then do the same with sigcreate.h. This is the way to remove obsolete files from your project and the Makefile.am will be updated. Remember to run automake &amp;amp; friends and configure before compiling your project again. We will not do it right now because we will make other changes. We will now use the class name SigCreate for the subclass.&lt;br /&gt;
&lt;br /&gt;
In the Automake Manager, in sigcreate (program in bin), right click on sigcreatedlg.ui and choose Subclass Widget... from the context menu that appears. Then fill in the subclass name which is SigCreate. Check the box: Reformat source and click on OK. Say No then about adding these files in cvs as we did not enable this in our project.&lt;br /&gt;
Note&lt;br /&gt;
You can see that the slot we created in designer is listed here and checked, the method will be implemented in the generated files. If you uncheck it, the code will not be generated in your class.&lt;br /&gt;
&lt;br /&gt;
(The subclass dialog Image)&lt;br /&gt;
&lt;br /&gt;
We have to suppress some lines in main.cpp as the KDE simple project template refers to a KMainWindow which is usually the base class used. But here, SigCreate is based on QWidget. You have to remove all the lines between KApplication app; and return app.exec(); except the ones I keep here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SigCreate *mainWin = 0;&lt;br /&gt;
&lt;br /&gt;
mainWin = new SigCreate();&lt;br /&gt;
app.setMainWidget( mainWin );&lt;br /&gt;
mainWin-&amp;gt;show();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Implementing the Slot===&lt;br /&gt;
&lt;br /&gt;
Then you implement the slot by adding the following lines in the parenthesis of:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
void SigCreate::slotCreateSig()&lt;br /&gt;
{}&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
to implement the slot&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
	sigBox-&amp;gt;append(&amp;quot;\n--&amp;quot;);&lt;br /&gt;
 	sigBox-&amp;gt;append(nameBox-&amp;gt;text());&lt;br /&gt;
 	sigBox-&amp;gt;append(mailBox-&amp;gt;text());&lt;br /&gt;
 	sigBox-&amp;gt;append(commBox-&amp;gt;currentText());&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
and also the corresponding headers of course:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
 #include &amp;lt;qlineedit.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;qcombobox.h&amp;gt;&lt;br /&gt;
 #include &amp;lt;qmultilineedit.h&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;lt;&lt;br /&gt;
Run ''Build -&amp;gt; Run automake &amp;amp; friends'', ''Build-&amp;gt; Run Configure'', ''Build -&amp;gt; Build Project'', ''Build -&amp;gt; Install'' (or ''Build-&amp;gt;Install as root user''), ''Build -&amp;gt; Execute Program''. That's it! The program is working!&lt;br /&gt;
&lt;br /&gt;
(Picture 20)&lt;br /&gt;
&lt;br /&gt;
A few more words about signals and slots. The signals and slots mechanism is type safe: the signature of a signal must match the signature of the receiving slot (for example, you will connect valueChanged(int) with a slot having an int as argument). And another thing to keep in mind is that all classes that inherit from QObject or one of its subclasses (e.g. QWidget) can contain signals and slots.&lt;br /&gt;
&lt;br /&gt;
All the strings used in KDE program must be wrapped in the i18n() function (klocale.h as header) because all KDE projects are translated. Please see the KDE Translation HowTo to learn more about i18n to make translations for an application.&lt;br /&gt;
&lt;br /&gt;
==In Short==&lt;br /&gt;
==Make the translations for a simple kde project==&lt;br /&gt;
==A few general tips==&lt;br /&gt;
==Generating the source (alternate)==&lt;br /&gt;
==Credits and License==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/KDE3/Qt_Designer_and_KDevelop_3.0_for_Beginners</id>
		<title>Development/Tutorials/KDE3/Qt Designer and KDevelop 3.0 for Beginners</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/KDE3/Qt_Designer_and_KDevelop_3.0_for_Beginners"/>
				<updated>2007-01-10T03:01:07Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Generating the Source */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{improve}}&lt;br /&gt;
{{KDE3}}&lt;br /&gt;
&lt;br /&gt;
==Introduction==&lt;br /&gt;
To get us started doing something useful with [http://www.trolltech.com/products/qt/features/designer Qt Designer], we are going to build a simple program that will show you the power of Qt Designer and [http://www.kdevelop.org/ KDevelop]. I hope that this will help you to create your first &amp;quot;real&amp;quot; KDE application.&lt;br /&gt;
&lt;br /&gt;
[http://www.trolltech.com/products/qt/features/designer KDevelop] will help you to build a complete KDE application. The KDE project uses the autoconf and automake tools for KDE 3.x, and [http://www.kdevelop.org/ KDevelop] will provide you with all the necessary files (admin directory, Makefile.cvs, Makefile.am,...).&lt;br /&gt;
&lt;br /&gt;
==Requirements==&lt;br /&gt;
&lt;br /&gt;
===How to Get Qt Designer===&lt;br /&gt;
====From your Distribution====&lt;br /&gt;
Qt Designer is part of the qt-3.2.x package and above. If you have an older Qt on your system, you should get at least this version. At the time of writing, Qt latest version is 3.3.2.&lt;br /&gt;
&lt;br /&gt;
Please remember to check if you have all the qt-related packages installed. You need the qt headers in order to compile this tutorial application. These headers usually come in the ''devel'' package. You also need to be sure you have designer. In some distributions, it comes in a separate package.&lt;br /&gt;
&lt;br /&gt;
To check if you have everything, do a:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;locate qstring.h&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you get something like ''/usr/lib/qt3/include/qstring.h'' then you can set your ''QTDIR'' variable to ''/usr/lib/qt3/''. In bash environment, this is done by typing:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export QTDIR= /usr/lib/qt3&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Tarball or Anonymous Subversion====&lt;br /&gt;
You can download the tarball from the [http://www.trolltech.com/download/qt/x11.html Trolltech website], or get the ''qt-copy'' module from SVN. Please note that Qt for [http://www.kernel.org/ Linux] is [http://www.gnu.org/copyleft/gpl.html GPL].&lt;br /&gt;
&lt;br /&gt;
For an explanation for how to use anonymous SVN, get the ''qt-copy'' and ''kde'' modules and compile them, please see a great documentation at [[Getting_Started/Sources/Using Subversion with KDE|Using Subversion with KDE]].&lt;br /&gt;
&lt;br /&gt;
You must then set the ''QTDIR'' environment variable. This should point to the directory into which you installed Qt. In bash, for example, you would type:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export QTDIR= /usr/local/qt&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
provided that ''/usr/local/qt'' is the directory into which you installed Qt. Please read the INSTALL file for more details.&lt;br /&gt;
&lt;br /&gt;
You then compile by issuing the following commands, here is the recommended compile line:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;./configure -system-zlib -qt-gif -system-libpng -system-libjpeg \&lt;br /&gt;
-plugin-imgfmt-mng -thread -no-exceptions -debug -fast&lt;br /&gt;
make&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The command ''make install'' is not needed.&lt;br /&gt;
&lt;br /&gt;
Qt Designer is located in the ''bin'' directory of your Qt installation directory. You can run it by typing:&lt;br /&gt;
&amp;lt;code&amp;gt;/usr/local/qt/bin/designer&amp;lt;/code&amp;gt;&lt;br /&gt;
in a console.&lt;br /&gt;
&lt;br /&gt;
To compile Qt from source, please see [http://www.trolltech.com/ Trolltech]'s [http://www.trolltech.com/developer/downloads/qt/x11 Qt/X11 Open Source Edition] page.&lt;br /&gt;
&lt;br /&gt;
===How to get KDevelop 3===&lt;br /&gt;
====From your Distribution====&lt;br /&gt;
KDevelop 3 should be part of your distribution. Pre 3 versions of KDevelop were nicknamed Gideon, but they are obsolete now.&lt;br /&gt;
&lt;br /&gt;
====From Tarball====&lt;br /&gt;
KDevelop can be downloaded from the [http://www.kdevelop.org KDevelop website], under the '''Quick download''' heading.&lt;br /&gt;
&lt;br /&gt;
To compile KDevelop 3, you need qt-3.1.0 or higher and kdelibs-3.1.0 or higher. The environment variables ''QTDIR'' and ''KDEDIR'' should point to those directories.&lt;br /&gt;
&lt;br /&gt;
Don't forget to set up the KDE and Qt paths. The most common errors while using KDevelop come from the environment variables not set up properly. Check in a console by issuing the command '''set''' to see all your environment variables. You should set your ''PATH'' variable as follow as well as your ''LD_LIBRARY_PATH'':&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;export PATH=$QTDIR/bin:$KDEDIR/bin:$PATH&lt;br /&gt;
export LD_LIBRARY_PATH=$QTDIR/lib:$LD_LIBRARY_PATH&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
If you have any problem getting KDevelop running, please refer to the [http://www.kdevelop.org/phorum5/ KDevelop Forum] to find the answer to your problem.&lt;br /&gt;
&lt;br /&gt;
If you never used KDevelop before, try to create a new project and to compile it to get used to the interface and the icons. &lt;br /&gt;
&lt;br /&gt;
====KDevelop 3.4====&lt;br /&gt;
Please refer to [http://www.kdevelop.org/index.html?filename=3.4/download.html Downloading KDevelop 3.4] and [http://www.kdevelop.org/index.html?filename=3.4/branches_compiling.html Compiling KDevelop 3.4].&lt;br /&gt;
&lt;br /&gt;
===Lexicon===&lt;br /&gt;
* '''Widget''': a widget is an element of an graphical interface such as a container window, a button or a field for entering text.&lt;br /&gt;
* '''Layout management''': this term describes the way in which widgets are arranged in a window. In its simplest form, an element may be placed at a specific position and given a specific height and width. But when the user resizes the window, the widgets should stay in their position and change their size accordingly. Linux allows to do that by using layouts to place the widgets in.&lt;br /&gt;
* '''Signal and Slots''': Signals and slots are used for communication between objects. The signal/slot mechanism is a central feature of Qt. Signals are emitted by objects when they change their state in a way that may be interesting to the outside world. Slots can be used for receiving signals, but they are normal member functions. You can connect as many signals as you want to a single slot, and a signal can be connected to as many slots as you desire. Please see the [http://doc.trolltech.com/3.3/signalsandslots.html TrollTech documentation on signals and slots] for more details. In the excellent online documentation that comes with Qt, you'll find the signals and the public slots that go with each class. You can then implement your own slots. &lt;br /&gt;
&lt;br /&gt;
==Creating the Application==&lt;br /&gt;
===Starting the project===&lt;br /&gt;
====Creating the framework with KDevelop====&lt;br /&gt;
&lt;br /&gt;
The framework in which our program will sit in (i.e. the main window) can be done easily and quickly by using KDevelop. Start KDevelop and select ''New Project'' in the Project menu. The Application Wizard appears then. Choose a ''C++ -&amp;gt; KDE -&amp;gt; Simple KDE Application''. Fill in the blank lines with the project name '''SigCreate''', your name as author, and your email.  Refer to [[:Image:KDevelop3-CreateNewProject.png|this screen shot]] as a reference.&lt;br /&gt;
&lt;br /&gt;
Click on ''Next''. Have a look to the CVS option and the header templates. Then click on ''Finish'' on the last screen. KDevelop creates all the files that you need to compile your project. You can use the file selector to view the code of the 3 files which are main.cpp, sigcreate.cpp and sigcreate.h, as shown [[:Image:KDevelop3-FileSelector.png|here]].&lt;br /&gt;
&lt;br /&gt;
Once the ''Application Wizard'' has created your application, compile it to ensure that everything is fine. To do that, select '''Build -&amp;gt; Run automake &amp;amp; friends''' then '''Build -&amp;gt; Run configure'''. The ''Messages output window'' should say&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;quot; Good - your configure finished. Start make now&lt;br /&gt;
*&lt;br /&gt;
* *** Success ***&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
so you can run ''make'' with '''Build -&amp;gt; Build Project''' (or using the F8 shortcut). Then '''Build -&amp;gt; Install'''. Then '''Build -&amp;gt; Execute program''' (or F9). The result is shown [[:Image:KDevelop-SigCreate.png|here]].&lt;br /&gt;
&lt;br /&gt;
*'''NOTE''' - If KDevelop does not recognize your ''QTDIR'' and ''KDEDIR'' variables, you can set them in '''Project -&amp;gt; Project Options...''' in ''Configure Options'', as [[:Image:KDevelop3-ConfigureOptions.png|shown]].&lt;br /&gt;
&lt;br /&gt;
====Using Qt Designer====&lt;br /&gt;
Qt Designer is a tool for designing and implementing user interfaces. It helps you arranging your widgets on a form and adding a proper layout so your interface can be resized properly. I recommend that you read the [http://doc.trolltech.com/3.3/designer-manual.html Qt Designer manual] to know everything about Qt Designer. Qt Designer includes a code editor but we'll use KDevelop to edit and modify all code.&lt;br /&gt;
&lt;br /&gt;
We will now create the interface of our application using Qt Designer. A form from Qt Designer is saved with a .ui extension because it is then processed by the uic program to generate a .h and .cpp files. KDevelop takes care of that, the only thing we need to do is to create the form.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - Each time you add or remove a file (now we will add a .ui file) in your KDevelop project, the Makefile.am will be changed. KDevelop does that itself but you will need to ''Run automake &amp;amp; friends'' after such changes.&lt;br /&gt;
&lt;br /&gt;
In KDevelop, click on '''File -&amp;gt; New''' and fill the dialog window that appears. First write the file name: ''sigcreatedlg'' and select what new file you want in the combobox: here we want a ''Widget (.ui)''. Please be sure that '''Add to project''' is checked, this ensures that the Makefile.am is updated. Refer to [[:Image:KDevelop3-NewFile-Widget.png|this screen shot]].&lt;br /&gt;
&lt;br /&gt;
Click the ''OK'' button. The [[:Image:KDevelop3-AutomakeManagerDialog.png|Automake manager dialog]] then pops up.  Click the ''OK'' button for this dialog as well.&lt;br /&gt;
&lt;br /&gt;
If the new file ''sigcreatedlg.ui'' is not open in Qt Designer, open the ''Automake Manager'', right-click on the file and select ''Open With'', then ''Qt Designer''. Qt Designer will open.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - About the names: it is a good idea to finish a dialog name or a form name by ''dlg'' to ensure a nice visibility for people who want to have a look at the code. ''sigcreatedlg'' says that it is a dialog, i.e an interface class, only.&lt;br /&gt;
&lt;br /&gt;
The [[:Image:QtDesigner3-Interface.png|Qt Designer interface]] is essentially split into three areas. On the left is the '''toolbox''', where you can select your widgets. On the right, several dialogs can be selected. I'll keep only the '''Property Editor''' dialog (I close the 2 others). Your widgets can be fine tuned to behave how you want them to. You can choose the size of the widget, its background color (palette), and so on. Between those 2 windows is the '''Form''', your program window, within which you will design your user interface.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - After adding the ''sigcreatedlg.ui'' file, you will have to run ''Automake &amp;amp; friends'' and ''Run configure'' before building the program. This ensures that the updated ''Makefile.am'' is now read. &lt;br /&gt;
&lt;br /&gt;
===Designing the Program===&lt;br /&gt;
&lt;br /&gt;
Each time you want to use Qt Designer, you should have a precise visual idea of the design of your interface. You can see in [[:Image:KDevelop3-SigCreateDialog.png|this picture]] what the program will be like. It is a window with a number of different items (or widgets) on it, designed so that the user puts the right information in the right boxes. You should always design your program from the user's point of view, as it must be easy to use.&lt;br /&gt;
&lt;br /&gt;
This application creates an email signature, which is then displayed on the screen. The user should enter her/his name, email address, and then select one of three comments. When you click the '''Create!''' button, the generated signature is shown in a ''MultiLineEdit''. When you click '''Cancel''', the program quits.&lt;br /&gt;
&lt;br /&gt;
* '''Note''' - Note that this project is meant as a tutorial, so this is somewhat far away from practical use.&lt;br /&gt;
&lt;br /&gt;
Go back to the Qt Designer window with the new dialog open. You will see that the property editor has been filled with details about the form you have created. The first line in the '''Property Editor''' [[:Image:QtDesigner3-PropertyEditor.png|shows]] the name of the form which is Form1. Click on the field with this name to change it and type SigCreateDlg. This will form the class name of the dialog so you should name it something useful.&lt;br /&gt;
&lt;br /&gt;
To change properties, select the property you wish to change, then alter its setting on the right. Change the '''Caption''' property to &amp;quot;SigCreateDlg v.01&amp;quot;.   We will now begin to add widgets on our dialog.&lt;br /&gt;
&lt;br /&gt;
===Adding Widgets===&lt;br /&gt;
&lt;br /&gt;
To start, we will insert the text at the top of the program window, which can be seen [[:Image:KDevelop3-NewFile-Widget.png|here]]. This text tells the user how to operate the program. This type of widget is called a ''Label'' and you can put one on your program like this:&lt;br /&gt;
&lt;br /&gt;
# Select the dialog in ToolBox called '''Common Widgets-&amp;gt;TextLabel''', or from the menubar '''Tools-&amp;gt;Display-&amp;gt;TextLabel'''&lt;br /&gt;
# The cursor will become a crosshair over the form. Draw a box for the label, just as you would in a paint program, and you will see that the label is created with some dummy text in it.&lt;br /&gt;
# To change this text, double click on the label and type in the text, instead of ''TextLabel1''. The text you should type is ''This program will create an email signature for you. Just fill in the boxes and hit the Create! button.'' Select '''Align Center'' to have the text positioned nicely.  Refer to this [[:Image:QtDesigner3-TextEditDialog.png|screenshot]].&lt;br /&gt;
# Finally, resize the widget using the handles so it is the correct size and at the top of the box. Try to center the label by moving it with the mouse. This is just a temporary measure. Later on we will look at a more elegant layout management technique. You may refer to [[:Image:QtDesigner3-ResizingBox.png|this screenshot]].&lt;br /&gt;
&lt;br /&gt;
You follow pretty much the same procedure for embedding any type of widget that is supported by Qt Designer; select it, drag it, and finally, change its properties and size.&lt;br /&gt;
&lt;br /&gt;
An interesting concept in Qt Designer is that widgets can act as containers for other widgets. This will be demonstrated in our next task, which is to create the input fields inside the frame. You can see that in Picture 8 we have a bunch of labels and text boxes inside a frame. This frame is called a Group Box and acts as a container for the labels and text boxes inside it. Let's first create the frame by selecting the GroupBox in the '''Toolbox dialog-&amp;gt;Containers''' or '''Tools-&amp;gt;Containers-&amp;gt;GroupBox''' from the menubar. You can drag the mouse to create the box just below the Label you put before. In the ''Property Editor'' you can change the title property to alter the text in the frame. Put ''Details'' in the title text field. You may notice a + symbol in this entry in the ''Property Editor''. This indicates that the property has subproperties that can also be changed.&lt;br /&gt;
&lt;br /&gt;
Once you have created the frame (i.e the GroupBox), create three more labels as before but when you draw them, draw them inside the GroupBox frame. You can then see in the Object Explorer box ('''Windows menu -&amp;gt; Views -&amp;gt; Object Explorer''') to the right that the labels have become children of the GroupBox frame. See [[:Image:QtDesigner3-EditingTheDialog.png|this image]].&lt;br /&gt;
&lt;br /&gt;
Change the text of labels by double-clicking on it.&lt;br /&gt;
&lt;br /&gt;
Once you have done this you can then create the text boxes. They will allow the user to type in text like his(her) name and email address. We use the simplest type of text boxes: a widget called QLineEdit which allows the user to enter one line of text only. You have to create two QLineEdit widgets for the name and the email address. You choose the menu Tools then the entry Input then LineEdit and you draw it beside the 'Your Name' Label. Do the same below for the address.&lt;br /&gt;
&lt;br /&gt;
The witty comment will be selected by the user. We use a ComboBox which will present the user with three comments. Click on the ComboBox icon or select it via the Tools-&amp;gt; Input-&amp;gt; ComboBox menu. Draw it beside the Witty Comment label. Then double-click on it. You will be presented with a box into which you can add the contents of the combo box. Click on the 'New Item' button and type in your comment in the text box at the right. Then click again on 'New Item' for the second and third comments. Click on OK when you have finished.&lt;br /&gt;
&lt;br /&gt;
Adjust the size of the different widgets so they are nicely placed.&lt;br /&gt;
&lt;br /&gt;
Up to now, we have not named any of the widgets that are being placed in our program. It is useful to set an internal name for widgets so we can call them after in the program. Labels don't perform any action so they don't need to be named but other widgets do. It is the case now for our text boxes. We'll need to manipulate the data from the three input widgets (i.e. read the text) so we should give them a name. Names should be easily recognized later and they should make sense. The names are assigned via the name property on the top of the Property Editor. We name the top LineEdit nameBox and the second one mailBox. We name the ComboBox commBox. This will allow us to access the comments. So click on each LineEdit and then besides Name in the Property Editor write nameBox and mailBox. Then click on the ComboBox and name it commBox.&lt;br /&gt;
&lt;br /&gt;
We finish the graphical design by adding a label with 'Generated Signature' as text. Below it, we put a TextEdit ('''Tools-&amp;gt;Input-&amp;gt;TextEdit'''') where the generated signature will be displayed. We name it 'sigBox'. And then we add two PushButtons at the bottom ('Create!' and 'Cancel'). They don't need names but you can give them some if you want.&lt;br /&gt;
&lt;br /&gt;
Save your form. You can now have a quick preview by selecting the menu '''Preview-&amp;gt; Preview Form'''.  [[:Image:QtDesigner3-BeforeLayoutManagement.png|This]] is the form ''before'' layout management.&lt;br /&gt;
&lt;br /&gt;
===Getting Spaced Out===&lt;br /&gt;
This section describes the layout management. If you resize the preview window you will then notice that the widgets do not adjust appropriately. They are not resized. To improve things, we need to use a feature in Qt called spacers. Spacers are like virtual springs that push the widgets on each side apart.&lt;br /&gt;
* '''Note''' - Having a good layout is essential for your application, as when the strings are translated, they might be longer than the English ones and they need to fit on your widgets. The geometry of the widgets has to be nice if the user can resize your window application. Layouts are done by trial and error so use '''Preview-&amp;gt;Preview Form''' to see the result of your layout management and to achieve the best layout.&lt;br /&gt;
&lt;br /&gt;
The use of spacers and layout management is a skill that is developed through trial and error. The main thing to remember when dealing with spacers is that you work horizontally first and then vertically.&lt;br /&gt;
&lt;br /&gt;
We will first use spacers to center the text in the top box. Resize your label so that it only get the size of the text. Then we add two spacers, one at each side. Choose the 'spring' icon or menu '''Layout-&amp;gt; Add Spacer'''. You adjust each of the spacers horizontally. Click the space to the left of the text and the blue spacer will appear . Repeat the same procedure for the right. Then add a spacer on the right of the 'Generated Signature' label, and a last one on the left of the the 'Create!' pushbutton. Please use [[:Image:QtDesigner3-AddingTheSpacers.png|this image]] as a reference.&lt;br /&gt;
&lt;br /&gt;
Now that we have spacers to fill blank space, we need a proper layout management. This will allow the widgets to be nicely resized whenever the main window is resized. It is really compulsory to have good layout management. Again, try to resize several times to see if everything is in place. We can use Vertical or horizontal layout or grid management. The top row of widget is horizontal (spacer + label + spacer) so we need Horizontal management. We need to select the three widgets alltogether: click on the first spring, then click on the label while holding down ''Shift'', then on the second spring while holding down ''Shift''. Then click on the Horizontal Layout icon or menu '''Layout-&amp;gt; Lay Out Horizontally'''. You will then see a resizable red line around the three objects to indicate that their layout is being managed. Resize the red box if it needs to.&lt;br /&gt;
&lt;br /&gt;
We can now repeat this procedure for the three labels inside the GroupBox, this time using vertical layout management. The same vertical management for the two LineEdit and the ComboBox. It is better to use vertical management to keep the object aligned. If we use horizontal management for each label + text box then they will not stay aligned and equally sized. Horizontal management is needed for the label with the spacer and another one for the two pushbuttons and the spacer.&lt;br /&gt;
&lt;br /&gt;
To finish the layout, we need to let the form look after the laid-out boxes. We put everything in a grid. This is done by right clicking the form and selecting &amp;quot;Lay Out in a Grid&amp;quot; from the menu. The final design with layout lines should resemble something similar to [[:Image:QtDesigner3-CompleteLayoutManagement.png|this image]].&lt;br /&gt;
&lt;br /&gt;
===Signals and Slots===&lt;br /&gt;
&lt;br /&gt;
[http://doc.trolltech.com/3.0/signalsandslots.html Signals and Slots] are used for communication between Qt objects. The signal/slot mechanism is a central feature of Qt and probably the part that differs most from other toolkits which often use callbacks. In Qt, a signal is emitted by a widget when a particular event occurs, very often triggered by the user like for example pressing a button or writing something in a LineEdit. A slot is simply a function that is called in reponse to a particular signal.&lt;br /&gt;
&lt;br /&gt;
Now the widgets are implemented and the layout is arranged the final thing we need to do in the design stage of the form is to create the signal/slot connections. To do this manually requires a ''connect()'' function but Qt Designer provides a simple yet effective solution. To create the signal/slot connections we need to use the connecting tool. To do this either select the icon (it looks like a red arrow going into a green square) or select '''Tools-&amp;gt; Connect Signals/Slots''' from the menu (or use the F3 shortcut key). To create a connection, click on the form on the widget that is going to be dealing with the slot, drag the line off the form and release the mouse button.&lt;br /&gt;
&lt;br /&gt;
Let's deal first with the Create! button. Click first on the '''Connect Signal/Slot''' icon or select it from the Tools menu or use the F3 key. Then click on the Create! button with the crosshair and drag the line off the form completely. When you have released the mouse button you will see the connections tool shown [[:Image:QtDesigner3-CreateSlot.png|here]].&lt;br /&gt;
&lt;br /&gt;
What we want to do is to create a slot that will create our signature when the user clicks on the Create! button. The signal will be clicked() (you may choose among five signals for a QPushButton) and we need to create the slot then make the connection.&lt;br /&gt;
&lt;br /&gt;
To create the slot we need to click on the '''Edit Slots''' button. The slot creation box then appears. See [[:Image:QtDesigner3-CreateSlot.png|this example]]. Now click on the '''New Function''' button and a slot will appear in the box. Instead of ''new_slot()'' rename it to ''slotCreateSig()'' and leave the access specifier as public. When you click on ''OK'' you will be returned to the connections box and you will see your new slot in the Slots section of the box.&lt;br /&gt;
&lt;br /&gt;
To [[:Image:QtDesigner3-ViewandEditConnections.png|make a connection]] you simply select the appropriate signal (which is ''clicked()'' in our case) and then select the slot (which is our new slot ''slotCreateSig()''). When you have selected both signal and slot you will see the connection made at the bottom of the screen. After you are finished click OK.&lt;br /&gt;
&lt;br /&gt;
Repeat the procedure for the Cancel button by using the clicked() signal and the close() slot. You are now done with the signals and slots.&lt;br /&gt;
* '''Warning''' - Don't forget to save your form!&lt;br /&gt;
&lt;br /&gt;
===Generating the Source===&lt;br /&gt;
&lt;br /&gt;
In this tutorial, we use KDevelop subclassing tool in Automake Manager. If you have KDevelop version which has not that capability, then please go to Chapter 7 where I explain this step without the subclass tool.&lt;br /&gt;
&lt;br /&gt;
Here we start with the KDE simple project named SigCreate and the sigcreatedlg.ui that we have added in our project. In the Automake Manager, in the section sigcreate (Program in bin) you must have three files: sigcreatedlg.ui, sigcreate.cpp and main.cpp. The project must compile and give the main window as in picture 3 (creating.html).&lt;br /&gt;
&lt;br /&gt;
As the sigcreate class is no use for us, we will remove it and use it for subclassing the sigcreatedlg.ui file. In the Automake Manager, right click on sigcreate.cpp and select Remove and a dialog pops up. Please check 'Also Remove it from disk'. Then do the same with sigcreate.h. This is the way to remove obsolete files from your project and the Makefile.am will be updated. Remember to run automake &amp;amp; friends and configure before compiling your project again. We will not do it right now because we will make other changes. We will now use the class name SigCreate for the subclass.&lt;br /&gt;
&lt;br /&gt;
In the Automake Manager, in sigcreate (program in bin), right click on sigcreatedlg.ui and choose Subclass Widget... from the context menu that appears. Then fill in the subclass name which is SigCreate. Check the box: Reformat source and click on OK. Say No then about adding these files in cvs as we did not enable this in our project.&lt;br /&gt;
Note&lt;br /&gt;
You can see that the slot we created in designer is listed here and checked, the method will be implemented in the generated files. If you uncheck it, the code will not be generated in your class.&lt;br /&gt;
&lt;br /&gt;
(The subclass dialog Image)&lt;br /&gt;
&lt;br /&gt;
We have to suppress some lines in main.cpp as the KDE simple project template refers to a KMainWindow which is usually the base class used. But here, SigCreate is based on QWidget. You have to remove all the lines between KApplication app; and return app.exec(); except the ones I keep here:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;SigCreate *mainWin = 0;&lt;br /&gt;
&lt;br /&gt;
mainWin = new SigCreate();&lt;br /&gt;
app.setMainWidget( mainWin );&lt;br /&gt;
mainWin-&amp;gt;show();&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Implementing the Slot===&lt;br /&gt;
&lt;br /&gt;
==In Short==&lt;br /&gt;
==Make the translations for a simple kde project==&lt;br /&gt;
==A few general tips==&lt;br /&gt;
==Generating the source (alternate)==&lt;br /&gt;
==Credits and License==&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Localization/i18n_Mistakes</id>
		<title>Development/Tutorials/Localization/i18n Mistakes</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Localization/i18n_Mistakes"/>
				<updated>2007-01-10T02:42:10Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: /* Pitfall #1: Pixel Based Layouts */  Proofreading - &amp;quot;compared&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Localization|&lt;br /&gt;
&lt;br /&gt;
name=Avoiding Common Localization Pitfalls|&lt;br /&gt;
&lt;br /&gt;
pre=[[Development/Tutorials/i18n|Writing Applications With Localization in Mind]]|&lt;br /&gt;
&lt;br /&gt;
next=[[Development/Tutorials/i18n_Build_Systems|Incorporating i18n Into the Build System]]|&lt;br /&gt;
&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
== Abstract ==&lt;br /&gt;
&lt;br /&gt;
There are a few common pitfalls that prevent applications from being properly translated or otherwise localized. These include using pixel based layouts, &amp;quot;word puzzles&amp;quot; and writing code that does not deal with Unicode characters properly. This tutorial covers each of these issues, explaining what to avoid and how to do it properly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Pitfall #1: Pixel Based Layouts ==&lt;br /&gt;
&lt;br /&gt;
English text is often very compact compared to other languages where the translated text is often substantially longer. Therefore the interface much be able to adjust size to accommodate the length of translations provided at runtime. If it can't do this, then messages will end up misaligned and truncated.&lt;br /&gt;
&lt;br /&gt;
The answer is to use layout managers. Qt provides a number of such layout managers pre-made for you. They include &amp;lt;tt&amp;gt;QHBoxLayout&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;QVBoxLayout&amp;lt;/tt&amp;gt;, &amp;lt;tt&amp;gt;QGridLayout&amp;lt;/tt&amp;gt; and &amp;lt;tt&amp;gt;QStackedLayout&amp;lt;/tt&amp;gt;, all of which are subclasses of &amp;lt;tt&amp;gt;QLayout&amp;lt;/tt&amp;gt;. You may also create your own &amp;lt;tt&amp;gt;QLayout&amp;lt;/tt&amp;gt; based classes, but this is generally not needed. &lt;br /&gt;
&lt;br /&gt;
These layout classes manage the pixel positioning of widgets for you at runtime, so no matter what the size of the translated strings your interface will adjust properly. For more information look at the documentation for [[http://doc.trolltech.com/qlayout.html QLayout]].&lt;br /&gt;
&lt;br /&gt;
== Pitfall #2: Word Puzzles ==&lt;br /&gt;
&lt;br /&gt;
Another thing to be aware of is to not concatenate pieces of sentences together like this: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;QString msg=i18n(&amp;quot;Do you want to replace &amp;quot;)+oldFile+i18n(&amp;quot; with &amp;quot;)+newFile+&amp;quot;?&amp;quot;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Such &amp;quot;word puzzles&amp;quot; are very hard or even impossible to translate. This is because the structure of the sentence will often be completely different in another language and thus must be controlled by the translator. When the order of words and phrases is hard-coded as in the above example, the translator can not create a proper translation.&lt;br /&gt;
&lt;br /&gt;
Adding to this problem, a translator will only see parts of the sentence while translating and will have to guess at what belongs together. &lt;br /&gt;
&lt;br /&gt;
The solution thankfully is quite simple: use QString::arg() which lets the translator not only make good translations because they can see the entirety of the sentence during translation but which also lets them change the order of the arguments freely. Because of this latter advantage, QString::arg() is also recommended to use instead of sprintf and similar functions. &lt;br /&gt;
&lt;br /&gt;
The above example written properly would then look like this: &lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;QString msg=i18n(&amp;quot;Do you want to replace %1 with %2?&amp;quot;).arg(oldFile, newFile)&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{note|Avoid inserting anything other than numbers or nouns with this method, since in some languages the translation depends on the inserted words. It is therefore best to create strings that are as complete sentences as possible.}}&lt;br /&gt;
&lt;br /&gt;
Similarly, messages that contain a version string or other often changing parts should use QString::arg() to insert them into the message. This prevents unnecessary changes that cause the translators to have to change the translated messages as well. &lt;br /&gt;
&lt;br /&gt;
Since KDE is translated into more than 65 languages a single string change causes at least 65 people to open the file, find the changed message, look carefully if this is the only thing that has changed, change the translation, save the file again and commit the changed file into the code repository. All in all such a small change might create hours of work which could be easily avoided.&lt;br /&gt;
&lt;br /&gt;
== Pitfall #3: Lack of Unicode Support ==&lt;br /&gt;
&lt;br /&gt;
Whenever there is source code that handles strings which does not use a datatype (such as &amp;lt;tt&amp;gt;char&amp;lt;/tt&amp;gt;) or class (such as &amp;lt;tt&amp;gt;std::string&amp;lt;/tt&amp;gt;) that can not handle Unicode, translations will break.&lt;br /&gt;
&lt;br /&gt;
To avoid this, never call QString::latin1() or QString::ascii() on translated strings. This also applies to information resulting from user input such as passwords, URLs and filenames. If you really need a plain &amp;lt;tt&amp;gt;char*&amp;lt;/tt&amp;gt; representation of a string, it is better to use QString::utf8(). &lt;br /&gt;
&lt;br /&gt;
{{note|For more information on character sets and Unicode, see the [[Development/Tutorials/Unicode|Unicode tutorial]].}}&lt;br /&gt;
&lt;br /&gt;
KIO slaves may also provide paths and file names encoded using UTF-8. It is up to the programmer, however, to take care of passing properly encoded filenames to any KIO method in question. The correct way to do this is not to guess at user's filesystem encoding but to use QFile::encodeName() and QFile::decodeName() instead.&lt;br /&gt;
&lt;br /&gt;
{{tip|You can turn KIO's UTF-8 file name support on for testing by exporting the KDE_UTF8_FILENAMES environment variable in your shell's startup file (e.g. ~/.bashrc).}}&lt;br /&gt;
&lt;br /&gt;
== Success! ==&lt;br /&gt;
&lt;br /&gt;
If you avoid the three common categories of pitfalls detailed in this tutorial, your application should be fully localizable by the various KDE translation teams around the world and open up your application to the majority of people on the planet.&lt;br /&gt;
&lt;br /&gt;
[[Category:Programming]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE4/KParts</id>
		<title>Development/Architecture/KDE4/KParts</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE4/KParts"/>
				<updated>2007-01-10T02:38:58Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Category KDE4&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''KParts''' is the name of the component framework for KDE. An individual component is called a '''KPart'''. As an example, Konsole is available as a KPart and is used in applications like Konqueror and Kate. Good examples about how KParts can be used are Konqueror, which (among other things) uses the KWord part to display documents, KMPlayer part to play multimedia, and Kontact, which embeds kdepim applications under one roof.&lt;br /&gt;
&lt;br /&gt;
===Further reading===&lt;br /&gt;
* [http://api.kde.org/cvs-api/kdelibs-apidocs/kparts/html/index.html KParts API Reference]&lt;br /&gt;
* [http://api.kde.org/cvs-api/kdelibs-apidocs/kparts/html/classKParts_1_1Part.html KParts Class Reference]&lt;br /&gt;
* [http://www-106.ibm.com/developerworks/library/l-kparts/ Coding with KParts] (from IBM)&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE4]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE4</id>
		<title>Development/Architecture/KDE4</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE4"/>
				<updated>2007-01-10T02:38:28Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Category KDE4&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[/KParts|KParts]]&lt;br /&gt;
[[Category:KDE4]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Architecture/KDE3/XMLGUI_Technology</id>
		<title>Development/Architecture/KDE3/XMLGUI Technology</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Architecture/KDE3/XMLGUI_Technology"/>
				<updated>2007-01-10T02:37:34Z</updated>
		
		<summary type="html">&lt;p&gt;CuCullin: Category KDE3&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;'''Defining the menu and toolbar structure in XML'''&lt;br /&gt;
&lt;br /&gt;
== Introduction ==&lt;br /&gt;
&lt;br /&gt;
While the [[../Action_Pattern|action pattern]] allows to encapsulate&lt;br /&gt;
actions triggered by the user in an object which can be &amp;quot;plugged&amp;quot; somewhere in&lt;br /&gt;
the menu bars or toolbars, it does not by itself solve the problem of &lt;br /&gt;
constructing the menus themselves. In particular, you have build all popup menus&lt;br /&gt;
in C++ code and explicitly insert the actions in a certain order, under &lt;br /&gt;
consideration of the style guide for standard actions. This makes it pretty&lt;br /&gt;
difficult to allow the user to customize the menus or change shortcuts to&lt;br /&gt;
fit his needs, without changing the source code.&lt;br /&gt;
&lt;br /&gt;
This problem is solved by a set of classes called ''XMLGUI''. Basically,&lt;br /&gt;
this separates actions (coded in C++) from their appearance in menu bars&lt;br /&gt;
and tool bars (coded in XML). Without modifying any source code, menus&lt;br /&gt;
can be simply customized by adjusting an XML file. Furthermore, it helps&lt;br /&gt;
to make sure that standard actions (such as &amp;lt;tt&amp;gt;File-&amp;amp;gt;Open&amp;lt;/tt&amp;gt; or &lt;br /&gt;
&amp;lt;tt&amp;gt;Help-&amp;amp;gt;About&amp;lt;/tt&amp;gt;) appear in the locations suggested by the style guide.&lt;br /&gt;
XMLGUI is especially important for modular programs, where the items &lt;br /&gt;
appearing in the menu bar may come from many different plugins or parts.&lt;br /&gt;
&lt;br /&gt;
KDE's class for toplevel windows,&lt;br /&gt;
[http://api.kde.org/3.5-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KMainWindow],&lt;br /&gt;
inherits &lt;br /&gt;
[http://api.kde.org/3.5-api/kdelibs-apidocs/kdeui/html/classKMainWindow.html KXMLGUIClient]&lt;br /&gt;
and therefore supports XMLGUI out of the box. All actions created within it must&lt;br /&gt;
have the client's actionCollection() as parent. A call to createGUI() will then &lt;br /&gt;
build the whole set of menu and tool bars defined the applications XML file &lt;br /&gt;
(conventionally with the suffix ui.rc). &lt;br /&gt;
&lt;br /&gt;
== An example: Menu in KView ==&lt;br /&gt;
&lt;br /&gt;
In the following, we take KDE's image view KView as example. It has a ui.rc &lt;br /&gt;
file kviewui.rc, which is installed with the Makefile.am snippet&lt;br /&gt;
&lt;br /&gt;
 rcdir = $(kde_datadir)/kview&lt;br /&gt;
 rc_DATA = kviewui.rc&lt;br /&gt;
&lt;br /&gt;
Here is an excerpt from the kviewui.rc file. For simplicity, we show &lt;br /&gt;
only the definition of the View menu.&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE kpartgui&amp;gt;&lt;br /&gt;
&amp;lt;kpartgui name=&amp;quot;kview&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;MenuBar&amp;gt;&lt;br /&gt;
    &amp;lt;Menu name=&amp;quot;view&amp;quot; &amp;gt;&lt;br /&gt;
      &amp;lt;Action name=&amp;quot;zoom50&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;Action name=&amp;quot;zoom100&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;Action name=&amp;quot;zoom200&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;Action name=&amp;quot;zoomMaxpect&amp;quot; /&amp;gt;&lt;br /&gt;
      &amp;lt;Separator/&amp;gt;&lt;br /&gt;
      &amp;lt;Action name=&amp;quot;fullscreen&amp;quot; /&amp;gt;&lt;br /&gt;
    &amp;lt;/Menu&amp;gt;&lt;br /&gt;
  &amp;lt;/MenuBar&amp;gt;&lt;br /&gt;
&amp;lt;/kpartgui&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The corresponding part of the setup in C++ is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt3&amp;gt;&lt;br /&gt;
KStdAction::zoomIn (this, SLOT(slotZoomIn()), actionCollection());&lt;br /&gt;
KStdAction::zoomOut(this, SLOT(slotZoomOut()), actionCollection());&lt;br /&gt;
KStdAction::zoom   (this, SLOT(slotZoom()), actionCollection());&lt;br /&gt;
new KAction        (i18n(&amp;quot;&amp;amp;Half size&amp;quot;), ALT+Key_0,&lt;br /&gt;
                    this, SLOT(slotHalfSize()),&lt;br /&gt;
                    actionCollection(), &amp;quot;zoom50&amp;quot;);&lt;br /&gt;
new KAction        (i18n(&amp;quot;&amp;amp;Normal size&amp;quot;), ALT+Key_1,&lt;br /&gt;
                    this, SLOT(slotDoubleSize()),&lt;br /&gt;
                    actionCollection(), &amp;quot;zoom100&amp;quot;);&lt;br /&gt;
new KAction        (i18n(&amp;quot;&amp;amp;Double size&amp;quot;), ALT+Key_2,&lt;br /&gt;
                    this, SLOT(slotDoubleSize()),&lt;br /&gt;
                    actionCollection(), &amp;quot;zoom200&amp;quot;);&lt;br /&gt;
new KAction        (i18n(&amp;quot;&amp;amp;Fill Screen&amp;quot;), ALT+Key_3,&lt;br /&gt;
                    this, SLOT(slotFillScreen()),&lt;br /&gt;
                    actionCollection(), &amp;quot;zoomMaxpect&amp;quot;);&lt;br /&gt;
new KAction        (i18n(&amp;quot;Fullscreen &amp;amp;Mode&amp;quot;), CTRL+SHIFT+Key_F,&lt;br /&gt;
                    this, SLOT(slotFullScreen()),&lt;br /&gt;
                    actionCollection(), &amp;quot;fullscreen&amp;quot;);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The View menu resulting from this GUI definition looks like in this&lt;br /&gt;
screenshot:&lt;br /&gt;
&lt;br /&gt;
[[Image:k3view-menu.png|frame|center|KView menu screenshot]]&lt;br /&gt;
&lt;br /&gt;
The XML file begins with a document type declaration. The DTD for kpartgui can&lt;br /&gt;
be found in the kdelibs sources in {{path|kdeui/kpartgui.dtd}}. The outermost&lt;br /&gt;
element of the file contains the instance name of the application as attribute.&lt;br /&gt;
It can also contain a version number in the form &amp;quot;version=2&amp;quot;. This is useful&lt;br /&gt;
when you release new versions of an application with a changed menu structure,&lt;br /&gt;
e.g. with more features. If you bump up the version number of the {{path|ui.rc}} file, &lt;br /&gt;
KDE makes sure that any customized version of the file is discarded and the new &lt;br /&gt;
file is used instead.&lt;br /&gt;
&lt;br /&gt;
The next line, &amp;amp;lt;MenuBar&amp;amp;gt; contains a declaration of a menu bar. You can&lt;br /&gt;
also insert any number of &amp;amp;lt;ToolBar&amp;amp;gt; declarations in order to create some&lt;br /&gt;
tool bars. The menu contains a submenu with the name &amp;quot;view&amp;quot;. This name is&lt;br /&gt;
already predefined, and thus you see a translated version of the word &amp;quot;View&amp;quot;&lt;br /&gt;
in the screenshot. If you declare your own submenus, you have to add the title&lt;br /&gt;
explicitly. For example, KView has a submenu with the title &amp;quot;Image&amp;quot; which is&lt;br /&gt;
declared as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;Menu name=&amp;quot;image&amp;quot;&amp;gt;&lt;br /&gt;
   &amp;lt;text&amp;gt;&amp;amp;amp;Image&amp;lt;/text&amp;gt;&lt;br /&gt;
   ...&lt;br /&gt;
&amp;lt;/Menu&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In KDE's automake framework, such titles are automatically extracted and put &lt;br /&gt;
into the application's [kde-i18n-howto.html &amp;lt;tt&amp;gt;.po&amp;lt;/tt&amp;gt;] file, so &lt;br /&gt;
it is considered by translators. Note that you have to write the accelerator &lt;br /&gt;
marker &amp;quot;&amp;amp;&amp;quot; in the form XML compliant form &amp;quot;&amp;amp;&amp;amp;&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Let us come back to the example. KView's View menu contains a couple of custom&lt;br /&gt;
actions: zoom50, zoom100, zoom200, zoomMaxpect and fullscreen, declared with a&lt;br /&gt;
&amp;amp;lt;Action&amp;amp;gt; element. The separator in the screenshots corresponds with the&lt;br /&gt;
&amp;amp;lt;Separator&amp;amp;gt; element. &lt;br /&gt;
&lt;br /&gt;
You will note that some menu items do not not have a corresponding element in&lt;br /&gt;
the XML file. These are ''standard actions''. Standard actions are created by &lt;br /&gt;
the class &lt;br /&gt;
[http://api.kde.org/3.5-api/kdelibs-apidocs/kdeui/html/kstdaction_8h-source.html KStdAction].&lt;br /&gt;
When you create such actions in your application (such as in the C++ example&lt;br /&gt;
above), they will automatically be inserted in a prescribed position, and&lt;br /&gt;
possibly with an icon and a shortcut key. You can look up these locations in&lt;br /&gt;
the file &amp;lt;tt&amp;gt;kdeui/ui_standards.rc&amp;lt;/tt&amp;gt; in the kdelibs sources.&lt;br /&gt;
&lt;br /&gt;
== An example: Toolbars in Konqueror ==&lt;br /&gt;
&lt;br /&gt;
For the discussion of toolbars, we switch to Konqueror's GUI&lt;br /&gt;
definition. This excerpt defines the location bar, which contains the input&lt;br /&gt;
field for URLs.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;ToolBar name=&amp;quot;locationToolBar&amp;quot; fullWidth=&amp;quot;true&amp;quot; newline=&amp;quot;true&amp;quot; &amp;gt;&lt;br /&gt;
  &amp;lt;text&amp;gt;Location Toolbar&amp;lt;/text&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;clear_location&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;location_label&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;toolbar_url_combo&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;go_url&amp;quot; /&amp;gt;&lt;br /&gt;
&amp;lt;/ToolBar&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The first thing we notice is that there are a lot more attributes than for&lt;br /&gt;
menu bars. These include:&lt;br /&gt;
&lt;br /&gt;
*'''&amp;lt;tt&amp;gt;fullWidth&amp;lt;/tt&amp;gt;''': Tells XMLGUI that the toolbar has the same width as the toplevel window. Af this is &amp;quot;false&amp;quot;, the toolbar only takes as much space as necessary, and further toolbars are put in the same row.&lt;br /&gt;
*'''&amp;lt;tt&amp;gt;newline&amp;lt;/tt&amp;gt;''': This is related to the option above. If newline is &amp;quot;true&amp;quot;, the toolbar starts a new row. Otherwise it may be put in the row together with the previous toolbar.&lt;br /&gt;
*'''&amp;lt;tt&amp;gt;noEdit&amp;lt;/tt&amp;gt;''': Normally toolbars can be customized by the user, e.g. in &amp;lt;tt&amp;gt;Settings-&amp;amp;gt;Configure Toolbars&amp;lt;/tt&amp;gt; in Konqueror. Setting this option to &amp;quot;true&amp;quot; marks this toolbar as not editable. This is important for toolbars which are filled with items at runtime, e.g. Konqueror's bookmark toolbar.&lt;br /&gt;
*'''&amp;lt;tt&amp;gt;iconText&amp;lt;/tt&amp;gt;''': Tells XMLGUI to show the text of the action next to the icon. Normally, the text is only shown as a tooltip when the mouse cursor remains over the icon for a while. Possible values for this attribute are &amp;quot;icononly&amp;quot; (shows only the icon), &amp;quot;textonly&amp;quot; (shows only the text), &amp;quot;icontextright&amp;quot; (shows the text on the right side of the icon) and &amp;quot;icontextbottom&amp;quot; (shows the text beneath the icon).&lt;br /&gt;
*'''&amp;lt;tt&amp;gt;hidden&amp;lt;/tt&amp;gt;''': If this is &amp;quot;true&amp;quot;, the toolbar is not visible initially and must be activated by some menu item.&lt;br /&gt;
*'''&amp;lt;tt&amp;gt;position&amp;lt;/tt&amp;gt;''': The default for this attribute is &amp;quot;top&amp;quot;, meaning that the toolbar is positioned under the menu bar. For programs with many tools, such as graphics programs, it may be interesting to replace this with &amp;quot;left&amp;quot;, &amp;quot;right&amp;quot; or &amp;quot;bottom&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
== Dynamical menus ==&lt;br /&gt;
&lt;br /&gt;
Obviously, an XML can only contain a static description of a user interface.&lt;br /&gt;
Often, there are menus which change at runtime. For example, Konqueror's&lt;br /&gt;
&amp;lt;tt&amp;gt;Location&amp;lt;/tt&amp;gt; menu contains a set of items &amp;lt;tt&amp;gt;Open with Foo&amp;lt;/tt&amp;gt; with&lt;br /&gt;
the applications able to load a file with a given MIME type. Each time the&lt;br /&gt;
document shown changes, the list of menu items is updated. XMLGUI is prepared&lt;br /&gt;
to handle such cases with the notion of ''action lists''. An action list &lt;br /&gt;
is declared as one item in the XML file, but consists of several actions which&lt;br /&gt;
are plugged into the menu at runtime. The above example is implemented with&lt;br /&gt;
the following declaration in Konqueror's XML file:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;Menu name=&amp;quot;file&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;text&amp;gt;&amp;amp;amp;Location&amp;lt;/text&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
  &amp;lt;ActionList name=&amp;quot;openwith&amp;quot;&amp;gt;&lt;br /&gt;
  ...&lt;br /&gt;
&amp;lt;/Menu&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The function KXMLGUIClient::plugActionList() is then used to add actions to be&lt;br /&gt;
displayed, whereas the function KXMLGuiClient::unplugActionList() removes all&lt;br /&gt;
plugged actions. The routine responsible for updating looks as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt3&amp;gt;&lt;br /&gt;
void MainWindow::updateOpenWithActions()&lt;br /&gt;
{&lt;br /&gt;
    unplugActionList(&amp;quot;openwith&amp;quot;);&lt;br /&gt;
    openWithActions.clear();&lt;br /&gt;
    for ( /* iterate over the relevant services */ ) {&lt;br /&gt;
        KAction *action = new KAction( ...);&lt;br /&gt;
        openWithActions.append(action);&lt;br /&gt;
    }&lt;br /&gt;
    plugActionList(&amp;quot;openwith&amp;quot;, openWithActions);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note that in contrast to the static actions, the ones created here are &lt;br /&gt;
''not'' constructed with the action collection as parent, and you are &lt;br /&gt;
responsible for deleting them for yourself. The simplest way to achieve this&lt;br /&gt;
is by using &amp;lt;tt&amp;gt;openWithActions.setAutoDelete(true)&amp;lt;/tt&amp;gt; in the above&lt;br /&gt;
example.&lt;br /&gt;
&lt;br /&gt;
Also note that to be able to extend menus this way, you need to call&lt;br /&gt;
&amp;lt;tt&amp;gt;createGUI()&amp;lt;/tt&amp;gt; with the second parameter (conserveMemory) set to &amp;quot;false&amp;quot;.&lt;br /&gt;
If you don't, you won't get any error but your actions won't appear in the&lt;br /&gt;
menu.&lt;br /&gt;
&lt;br /&gt;
== Context menus ==&lt;br /&gt;
&lt;br /&gt;
The examples above only contained cases where a main window's menubar and &lt;br /&gt;
toolbars were created. In the cases, the processes of constructing these&lt;br /&gt;
containers is completely hidden from you behind the createGUI() call&lt;br /&gt;
(except if you have custom containers). However, there are cases, where&lt;br /&gt;
you want to construct other containers and populate them with GUI definitions&lt;br /&gt;
from the XML file. One such example are context menus. In order to get a&lt;br /&gt;
pointer to a context menu, you have to ask the client's factory for it:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code cppqt3&amp;gt;&lt;br /&gt;
void MainWindow::popupRequested()&lt;br /&gt;
{&lt;br /&gt;
    QWidget *w = factory()-&amp;gt;container(&amp;quot;context_popup&amp;quot;, this);&lt;br /&gt;
    QPopupMenu *popup = static_cast&amp;lt;QPopupMenu *&amp;gt;;(w);&lt;br /&gt;
    popup-&amp;gt;exec(QCursor::pos());&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The method KXMLGUIFactory::container() used above looks whether it finds a&lt;br /&gt;
container in the XML file with the given name. Thus, a possible definition&lt;br /&gt;
could look as follows:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;Menu name=&amp;quot;context_popup&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;file_add&amp;quot;/&amp;gt;&lt;br /&gt;
  &amp;lt;Action name=&amp;quot;file_remove&amp;quot;/&amp;gt;&lt;br /&gt;
&amp;lt;/Menu&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
''Initial Author:'' [mailto:bernd@kdevelop.org Bernd Gehrmann]&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE3]]&lt;/div&gt;</summary>
		<author><name>CuCullin</name></author>	</entry>

	</feed>