<?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=Chris&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=Chris&amp;feedformat=atom"/>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Special:Contributions/Chris"/>
		<updated>2013-06-19T11:12:29Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.20.2</generator>

	<entry>
		<id>http://techbase.kde.org/User:Chris</id>
		<title>User:Chris</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User:Chris"/>
				<updated>2009-04-25T08:35:41Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: bug 154142 fixed&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User:Chris</id>
		<title>User:Chris</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User:Chris"/>
				<updated>2009-01-12T03:48:26Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;What happens, when you insert [http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=200ca Character U+200ca] using Konqueror 4.1.3: #56522;. Wow! I swear I pasted the character from the Unicode page.&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User:Chris</id>
		<title>User:Chris</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User:Chris"/>
				<updated>2009-01-12T03:36:13Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;What happens, when you insert [http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=200ca Character U+200ca] using Konqueror 4.3: #56522;. Wow! I swear I pasted the character from the Unicode page.&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User:Chris</id>
		<title>User:Chris</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User:Chris"/>
				<updated>2009-01-12T03:32:16Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;What happens, when you insert [http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=20000 Character U+20000] using Konqueror 4.3: Let's check the wiki code.&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/User:Chris</id>
		<title>User:Chris</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/User:Chris"/>
				<updated>2009-01-12T03:31:32Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: New page: What happens, when you insert [http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=20000 Character U+20000] using Konqueror 4.3:  Let's check the wiki code.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;What happens, when you insert [http://www.unicode.org/cgi-bin/GetUnihanData.pl?codepoint=20000 Character U+20000] using Konqueror 4.3:  Let's check the wiki code.&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Using_KActions</id>
		<title>Development/Tutorials/Using KActions</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Using_KActions"/>
				<updated>2008-12-21T15:37:00Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: /* XMLGUI */ link to better though old info&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/Using_KActions}}&lt;br /&gt;
&lt;br /&gt;
{{TutorialBrowser|&lt;br /&gt;
&lt;br /&gt;
series=Beginner Tutorial|&lt;br /&gt;
&lt;br /&gt;
name=How To Use KActions and XMLGUI|&lt;br /&gt;
&lt;br /&gt;
pre=[[Development/Tutorials/Using_KXmlGuiWindow|Tutorial 2 - KXmlGuiWindow]], Basic XML knowledge|&lt;br /&gt;
&lt;br /&gt;
next=[[Development/Tutorials/Saving_and_loading|Tutorial 4 - Saving and loading]]| &lt;br /&gt;
&lt;br /&gt;
reading=None&lt;br /&gt;
}}&lt;br /&gt;
&lt;br /&gt;
==Abstract==&lt;br /&gt;
This tutorial introduces the concept of actions. Actions are a unified way of supplying the user with ways to interact with your program.&lt;br /&gt;
&lt;br /&gt;
For example, if we wanted to let the user of [[Development/Tutorials/Using_KXmlGuiWindow|Tutorial 2 ]] clear the text box by clicking a button in the toolbar, from an option in the File menu or through a keyboard shortcut, it could all be done with one {{class|KAction}}.&lt;br /&gt;
&lt;br /&gt;
[[image:introtokdetutorial3.png|frame|center]]&lt;br /&gt;
&lt;br /&gt;
==KAction==&lt;br /&gt;
A {{class|KAction}} is an object which contains all the information about the icon and shortcuts that is associated with a certain action. The action is then connected to a [http://doc.trolltech.com/latest/signalsandslots.html slot] which carries out the work of your action.&lt;br /&gt;
&lt;br /&gt;
== The Code ==&lt;br /&gt;
&lt;br /&gt;
===main.cpp===&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
#include &amp;lt;KApplication&amp;gt;&lt;br /&gt;
#include &amp;lt;KAboutData&amp;gt;&lt;br /&gt;
#include &amp;lt;KCmdLineArgs&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;mainwindow.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
int main (int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
  KAboutData aboutData( &amp;quot;tutorial3&amp;quot;, &amp;quot;tutorial3&amp;quot;,&lt;br /&gt;
      ki18n(&amp;quot;Tutorial 3&amp;quot;), &amp;quot;1.0&amp;quot;,&lt;br /&gt;
      ki18n(&amp;quot;A simple text area using KAction etc.&amp;quot;),&lt;br /&gt;
      KAboutData::License_GPL,&lt;br /&gt;
      ki18n(&amp;quot;Copyright (c) 2007 Developer&amp;quot;) );&lt;br /&gt;
  KCmdLineArgs::init( argc, argv, &amp;amp;aboutData );&lt;br /&gt;
  KApplication app;&lt;br /&gt;
 &lt;br /&gt;
  MainWindow* window = new MainWindow();&lt;br /&gt;
  window-&amp;gt;show();&lt;br /&gt;
  return app.exec();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This time, very little has changed in &amp;lt;tt&amp;gt;main.cpp&amp;lt;/tt&amp;gt;, only the KAboutData constructor has been updated to show that we are now on tutorial 3.&lt;br /&gt;
&lt;br /&gt;
===mainwindow.h===&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
#ifndef MAINWINDOW_H&lt;br /&gt;
#define MAINWINDOW_H&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;KXmlGuiWindow&amp;gt;&lt;br /&gt;
#include &amp;lt;KTextEdit&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MainWindow : public KXmlGuiWindow&lt;br /&gt;
{&lt;br /&gt;
  public:&lt;br /&gt;
    MainWindow(QWidget *parent=0);&lt;br /&gt;
	&lt;br /&gt;
  private:&lt;br /&gt;
    KTextEdit* textArea;&lt;br /&gt;
    void setupActions();&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
#endif&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Only a function &amp;lt;tt&amp;gt;void setupActions()&amp;lt;/tt&amp;gt; has been added which will do all the work setting up the KActions.&lt;br /&gt;
&lt;br /&gt;
===mainwindow.cpp===&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
#include &amp;quot;mainwindow.h&amp;quot;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;KApplication&amp;gt;&lt;br /&gt;
#include &amp;lt;KAction&amp;gt;&lt;br /&gt;
#include &amp;lt;KLocale&amp;gt;&lt;br /&gt;
#include &amp;lt;KActionCollection&amp;gt;&lt;br /&gt;
#include &amp;lt;KStandardAction&amp;gt;&lt;br /&gt;
&lt;br /&gt;
MainWindow::MainWindow(QWidget *parent)&lt;br /&gt;
    : KXmlGuiWindow(parent)&lt;br /&gt;
{&lt;br /&gt;
  textArea = new KTextEdit;&lt;br /&gt;
  setCentralWidget(textArea);&lt;br /&gt;
&lt;br /&gt;
  setupActions();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MainWindow::setupActions()&lt;br /&gt;
{&lt;br /&gt;
  KAction* clearAction = new KAction(this);&lt;br /&gt;
  clearAction-&amp;gt;setText(i18n(&amp;quot;Clear&amp;quot;));&lt;br /&gt;
  clearAction-&amp;gt;setIcon(KIcon(&amp;quot;document-new&amp;quot;));&lt;br /&gt;
  clearAction-&amp;gt;setShortcut(Qt::CTRL + Qt::Key_W);&lt;br /&gt;
  actionCollection()-&amp;gt;addAction(&amp;quot;clear&amp;quot;, clearAction);&lt;br /&gt;
  connect(clearAction, SIGNAL(triggered(bool)),&lt;br /&gt;
          textArea, SLOT(clear()));&lt;br /&gt;
&lt;br /&gt;
  KStandardAction::quit(kapp, SLOT(quit()),&lt;br /&gt;
                        actionCollection());&lt;br /&gt;
&lt;br /&gt;
  setupGUI();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Explanation==&lt;br /&gt;
This builds upon the KXmlGuiWindow code from [[Development/Tutorials/Using_KXmlGuiWindow|Tutorial 2]]. Most of the changes are to &amp;lt;tt&amp;gt;mainwindow.cpp&amp;lt;/tt&amp;gt;, an important structural change being that the constructor for MainWindow now calls &amp;lt;tt&amp;gt;setupActions()&amp;lt;/tt&amp;gt; instead of &amp;lt;tt&amp;gt;setupGUI()&amp;lt;/tt&amp;gt;. &amp;lt;tt&amp;gt;setupActions()&amp;lt;/tt&amp;gt; is where the new KAction code goes before finally calling &amp;lt;tt&amp;gt;setupGUI()&amp;lt;/tt&amp;gt; itself.&lt;br /&gt;
&lt;br /&gt;
===Creating the KAction object===&lt;br /&gt;
The KAction is built up in a number of steps. The first is including the &amp;lt;tt&amp;gt;KAction&amp;lt;/tt&amp;gt; library and then creating the KAction:&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
#include &amp;lt;KAction&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
KAction* clearAction = new KAction(this);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This creates a new KAction called &amp;lt;tt&amp;gt;clearAction&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Setting KAction Properties===&lt;br /&gt;
====Text====&lt;br /&gt;
Now we have our KAction object, we can start setting its properties. The following code sets the text that will be displayed in the menu and under the &amp;lt;tt&amp;gt;KAction&amp;lt;/tt&amp;gt;'s icon in the toolbar.&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;clearAction-&amp;gt;setText(i18n(&amp;quot;Clear&amp;quot;));&amp;lt;/code&amp;gt;&lt;br /&gt;
Note that the text is passed through the i18n() function; this is necessary for the UI to be translatable (more information on this can be found in the [[Development/Tutorials/Localization/i18n|i18n tutorial]]).&lt;br /&gt;
&lt;br /&gt;
====Icon====&lt;br /&gt;
If the action is going to be displayed in a toolbar, it's nice to have an icon depicting the action. The following code sets the icon to the standard KDE &amp;lt;tt&amp;gt;document-new&amp;lt;/tt&amp;gt; icon through the use of the &amp;lt;tt&amp;gt;setIcon()&amp;lt;/tt&amp;gt; function:&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;clearAction-&amp;gt;setIcon(KIcon(&amp;quot;document-new&amp;quot;));&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Keyboard Shortcut====&lt;br /&gt;
Setting a keyboard shortcut to perform our action is equally simple:&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;clearAction-&amp;gt;setShortcut(Qt::CTRL + Qt::Key_W);&amp;lt;/code&amp;gt;&lt;br /&gt;
This associates Ctrl+W with the KAction.&lt;br /&gt;
&lt;br /&gt;
===Adding to the Collection===&lt;br /&gt;
In order for the action to be accessed by the XMLGUI framework (explained in depth later) it must be added to the application's ''action collection''. The action collection is accessed via the &amp;lt;tt&amp;gt;actionCollection()&amp;lt;/tt&amp;gt; function like this: &lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
actionCollection()-&amp;gt;addAction(&amp;quot;clear&amp;quot;, clearAction);&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
Here, the &amp;lt;tt&amp;gt;clearAction&amp;lt;/tt&amp;gt; KAction is added to the collection and given a name of ''clear''. This name (''clear'') is used by the XMLGUI framework to refer to the action, ergo, it should not be localized, since it is used internally only.&lt;br /&gt;
&lt;br /&gt;
====Connecting the action====&lt;br /&gt;
Now that the action is fully set up, it needs to be connected to something useful. In this case (because we want to clear the text area), we connect our action to the &amp;lt;tt&amp;gt;clear()&amp;lt;/tt&amp;gt; action belonging to a KTextEdit (which, unsurprisingly, clears the KTextEdit)&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;&lt;br /&gt;
connect( clearAction, SIGNAL( triggered(bool) ), &lt;br /&gt;
         textArea, SLOT( clear() ) );&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
This is the same as it would be done in Qt with a {{qt|QAction}}.&lt;br /&gt;
&lt;br /&gt;
===KStandardAction===&lt;br /&gt;
&lt;br /&gt;
For actions which would likely appear in almost every KDE application such as 'quit', 'save', and 'load' there are pre-created convenience KActions, accessed through [http://api.kde.org/4.0-api/kdelibs-apidocs/kdeui/html/namespaceKStandardAction.html KStandardAction].&lt;br /&gt;
&lt;br /&gt;
They are very simple to use. Once the library has been included (&amp;lt;tt&amp;gt;#include &amp;lt;KStandardAction&amp;gt;&amp;lt;/tt&amp;gt;), simply supply it with what you want the function to do and which KActionCollection to add it to. For example:&lt;br /&gt;
&amp;lt;code cppqt&amp;gt;KStandardAction::quit(kapp, SLOT(quit()), actionCollection());&amp;lt;/code&amp;gt;&lt;br /&gt;
This creates a KAction with the correct icon, text and shortcut and even adds it to the File menu.&lt;br /&gt;
&lt;br /&gt;
==Adding the action to menus and toolbars==&lt;br /&gt;
At the moment, the new &amp;quot;Clear&amp;quot; action has been created but it hasn't been associated with any menus or toolbars. This is done with a KDE technology called XMLGUI, which does nice things like movable toolbars for you.&lt;br /&gt;
&lt;br /&gt;
{{note|In a later version of KDE4, XMLGUI, may be replaced with a new framework called liveui. For now, XMLGUI, is the only and correct way to set up the UI.}}&lt;br /&gt;
&lt;br /&gt;
==XMLGUI==&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;setupGUI()&amp;lt;/tt&amp;gt; function in {{class|KXmlGuiWindow}} depends on the XMLGUI system to construct the GUI, which XMLGUI does by parsing an XML file description of the interface.&lt;br /&gt;
&lt;br /&gt;
The rule for naming this XML file is &amp;lt;tt&amp;gt;appnameui.rc&amp;lt;/tt&amp;gt;, where &amp;lt;tt&amp;gt;appname&amp;lt;/tt&amp;gt; is the name you set in {{class|KAboutData}} (in this case, ''tutorial3''). So in our example, the file is called &amp;lt;tt&amp;gt;tutorial3ui.rc&amp;lt;/tt&amp;gt;, and is located in the build directory. Where the file will ultimately be placed is handled by CMake.&lt;br /&gt;
&lt;br /&gt;
''See also'' [http://developer.kde.org/documentation/library/kdeqt/kde3arch/xmlgui.html developer.kde.org] which still provides valid information for KDE4.&lt;br /&gt;
&lt;br /&gt;
==''appname''ui.rc File==&lt;br /&gt;
&lt;br /&gt;
Since the description of the UI is defined with XML, the layout must follow strict rules. This tutorial will not go into great depth on this topic, but for more information, see the [[Development/Architecture/KDE4/XMLGUI_Technology|detailed XMLGUI page]] (here is an older tutorial: [http://developer.kde.org/documentation/tutorials/xmlui/preface.html]).&lt;br /&gt;
&lt;br /&gt;
===tutorial3ui.rc===&lt;br /&gt;
&amp;lt;code xml&amp;gt;&lt;br /&gt;
&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;UTF-8&amp;quot;?&amp;gt;&lt;br /&gt;
&amp;lt;!DOCTYPE kpartgui SYSTEM &amp;quot;kpartgui.dtd&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;gui name=&amp;quot;tutorial3&amp;quot; version=&amp;quot;1&amp;quot;&amp;gt;&lt;br /&gt;
  &amp;lt;ToolBar name=&amp;quot;mainToolBar&amp;quot; &amp;gt;&lt;br /&gt;
    &amp;lt;text&amp;gt;Main Toolbar&amp;lt;/text&amp;gt;&lt;br /&gt;
    &amp;lt;Action name=&amp;quot;clear&amp;quot; /&amp;gt;&lt;br /&gt;
  &amp;lt;/ToolBar&amp;gt;&lt;br /&gt;
  &amp;lt;MenuBar&amp;gt;&lt;br /&gt;
    &amp;lt;Menu name=&amp;quot;file&amp;quot; &amp;gt;&lt;br /&gt;
      &amp;lt;Action name=&amp;quot;clear&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;/gui&amp;gt;&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The &amp;lt;tt&amp;gt;&amp;lt;Toolbar&amp;gt;&amp;lt;/tt&amp;gt; tag allows you to describe the toolbar, which is the bar across the top of the window normally with icons. Here it is given the unique name ''mainToolBar'' and its user visible name set to ''Main Toolbar'' using the &amp;lt;tt&amp;gt;&amp;lt;text&amp;gt;&amp;lt;/tt&amp;gt; tag. The clear action is added to the toolbar using the &amp;lt;tt&amp;gt;&amp;lt;Action&amp;gt;&amp;lt;/tt&amp;gt; tag, the name parameter in this tag being the string that was passed to the KActionCollection with &amp;lt;tt&amp;gt;addAction()&amp;lt;/tt&amp;gt; in &amp;lt;tt&amp;gt;mainwindow.cpp&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Besides having the action in the toolbar, it can also be added to the menubar. Here the action is being added to the ''File'' menu of the &amp;lt;tt&amp;gt;MenuBar&amp;lt;/tt&amp;gt; the same way it was added to the toolbar.&lt;br /&gt;
&lt;br /&gt;
Change the 'version' attribute of the &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;gui&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; tag if you changed .rc file since the last install to force a system cache update.&lt;br /&gt;
&lt;br /&gt;
Some notes on the interaction between code and the .rc file: Menus appear automatically and should have a &amp;lt;tt&amp;gt;&amp;lt;nowiki&amp;gt;&amp;lt;text/&amp;gt;&amp;lt;/nowiki&amp;gt;&amp;lt;/tt&amp;gt; child tag unless they refer to standard menus. Actions need to be created manually and inserted into the actionCollection() using the name in the .rc file. Actions can be hidden or disabled, whereas menus can't.&lt;br /&gt;
&lt;br /&gt;
==CMake==&lt;br /&gt;
Finally, the &amp;lt;tt&amp;gt;tutorial3ui.rc&amp;lt;/tt&amp;gt; needs to go somewhere where KDE can find it (can't just leave it in the source directory!). '''This means the project needs to be installed somewhere.'''&lt;br /&gt;
===CMakeLists.txt===&lt;br /&gt;
&amp;lt;code ini&amp;gt;&lt;br /&gt;
project(tutorial3)&lt;br /&gt;
&lt;br /&gt;
find_package(KDE4 REQUIRED)&lt;br /&gt;
include_directories(${KDE4_INCLUDES})&lt;br /&gt;
&lt;br /&gt;
set(tutorial3_SRCS &lt;br /&gt;
  main.cpp&lt;br /&gt;
  mainwindow.cpp&lt;br /&gt;
)&lt;br /&gt;
&lt;br /&gt;
kde4_add_executable(tutorial3 ${tutorial3_SRCS})&lt;br /&gt;
&lt;br /&gt;
target_link_libraries(tutorial3 ${KDE4_KDEUI_LIBS})&lt;br /&gt;
&lt;br /&gt;
install(TARGETS tutorial3 DESTINATION ${BIN_INSTALL_DIR})&lt;br /&gt;
install(FILES tutorial3ui.rc &lt;br /&gt;
        DESTINATION  ${DATA_INSTALL_DIR}/tutorial3)&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This file is almost identical to the one for tutorial2, but with two extra lines at the end that describe where the files are to be installed. Firstly, the &amp;lt;tt&amp;gt;tutorial3&amp;lt;/tt&amp;gt; target is installed to the &amp;lt;tt&amp;gt;BIN_INSTALL_DIR&amp;lt;/tt&amp;gt; then the &amp;lt;tt&amp;gt;tutorial3ui.rc&amp;lt;/tt&amp;gt; file that describes the layout of the user interface is installed to the application's data directory.&lt;br /&gt;
&lt;br /&gt;
===Make, Install And Run===&lt;br /&gt;
If you don't have write access to where your KDE4 installation directory, you can install it to a folder in your home directory.&lt;br /&gt;
&lt;br /&gt;
To tell CMake where to install the program, set the &amp;lt;tt&amp;gt;DCMAKE_INSTALL_PREFIX&amp;lt;/tt&amp;gt; switch. You probably just want to install it somewhere local for testing (it's probably a bit silly to go to the effort of installing these tutorials to your KDE directory), so the following might be appropriate:&lt;br /&gt;
 mkdir build &amp;amp;&amp;amp; cd build&lt;br /&gt;
 cmake .. -DCMAKE_INSTALL_PREFIX=$HOME&lt;br /&gt;
 make install&lt;br /&gt;
 $HOME/bin/tutorial3&lt;br /&gt;
which will create a KDE-like directory structure in your user's home directory directory and will install the executable to {{path|$HOME/bin/tutorial3}}.&lt;br /&gt;
&lt;br /&gt;
==Moving On==&lt;br /&gt;
Now you can move on to [[Development/Tutorials/Saving_and_loading|saving and loading]].&lt;br /&gt;
&lt;br /&gt;
[[Category:C++]]&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Languages/Python</id>
		<title>Development/Languages/Python</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Languages/Python"/>
				<updated>2008-12-04T14:42:52Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: /* Documentation and Tutorials */ Phonon Example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Languages/Python}}&lt;br /&gt;
&lt;br /&gt;
Python is a powerful object oriented, dynamic language. You can find out more about the language itself on the Python website at http://www.python.org/.&lt;br /&gt;
&lt;br /&gt;
Two important pieces of software are needed to develop KDE applications using Python, [http://www.riverbankcomputing.co.uk/software/pyqt/intro PyQt] and PyKDE. PyQt provides Python support for the Qt library which KDE is built on. PyQt can be obtained at http://www.riverbankcomputing.co.uk/software/pyqt/ . Riverbank Computing has a lot of good documentation about how to use PyQt to create pure Qt applications. If you are new to KDE / Python development, then learning how to use PyQt is the best first step.&lt;br /&gt;
&lt;br /&gt;
PyKDE builds on top of PyQt and adds Python support for KDE's libraries and technologies.&lt;br /&gt;
&lt;br /&gt;
PyKDE is distributed as part of the kdebindings module. Stable releases can be downloaded from the normal [http://kde.org/download/ KDE download page], although it is usually easier to install pre-built packages from your operating system distribution. You can also obtain PyKDE from KDE's subversion repository:&lt;br /&gt;
&lt;br /&gt;
 svn co svn://anonsvn.kde.org/home/kde/trunk/KDE/kdebindings/python/pykde4&lt;br /&gt;
&lt;br /&gt;
The code in subversion can be browsed online via http://websvn.kde.org/trunk/KDE/kdebindings/python/pykde4/.&lt;br /&gt;
&lt;br /&gt;
==Documentation and Tutorials==&lt;br /&gt;
* [http://www.riverbankcomputing.co.uk/software/pyqt/intro PyQt home page and documentation]&lt;br /&gt;
* [[/Using PyKDE 4|Using PyKDE 4]]&lt;br /&gt;
* [[/PyKDE_WebKit_Tutorial|PyKDE WebKit Tutorial]], a simple web browser application in PyKDE&lt;br /&gt;
* [http://api.kde.org/pykde-4.1-api/ KDE API class reference for PyKDE 4.1].&lt;br /&gt;
* [[Development/Tutorials/Python introduction to signals and slots|introduction to signals and slots]]&lt;br /&gt;
* [http://www.rkblog.rk.edu.pl/w/p/introduction-pyqt4/ Introduction article about PyQt4]&lt;br /&gt;
* [[Development/Tutorials/Phonon/Introduction/Python|Phonon Example]]&lt;br /&gt;
&lt;br /&gt;
===KDE 3 and PyKDE 3===&lt;br /&gt;
Documentation and tutorials for the older PyQt and PyKDE 3.&lt;br /&gt;
* [http://vizzzion.org/?id=pyqt Python-Qt tutorial]&amp;lt;br /&amp;gt;''&amp;lt;font size=&amp;quot;-1&amp;quot;&amp;gt; In this tutorial, the basic steps of creating a Qt-based application with PyQt are explained. &amp;lt;/font&amp;gt;''&lt;br /&gt;
&lt;br /&gt;
==Further reading and information==&lt;br /&gt;
*[http://www.riverbankcomputing.com/mailman/listinfo/pyqt PyQt and PyKDE mailing list]&lt;br /&gt;
*[http://www.riverbankcomputing.co.uk/software/pykde/intro PyKDE Homepage]&lt;br /&gt;
*[http://www.diotavelli.net/PyQtWiki The PyQt and PyKDE community Wiki]&lt;br /&gt;
*The book [http://www.qtrac.eu/pyqtbook.html Rapid GUI Programming with Python and Qt] is available and covers Qt 4 programming with Python.&lt;br /&gt;
*The IRC channel ''#kubuntu-devel'' on freenode often has PyKDE programmers in it.&lt;br /&gt;
&lt;br /&gt;
==Applications using PyKDE==&lt;br /&gt;
*[http://utils.kde.org/projects/printer-applet/ printer-applet]&lt;br /&gt;
*[http://websvn.kde.org/trunk/KDE/kdeadmin/system-config-printer-kde/ system-config-printer-kde]&lt;br /&gt;
*[http://websvn.kde.org/trunk/extragear/utils/guidance-power-manager/ Guidance Power Manager], a battery applet&lt;br /&gt;
*[https://code.launchpad.net/ubiquity/trunk Ubiquity], installer for Kubuntu&lt;br /&gt;
*[https://code.launchpad.net/~ubuntu-core-dev/gdebi/ubuntu GDebi], .deb package installer&lt;br /&gt;
*[https://code.launchpad.net/~jr/install-package/trunk install-package], graphical apt-get&lt;br /&gt;
*[http://websvn.kde.org/trunk/KDE/kdebindings/python/pykde4/examples/ some examples are in the PyKDE source]&lt;br /&gt;
&lt;br /&gt;
[[Category:Python]]&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Phonon/Introduction/Python</id>
		<title>Development/Tutorials/Phonon/Introduction/Python</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Phonon/Introduction/Python"/>
				<updated>2008-12-03T10:41:23Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: Behold C++ programmers, in your face! Python is so beautiful =)&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This is the Python port of tutorial2.cpp found under [[Development/Tutorials/Phonon/Introduction]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
#This file is part of the KDE project&lt;br /&gt;
#Copyright (C) 2007 Matthias Kretz &amp;lt;kretz@kde.org&amp;gt;&lt;br /&gt;
#adapted 2008 by Thorsten Staerk&lt;br /&gt;
#ported to PyQt4 by Christoph Burgmer&lt;br /&gt;
&lt;br /&gt;
#Permission to use, copy, modify, and distribute this software&lt;br /&gt;
#and its documentation for any purpose and without fee is hereby&lt;br /&gt;
#granted, provided that the above copyright notice appear in all&lt;br /&gt;
#copies and that both that the copyright notice and this&lt;br /&gt;
#permission notice and warranty disclaimer appear in supporting&lt;br /&gt;
#documentation, and that the name of the author not be used in&lt;br /&gt;
#advertising or publicity pertaining to distribution of the&lt;br /&gt;
#software without specific, written prior permission.&lt;br /&gt;
&lt;br /&gt;
#The author disclaim all warranties with regard to this&lt;br /&gt;
#software, including all implied warranties of merchantability&lt;br /&gt;
#and fitness.  In no event shall the author be liable for any&lt;br /&gt;
#special, indirect or consequential damages or any damages&lt;br /&gt;
#whatsoever resulting from loss of use, data or profits, whether&lt;br /&gt;
#in an action of contract, negligence or other tortious action,&lt;br /&gt;
#arising out of or in connection with the use or performance of&lt;br /&gt;
#this software.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
import sys&lt;br /&gt;
&lt;br /&gt;
from PyQt4.QtGui import QApplication, QMainWindow, QDirModel, QColumnView&lt;br /&gt;
from PyQt4.QtGui import QFrame&lt;br /&gt;
from PyQt4.QtCore import SIGNAL&lt;br /&gt;
from PyQt4.phonon import Phonon&lt;br /&gt;
&lt;br /&gt;
class MainWindow(QMainWindow):&lt;br /&gt;
&lt;br /&gt;
    m_model = QDirModel()&lt;br /&gt;
&lt;br /&gt;
    def __init__(self):&lt;br /&gt;
        QMainWindow.__init__(self)&lt;br /&gt;
        self.m_fileView = QColumnView(self)&lt;br /&gt;
        self.m_media = None&lt;br /&gt;
&lt;br /&gt;
        self.setCentralWidget(self.m_fileView)&lt;br /&gt;
        self.m_fileView.setModel(self.m_model)&lt;br /&gt;
        self.m_fileView.setFrameStyle(QFrame.NoFrame)&lt;br /&gt;
&lt;br /&gt;
        self.connect(self.m_fileView,&lt;br /&gt;
            SIGNAL(&amp;quot;updatePreviewWidget(const QModelIndex &amp;amp;)&amp;quot;), self.play)&lt;br /&gt;
&lt;br /&gt;
    def play(self, index):&lt;br /&gt;
        self.delayedInit()&lt;br /&gt;
        #self.m_media.setCurrentSource(self.m_model.filePath(index))&lt;br /&gt;
        self.m_media.setCurrentSource(&lt;br /&gt;
            Phonon.MediaSource(self.m_model.filePath(index)))&lt;br /&gt;
        self.m_media.play()&lt;br /&gt;
&lt;br /&gt;
    def delayedInit(self):&lt;br /&gt;
        if not self.m_media:&lt;br /&gt;
            self.m_media = Phonon.MediaObject(self)&lt;br /&gt;
            audioOutput = Phonon.AudioOutput(Phonon.MusicCategory, self)&lt;br /&gt;
            Phonon.createPath(self.m_media, audioOutput)&lt;br /&gt;
&lt;br /&gt;
def main():&lt;br /&gt;
    app = QApplication(sys.argv)&lt;br /&gt;
    QApplication.setApplicationName(&amp;quot;Phonon Tutorial 2 (Python)&amp;quot;)&lt;br /&gt;
    mw = MainWindow()&lt;br /&gt;
    mw.show()&lt;br /&gt;
    sys.exit(app.exec_())&lt;br /&gt;
&lt;br /&gt;
if __name__ == '__main__':&lt;br /&gt;
    main()&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Phonon/Introduction</id>
		<title>Development/Tutorials/Phonon/Introduction</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Phonon/Introduction"/>
				<updated>2008-12-03T10:38:37Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: Python example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;In order to make the revision process clear, I introduce a confident index, &amp;quot;0&amp;quot; means nobody except me has reviewed the text. I please the reviewers to increment the counter to prove the validity of the tutorials.&lt;br /&gt;
&lt;br /&gt;
You can get help on #phonon on irc.freenode.org.&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
See [[Development/Tutorials/Phonon/Introduction/Python]] for the same example in Python.&lt;br /&gt;
&lt;br /&gt;
= Introduction =&lt;br /&gt;
''Confident Index =1''&lt;br /&gt;
&lt;br /&gt;
The following is based on the documentation available here&lt;br /&gt;
[http://www.englishbreakfastnetwork.org/apidocs/apidox-kde-4.0/kdelibs-apidocs/phonon/html/index.html Phonon API].&lt;br /&gt;
&lt;br /&gt;
By getting involved with Phonon, you can choose between three different main tasks.&lt;br /&gt;
* '''Using the Phonon API''', which allows you to develop your own multimedia application. In fact any application which needs sound can take benefits from the phonon API. In the tutorials showing the API we will learn how to set up the development environment with kdevelop 3.4. &lt;br /&gt;
&lt;br /&gt;
* '''Hacking the Phonon library''', (try to develop more this topic).&lt;br /&gt;
&lt;br /&gt;
* '''Writing Phonon backend''', this consists in writing interfaces that allows Phonon to use different sound/video engine. This usually requires good skills and knowledge of the engine you interface with.&lt;br /&gt;
&lt;br /&gt;
Beginners will probably be more interested by the first task.&lt;br /&gt;
&lt;br /&gt;
= Using the phonon API =&lt;br /&gt;
The following example is taken from http://www.englishbreakfastnetwork.org/apidocs/apidox-kde-4.0/kdelibs-apidocs/phonon/html/index.html. It lets you choose a multimedia file and tries to play it. To change the sound device that is used by default, use the command &amp;lt;tt&amp;gt;systemsettings&amp;lt;/tt&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== tutorial2.cpp ==&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*   This file is part of the KDE project&lt;br /&gt;
     Copyright (C) 2007 Matthias Kretz &amp;lt;kretz@kde.org&amp;gt;&lt;br /&gt;
     adapted 2008 by Thorsten Staerk&lt;br /&gt;
 &lt;br /&gt;
     Permission to use, copy, modify, and distribute this software&lt;br /&gt;
     and its documentation for any purpose and without fee is hereby&lt;br /&gt;
     granted, provided that the above copyright notice appear in all&lt;br /&gt;
     copies and that both that the copyright notice and this&lt;br /&gt;
     permission notice and warranty disclaimer appear in supporting&lt;br /&gt;
     documentation, and that the name of the author not be used in&lt;br /&gt;
     advertising or publicity pertaining to distribution of the&lt;br /&gt;
     software without specific, written prior permission.&lt;br /&gt;
 &lt;br /&gt;
     The author disclaim all warranties with regard to this&lt;br /&gt;
     software, including all implied warranties of merchantability&lt;br /&gt;
     and fitness.  In no event shall the author be liable for any&lt;br /&gt;
     special, indirect or consequential damages or any damages&lt;br /&gt;
     whatsoever resulting from loss of use, data or profits, whether&lt;br /&gt;
     in an action of contract, negligence or other tortious action,&lt;br /&gt;
     arising out of or in connection with the use or performance of&lt;br /&gt;
     this software.&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;phonon/mediaobject.h&amp;gt;&lt;br /&gt;
#include &amp;lt;phonon/path.h&amp;gt;&lt;br /&gt;
#include &amp;lt;phonon/audiooutput.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;QtGui/QApplication&amp;gt;&lt;br /&gt;
#include &amp;lt;QtGui/QMainWindow&amp;gt;&lt;br /&gt;
#include &amp;lt;QtGui/QDirModel&amp;gt;&lt;br /&gt;
#include &amp;lt;QtGui/QColumnView&amp;gt;&lt;br /&gt;
&lt;br /&gt;
class MainWindow : public QMainWindow&lt;br /&gt;
{&lt;br /&gt;
    Q_OBJECT&lt;br /&gt;
    public:&lt;br /&gt;
        MainWindow();&lt;br /&gt;
&lt;br /&gt;
    private slots:&lt;br /&gt;
        void play(const QModelIndex &amp;amp;index);&lt;br /&gt;
&lt;br /&gt;
    private:&lt;br /&gt;
        void delayedInit();&lt;br /&gt;
&lt;br /&gt;
        QColumnView m_fileView;&lt;br /&gt;
        QDirModel m_model;&lt;br /&gt;
&lt;br /&gt;
        Phonon::MediaObject *m_media;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
MainWindow::MainWindow()&lt;br /&gt;
    : m_fileView(this),&lt;br /&gt;
    m_media(0)&lt;br /&gt;
{&lt;br /&gt;
    setCentralWidget(&amp;amp;m_fileView);&lt;br /&gt;
    m_fileView.setModel(&amp;amp;m_model);&lt;br /&gt;
    m_fileView.setFrameStyle(QFrame::NoFrame);&lt;br /&gt;
&lt;br /&gt;
    connect(&amp;amp;m_fileView, SIGNAL(updatePreviewWidget(const QModelIndex &amp;amp;)), SLOT(play(const QModelIndex &amp;amp;)));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MainWindow::play(const QModelIndex &amp;amp;index)&lt;br /&gt;
{&lt;br /&gt;
    delayedInit();&lt;br /&gt;
    m_media-&amp;gt;setCurrentSource(m_model.filePath(index));&lt;br /&gt;
    m_media-&amp;gt;play();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void MainWindow::delayedInit()&lt;br /&gt;
{&lt;br /&gt;
     if (!m_media) {&lt;br /&gt;
        m_media = new Phonon::MediaObject(this);&lt;br /&gt;
        Phonon::AudioOutput *audioOutput = new Phonon::AudioOutput(Phonon::MusicCategory, this);&lt;br /&gt;
        createPath(m_media, audioOutput);&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char **argv)&lt;br /&gt;
{&lt;br /&gt;
    QApplication app(argc, argv);&lt;br /&gt;
    QApplication::setApplicationName(&amp;quot;Phonon Tutorial 2&amp;quot;);&lt;br /&gt;
    MainWindow mw;&lt;br /&gt;
    mw.show();&lt;br /&gt;
    return app.exec();&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
#include &amp;quot;tutorial2.moc&amp;quot;&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Compile and run it ==&lt;br /&gt;
 moc tutorial2.cpp &amp;gt; tutorial2.moc&lt;br /&gt;
 g++ -o tutorial -lphonon tutorial2.cpp &amp;amp;&amp;amp; ./tutorial&lt;br /&gt;
&lt;br /&gt;
Eventually add a &amp;quot;-I/usr/include/qt4&amp;quot; to tell q++ where to look for the header files.&lt;br /&gt;
&lt;br /&gt;
[[Category:KDE4]]&lt;br /&gt;
[[Category:Phonon]]&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Projects/Marble/HistoricalMaps</id>
		<title>Projects/Marble/HistoricalMaps</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Projects/Marble/HistoricalMaps"/>
				<updated>2008-10-30T12:56:09Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: Replaced by better quality&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;====Historical Maps for Marble====&lt;br /&gt;
We'd like to add Historical Maps to Marble. Ideally one would later on be able to travel through time using a slider later on.&lt;br /&gt;
For now we concentrate on a more simple approach:&lt;br /&gt;
&lt;br /&gt;
There are lots of very early world maps that are under the public domain. You'll find several on Wikipedia (please add further ones to the list as you find them) and elsewhere on the internet:&lt;br /&gt;
&lt;br /&gt;
* [[/WorldMapSchagen1689|Historical World Map: G. van Schagen (1689) ]]&lt;br /&gt;
 -- Magnus has completed this one already&lt;br /&gt;
* [http://commons.wikimedia.org/wiki/Image:Leonhard_Euler_World_Map_AD1760.jpg Leonhard Euler World Map 1760]&lt;br /&gt;
* [http://commons.wikimedia.org/wiki/Image:Moll_-_A_new_map_of_the_whole_world_with_the_trade_winds.png Moll - A new map of the world with the trade winds]&lt;br /&gt;
* [http://commons.wikimedia.org/wiki/Image:Nova_Orbis_Tabula_in_Lucem_Edita.jpg Nova Orbis Tabula in Lucem Edita]&lt;br /&gt;
* [http://memory.loc.gov/cgi-bin/map_item.pl?data=/home/www/data/gmd/gmd3/g3200/g3200/ct000725.jp2&amp;amp;style=gmd&amp;amp;itemLink=r?ammem/gmd:@field(NUMBER+@band(g3200+ct000725))&amp;amp;title=Universalis%20cosmographia%20secundum%20Ptholomaei%20traditionem%20et%20Americi%20Vespucii%20alioru%5Bm%5Dque%20lustrationes. &amp;lt;nowiki&amp;gt;Universalis cosmographia secundum Ptholomaei traditionem et Americi Vespucii alioru[m]que lustrationes.&amp;lt;/nowiki&amp;gt;] ([http://www.loc.gov/rr/geogmap/waldexh.html General information])&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====Licensing====&lt;br /&gt;
&lt;br /&gt;
If you find new maps it's always important to check the license. Although ancient maps should usually be under the public domain there are several people who claim copyright on the data due to the image manipulation work they have done as a part of post-processing the scan. No matter whether this is legitimate or not we should respect those claims and look for data that was intended to be published under the public domain (or another free license) and use that. &lt;br /&gt;
&lt;br /&gt;
It's important to note that people like to distribute imagery &amp;quot;free for non-commercial usage&amp;quot;. Unfortunately we are not able to use and distribute this data as this would e.g. prohibit most Linux Distributors from distributing our software.&lt;br /&gt;
So do not use data that is &amp;quot;free for non-commercial use&amp;quot;! It's not suitable for our purposes. If you think that there is a chance that the author might agree to change the license to a less restrictive one then it might be worth to contact him. However pretty often the &amp;quot;non-commercial&amp;quot; wording is provided intentionally this way to allow for a business case of the author.&lt;br /&gt;
&lt;br /&gt;
====Preparing Historical Maps for use in Marble====&lt;br /&gt;
Maps for Marble need to get provided in [http://en.wikipedia.org/wiki/Plate_carrée_projection plate carrée projection] (also referred &lt;br /&gt;
to as &amp;quot;Equirectangular projection&amp;quot;):&lt;br /&gt;
&lt;br /&gt;
There are morphing tools and HOWTOS on the web that can tell you how to morph &lt;br /&gt;
ancient maps into the desired projection. It doesn't require too many skills. Just some patience and love to detail.&lt;br /&gt;
&lt;br /&gt;
You can have a look at [http://spin3d.com/ Spin3D] for a source of inspiration. Please consider to use Free Software instead of Morph Man (e.g. xmorph).&lt;br /&gt;
&lt;br /&gt;
The &amp;quot;rectangular image&amp;quot; that is the result after half of the tutorial is &lt;br /&gt;
what you need.&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Development/Tutorials/Printing_Hello_World</id>
		<title>Development/Tutorials/Printing Hello World</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Development/Tutorials/Printing_Hello_World"/>
				<updated>2008-07-24T22:53:01Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{note|This tutorial seems not to be up to date with current KDE4 development.}}&lt;br /&gt;
&lt;br /&gt;
=The mission=&lt;br /&gt;
Print '''Hello World''' on your printer.&lt;br /&gt;
&lt;br /&gt;
=The KDE version=&lt;br /&gt;
This code will work for KDE 3 as for KDE 4.&lt;br /&gt;
&lt;br /&gt;
=The code=&lt;br /&gt;
&amp;lt;code cppqt n&amp;gt;&lt;br /&gt;
#include &amp;lt;kprinter.h&amp;gt;&lt;br /&gt;
#include &amp;lt;qpainter.h&amp;gt;&lt;br /&gt;
#include &amp;lt;kapplication.h&amp;gt;&lt;br /&gt;
#include &amp;lt;kaboutdata.h&amp;gt;&lt;br /&gt;
#include &amp;lt;kmessagebox.h&amp;gt;&lt;br /&gt;
#include &amp;lt;kcmdlineargs.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
This prints Hello World on your printer&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int main(int argc, char *argv[])&lt;br /&gt;
{&lt;br /&gt;
  KAboutData aboutData( &amp;quot;test&amp;quot;, &amp;quot;test&amp;quot;, &amp;quot;1.0&amp;quot;, &amp;quot;test&amp;quot;,&lt;br /&gt;
      KAboutData::License_GPL, &amp;quot;(c) 2006&amp;quot; );&lt;br /&gt;
  KCmdLineArgs::init( argc, argv, &amp;amp;aboutData );&lt;br /&gt;
  KApplication app;&lt;br /&gt;
&lt;br /&gt;
  KPrinter job;&lt;br /&gt;
  job.setFullPage( true );&lt;br /&gt;
  if ( job.setup() )&lt;br /&gt;
  {&lt;br /&gt;
    QPainter painter;&lt;br /&gt;
    painter.begin( &amp;amp;job );&lt;br /&gt;
    painter.drawText(100,100,&amp;quot;Hello World&amp;quot;);&lt;br /&gt;
    painter.end(); &lt;br /&gt;
    // this makes the print job start&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=Explanation=&lt;br /&gt;
You need a KDE instance to print, because this instance stores your configuration, including your printer configuration. You create one by instanciating the KApplication class.&lt;br /&gt;
&lt;br /&gt;
=How to compile=&lt;br /&gt;
==With KDE 4 and CMake==&lt;br /&gt;
===CMakeLists.txt===&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
find_package(KDE4 REQUIRED)&lt;br /&gt;
include_directories( ${KDE4_INCLUDES} )&lt;br /&gt;
kde4_add_executable(printhelloworld printtest.cpp)&lt;br /&gt;
target_link_libraries(printhelloworld ${KDE4_KDEPRINT_LIBS})&lt;br /&gt;
&amp;lt;/code&amp;gt;&lt;br /&gt;
===Make and Run===&lt;br /&gt;
Then do:&lt;br /&gt;
 cmake .&lt;br /&gt;
 make&lt;br /&gt;
 ./printhelloworld&lt;br /&gt;
&lt;br /&gt;
==With KDE 3==&lt;br /&gt;
Quite easy:&lt;br /&gt;
 gcc printtest.cpp -o print -I/usr/lib/qt3/include \&lt;br /&gt;
 -I/opt/kde3/include -L/opt/kde3/lib \&lt;br /&gt;
 -L/usr/lib/qt3/lib  -lqt-mt -lkdeprint&lt;br /&gt;
&lt;br /&gt;
=See also=&lt;br /&gt;
* Point your konqueror to [http://developer.kde.org/documentation/library/cvs-api/kdelibs-apidocs/kdeprint/html/classKPrinter.html kde:kprinter]&lt;br /&gt;
[[Category:KDE4]]&lt;br /&gt;
[[Category:C++]]&lt;/div&gt;</summary>
		<author><name>Chris</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>2008-07-24T20:07:56Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: + pitfall #4, see the bug filed against Amarok for the Chinese example&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{Template:I18n/Language Navigation Bar|Development/Tutorials/Localization/i18n Mistakes}}&lt;br /&gt;
&lt;br /&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=[[../i18n|Writing Applications With Localization in Mind]]|&lt;br /&gt;
&lt;br /&gt;
next=[[../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 must 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 {{qt|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;&lt;br /&gt;
QString msg=i18n(&amp;quot;Do you want to replace &amp;quot;) + &lt;br /&gt;
                 oldFile+i18n(&amp;quot; with &amp;quot;) + &lt;br /&gt;
                 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 &amp;lt;tt&amp;gt;%&amp;lt;i&amp;gt;number&amp;lt;/i&amp;gt;&amp;lt;/tt&amp;gt; placeholder substitution, which lets the translators 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. The arguments themselves are passed as extra parameters to &amp;lt;tt&amp;gt;i18n()&amp;lt;/tt&amp;gt;.&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;&lt;br /&gt;
QString msg = i18n(&amp;quot;Do you want to replace %1 with %2?&amp;quot;,&lt;br /&gt;
                   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;
A related mistake is not including markup tags in rich text, such as &amp;amp;lt;b&amp;amp;gt;&amp;amp;lt;/b&amp;amp;gt; or &amp;amp;lt;i&amp;amp;gt;&amp;amp;lt;/i&amp;amp;gt;, in the translatable string. Not all languages use such markup in an identical fashion to English and so it is necessary for the translator to be able to &amp;quot;translate&amp;quot; the markup accordingly as well.&lt;br /&gt;
&lt;br /&gt;
Similarly, messages that contain a version string or other often changing parts should be inserted by placeholders 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 using 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/Localization/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;
== Pitfall #4: Complex Text Flow ==&lt;br /&gt;
&lt;br /&gt;
When designing an application that needs non-standard text flow, don't assume that the same rules apply for all languages. Given vertical writing as an example East-Asian languages using Chinese characters have a long history of vertical writing, even longer then horizontal. Strings are not rotated by 90 degrees but instead single characters are placed under one another. There might be just a different behaviour with different scripts. Expect the need to implement specialised versions.&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>Chris</name></author>	</entry>

	<entry>
		<id>http://techbase.kde.org/Contribute/Bugsquad/BugDays/AmarokDay1/Bugs_needing_users_with_particular_setups</id>
		<title>Contribute/Bugsquad/BugDays/AmarokDay1/Bugs needing users with particular setups</title>
		<link rel="alternate" type="text/html" href="http://techbase.kde.org/Contribute/Bugsquad/BugDays/AmarokDay1/Bugs_needing_users_with_particular_setups"/>
				<updated>2008-06-17T18:58:42Z</updated>
		
		<summary type="html">&lt;p&gt;Chris: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;===Bugs needing users with particular setups===&lt;br /&gt;
Bugs that require particular software or hardware that you don't have available should be listed here with a description of the non-standard requirement.&lt;br /&gt;
&lt;br /&gt;
*{{Bug|118288}} Requires a proxy setup for port 80. [[User:Mdhowe|Mdhowe]]&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;s&amp;gt;{{Bug|116220}} Needs KDE3 running, i really want to close this as INVALID or something :P [[User:Blauzahl|Blauzahl]]&amp;lt;/s&amp;gt;&lt;br /&gt;
**&amp;lt;s&amp;gt;Ramblurr says that if this still exists, its a WONTFIX&amp;lt;/s&amp;gt;&lt;br /&gt;
**&amp;lt;s&amp;gt;ack for WONTFIX --[[User:Nightrose|Nightrose]] 09:52, 15 June 2008 (CEST)&amp;lt;/s&amp;gt;[[User:Blauzahl|Blauzahl]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|119087}} Needs KDE3. [[User:Mdhowe|Mdhowe]]&lt;br /&gt;
** WONTFIX - even if it is still present we will not fix it --[[User:Nightrose|Nightrose]] 09:52, 15 June 2008 (CEST)&lt;br /&gt;
&lt;br /&gt;
*&amp;lt;s&amp;gt;{{Bug|114285}} Needs two screens [[User:Blauzahl|Blauzahl]]&amp;lt;/s&amp;gt;&lt;br /&gt;
** &amp;lt;s&amp;gt;very old - likely fixed - WONTFIX anyway --[[User:Nightrose|Nightrose]] 09:52, 15 June 2008 (CEST)&amp;lt;/s&amp;gt; closed as REMIND with a message to reopen if it exists in 2 [[User:Blauzahl|Blauzahl]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|119026}} Requires a RTL language setup such as Arabic or Hebrew. [[User:Mdhowe|Mdhowe]]&lt;br /&gt;
** close due to lag of feedback - WONTFIX anyway --[[User:Nightrose|Nightrose]] 09:52, 15 June 2008 (CEST)&lt;br /&gt;
** I'd close it as a REMIND, who knows, maybe they'll give you a patch for 2 :D [[User:Blauzahl|Blauzahl]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|112437}} Needs a proxy [[User:Kage Jittai|Kage Jittai]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|137346}} &amp;lt;b&amp;gt;crash&amp;lt;/b&amp;gt; Needs portable media device to check. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|133609}} Can't get transcode working [[User:progger1986|progger1986]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|133764}} Needs a DAAP share [[User:progger1986|progger1986]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|130597}} Need some unplayable files, reporter mentions m4a -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|134544}} Needs almost none free disk space [[User:progger1986|progger1986]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|134614}} Needs mDNSresponder and iTunes 7 [[User:progger1986|progger1986]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|134718}} Needs cue sheets ans last.fm account [[User:progger1986|progger1986]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|130929}} Needs media device -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|134416}} Needs DAAP client [[User:progger1986|progger1986]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|139030}} - Needs someone with a lot of mp3 files and PostgreSQL. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|138240}} - &amp;lt;b&amp;gt;patch&amp;lt;/b&amp;gt; Needs someone with a portable media device, includes a patch. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|138743}} - &amp;lt;b&amp;gt;crash&amp;lt;/b&amp;gt; Needs an mtp mp3 player. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|138850}} - Needs someone with an ipod to check. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|139218}} - Needs a Creative Vision M portable media device to check. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|139271}} - Needs a Creative Zen Vision portable media device to check. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|135466}} need an Ogg with multiple logical streams -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|135665}} need an iPod -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|135681}} need a media device. -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|135938}} need a Samba share -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|135823}} yet to be tested with amarok 2, mark as LATER (conf. by Nightrose) -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|136153}} should be fixed with recent libgpod (as stated in last comment), but can't verify without iPod -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|139805}} - Needs a portable media device. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|139836}} - Needs someone with Amarok/MySQL to recheck. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|140170}} - Needs someone with a MTP media device to check. [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|140752}} - Needs a podcast with a missing file (possibly a webserver 404 error page). [[User:Lemma|Lemma]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|140752}} - Needs IPod-Nano. Most likely resolved in 1.4.9.1 [[User:Leuty|Leuty]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|142680}} need media with cue-sheet -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|143421}} need someone to test podcast issues -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|143485}} another cue-sheet related bug -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|139538}} - Need a Sandisk player [[User:Krop|Krop]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|139772}} - Need someone running KDE3 and Amarok 1.4 (global shortcuts have no effects in KDE4) [[User:Krop|Krop]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|127832}} Requires a collection over NFS to test [[User:Kage Jittai|Kage Jittai]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|140270}} - Need a MTP compatible device [[User:Krop|Krop]]&lt;br /&gt;
&lt;br /&gt;
*{{Bug|147755}} needs East Asian locale -- [[User:Aides|Aides]]&lt;br /&gt;
*:Actually if the language files are all included, all you need to do is switch the language under the help menu. See the screenshot attached to the bug, to check if the script is still rotated, or if it's written top-down. Sorry, can't check, no nightly builds for Debian :(. But I'll evaluate a screenshot if you give me one. --[[User:Chris|Chris]] 20:58, 17 June 2008 (CEST)&lt;br /&gt;
*{{bug|147890}} complex setup, involving NFS shares, MySQL backend and some 60000 items in collection -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|148108}} need an iPod; bug has been updated recently, reporter is feedbackful -- [[User:Aides|Aides]]&lt;br /&gt;
&lt;br /&gt;
*{{bug|148692}}, {{bug|148691}} and {{bug|154495}} all need CUE files to be tested. Amarok really seems not to handle CUE files correctly. --[[User:Mamarok|Mamarok]] 13:54, 17 June 2008 (CEST)&lt;/div&gt;</summary>
		<author><name>Chris</name></author>	</entry>

	</feed>