<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>dead fish &#187; Qt</title>
	<atom:link href="http://www.thomaskeller.biz/blog/category/coding/qt/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.thomaskeller.biz/blog</link>
	<description>only dead fish swim with the stream</description>
	<lastBuildDate>Wed, 28 Jul 2010 11:13:00 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Makefile-based InnoSetup automation with QMake</title>
		<link>http://www.thomaskeller.biz/blog/2010/06/03/makefile-based-innosetup-automation-with-qmake/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/06/03/makefile-based-innosetup-automation-with-qmake/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 20:57:21 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[guitone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=681</guid>
		<description><![CDATA[Over the last couple of weeks I did several major improvements to the QMake-based build setup guitone uses: The project file comes now with one target to create a tarball, one to create a Mac OS X disk image containing all the needed Qt libraries and one target to install the application, which can be [...]]]></description>
			<content:encoded><![CDATA[<p>Over the last couple of weeks I did several major improvements to the QMake-based build setup <a href="http://guitone.thomaskeller.biz">guitone</a> uses: The project file comes now with one target to create a tarball, one to create a Mac OS X disk image containing all the needed Qt libraries and one target to install the application, which can be configured to use all the options you know from autotool-based projects (like PREFIX, BINDIR or DESTDIR, to name a few).</p>

<p>But yes, there was one task which was yet missing there &#8211; one to automatically create a Win32 installer. The steps to produce that had been so far:</p>

<ol>
<li>enter the to-be-packaged version in the InnoSetup script file</li>
<li>convert the supplied text files from Unix to DOS line endings, while giving them a .txt extension</li>
<li>call the InnoSetup compiler on the script file and create the executable</li>
</ol>

<p>Especially the first and second action looked hard to automate, given the fact that Windows does not come with a rich set of tools to process text streams &#8211; and requiring a Cygwin installation just for using <code>sed</code> seemed awkward to me. Obviously other people had similar problems before and <a href="http://stackoverflow.com/questions/127318/is-there-any-sed-like-utility-for-cmd-exe">somebody proposed</a> to emulate sed with a VBScript which would be executed by the Windows Scripting Host (WSH). Wow, cool thing &#8211; if I&#8217;d just remember my broken Visual Basic knowledge. But didn&#8217;t Microsoft have this Javascript Look-a-Like, JScript? Shouldn&#8217;t this be executable as well?</p>

<p>Apparently it was and I sat down to hack an improved JScript <code>sed</code> version:</p>

<pre><code>var patterns  = new Array();
var replacements = new Array();
var argcount = 0;

for (var i=0; i&lt;WScript.Arguments.length; ++i)
{
    pat = WScript.Arguments(i).split("/");
    if (pat.length != 4)
        continue;

    patterns[argcount] = new RegExp(pat[1]);
    replacements[argcount] = pat[2];  
    ++argcount;
}

while (!WScript.StdIn.AtEndOfStream)
{
    var line = WScript.StdIn.ReadLine();
    for (var i=0; i&lt;argcount; ++i)
    {
        line = line.replace(patterns[i], replacements[i]);
    }
    WScript.Echo(line);
}
</code></pre>

<p></p>

<p>Now the only thing what was left was to fiddle around with the WSH command line tool <code>cscript</code> and to combine everything for a proper QMake target. Here we go:</p>

<p><pre>
DOCFILES="NEWS README README.driver COPYING"
...
win32 {
    isEmpty(QTDIR):QTDIR           = "c:\Qt\4.6.2"
    isEmpty(MINGWDIR):MINGWDIR     = "c:\MinGW"
    isEmpty(OPENSSLDIR):OPENSSLDIR = "c:\OpenSSL"
    isEmpty(ISCC):ISCC = "c:\Program Files\Inno Setup 5\ISCC.exe"
&nbsp;&nbsp;&nbsp;&nbsp;
    win32setup.depends  = make_first
    win32setup.target   = win32setup
    win32setup.commands = \
        cscript //NoLogo res\win32\sed.js \
            s/@@VERSION@@/$${VERSION}/ \
            s/@@QTDIR@@/$${QTDIR}/ \
            s/@@MINGWDIR@@/$${MINGWDIR}/ \
            s/@@OPENSSLDIR@@/$${OPENSSLDIR}/ \
            &lt; res\win32\guitone.iss.in > res\win32\guitone.iss &amp;&amp; \
        ( for %%f in ($$DOCFILES) do \
            cscript //NoLogo res\win32\sed.js \
                s/\n\$$/\r\n/ \
                &lt; %%f > %%f.txt ) &amp;&amp; \
        \"$$ISCC\" res\win32\guitone.iss &amp;&amp; \
        ( for %%f IN ($$DOCFILES) do del %%f.txt )
&nbsp;&nbsp;&nbsp;&nbsp;
    QMAKE_EXTRA_TARGETS += win32setup
}
</pre></p>

<p>So if you know enough Javascript you can probably emulate whatever tool you're missing on Win32 without having to depend on any external dependency. Very cool!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/06/03/makefile-based-innosetup-automation-with-qmake/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quitting a Qt application from the Mac OS X dock</title>
		<link>http://www.thomaskeller.biz/blog/2010/05/02/quitting-a-qt-application-from-the-mac-os-x-dock/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/05/02/quitting-a-qt-application-from-the-mac-os-x-dock/#comments</comments>
		<pubDate>Sun, 02 May 2010 22:25:33 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[guitone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=626</guid>
		<description><![CDATA[So for some weird reason my application was not closable from the Mac OS X dock &#8211; it quit properly when you selected &#8220;Quit&#8221; from the application menu or hit the Cmd-Q shortcut &#8211; but the dock menu&#8217;s quit action was completely ignored. While debugging the issue I hooked into QApplication::notify(QObject *, QEvent *) and [...]]]></description>
			<content:encoded><![CDATA[<p>So for some weird reason <a href="http://guitone.thomaskeller.biz">my application</a> was not closable from the Mac OS X dock &#8211; it quit properly when you selected &#8220;Quit&#8221; from the application menu or hit the Cmd-Q shortcut &#8211; but the dock menu&#8217;s quit action was completely ignored.</p>

<p>While debugging the issue I hooked into <code>QApplication::notify(QObject *, QEvent *)</code> and noted that a <code>QCloseEvent</code> was send to my application&#8230; wait, what? A <code>QCloseEvent</code>? Yes, I also thought that these kinds of events would only be send to widgets, namely, top level widgets, but I got one for my application, and Qt plainly ignored it. So I went further ahead and tried to quit the application directly when the event occured, similar to this
<pre lang="c++">bool MyApp::event(QEvent * ev)
{
    bool eaten = false;
    switch (ev-&gt;type())
    {
        // other stuff ...
&#35;ifdef Q_WS_MAC:
        case QEvent::Close:
        {
            quit();
            eaten = true;
        }
&#35;endif
        default:
            eaten = QCoreApplication::event(ev);
            break;
    }
    return eaten;
}
</pre>
but this didn&#8217;t work out so nicely: while the application quitted correctly, the <code>quit()</code> slot was apparently called twice in a row. My guess is that Qt ignores the <code>quitOnLastWindowClosed</code> property &#8211; which I&#8217;ve set to false &#8211;  and since I close all windows in the quit slot it executes quit again, or something else, so I decided to just close all open windows when the <code>QCloseEvent</code> arrived &#8211; without calling <code>quit()</code> directly, and tada, my application quitted and the slot was also only called once. Fun times.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/05/02/quitting-a-qt-application-from-the-mac-os-x-dock/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>guitone 1.0rc3 released</title>
		<link>http://www.thomaskeller.biz/blog/2010/04/25/guitone-1-0rc3-released/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/04/25/guitone-1-0rc3-released/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 13:14:48 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[guitone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=612</guid>
		<description><![CDATA[I&#8217;m proud to announce the third release candidate of guitone 1.0. This release fixes some critical bugs and also adds support for drag&#8217;n'drop renames in the workspace amongst other minor improvements. The complete list of changes is as always listed in NEWS. A Mac OS X binary is also already available, a package for Windows [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m proud to announce the third release candidate of <a href="http://guitone.thomaskeller.biz/g/download
">guitone 1.0</a>.
This release fixes some critical bugs and also adds support for
drag&#8217;n'drop renames in the workspace amongst other minor improvements.</p>

<p>The complete list of changes is as always listed in <a href="http://guitone.thomaskeller.biz/releases/latest/NEWS">NEWS</a>. A Mac OS X
binary is also already available, a package for Windows will follow
tomorrow.</p>

<p>I&#8217;m still looking for translators &#8211; if you&#8217;re interested, please drop me
a note.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/04/25/guitone-1-0rc3-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt itemviews trouble</title>
		<link>http://www.thomaskeller.biz/blog/2010/03/31/qt-itemviews-trouble/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/03/31/qt-itemviews-trouble/#comments</comments>
		<pubDate>Wed, 31 Mar 2010 22:59:39 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=594</guid>
		<description><![CDATA[Whoever digged a little deeper into Qt&#8217;s item views and models in the past knows that they&#8217;re quite tricky beasts sometimes. Two problems where driving me nuts recently: How can I auto-expand the root node of a QTreeView whenever the view is resetted? How can I restore the expansion / root state of a QTreeView [...]]]></description>
			<content:encoded><![CDATA[<p>Whoever digged a little deeper into Qt&#8217;s item views and models in the past knows that they&#8217;re quite tricky beasts sometimes. Two problems where driving me nuts recently:</p>

<ol>
<li>How can I auto-expand the root node of a <code>QTreeView</code> whenever the view is resetted?</li>
<li>How can I restore the expansion / root state of a <code>QTreeView</code> when a model filter cleared all the items out before, effectively resetting the view as in 1.?</li>
</ol>

<p>After a lot of struggling and lots of debugging I think I found a solution for both problems, which are slightly connected.</p>

<p>To get the auto-expansion feature, I connected the <code>layoutChanged()</code> signal of the model to a timer in my view, whose <code>timeout()</code> signal then again called the following slot:</p>

<p><pre>
void MyTreeView::delayedLayoutChanged()
{
    QModelIndex index = model()->index(0, 0, QModelIndex());
    expand(index); // or alternatively: setRootIndex(index);
}
</pre></p>

<p>This simply takes the first element of the model and expands it. Why the trick with the timer? Well, apparently the <code>layoutChanged()</code> signal is already processed internally by <code>QAbstractItemView</code> or <code>QTreeView</code> and its implementation resets the view state completly &#8211; which is of course problematic if it gets executed <em>after</em> our own slot. A single-shot timer with an interval of 0 ms is enough here to make Qt use the next event loop cycle and do the right thing for us.</p>

<p>Now, things get more complex if you have a <code>QSortFilterProxyModel</code> attached to your tree view &#8211; imagine one of these fancy find-as-you-type inputs. If a user enters a search word which clears out all items from your current view and then resets the input again to see the original view, the view eventually gets a <code>layoutChanged()</code> signal as well, but because of the clearing you may have lost the expansion level in which the user was before!</p>

<p><code>QPersistentModelIndex</code> is here for the rescue. All you have to do is remember the model index you previously used to expand your view and use that instead of the static one if it is still valid:</p>

<p><pre>
QPersistentModelIndex MyTreeView::lastExpansion;
void MyTreeView::expandSomething(const QModelIndex &amp; index)
{
    lastExpansion = static_cast<const QSortFilterProxyModel *>(model())
        ->mapToSource(index);
    expand(index);
}
void MyTreeView::delayedLayoutChanged()
{
    QModelIndex index;
    // is the item still part of the source model? 
    // (important for dynamic source models)
    if (lastExpansion.isValid())
    {
        index = static_cast</const><const QSortFilterProxyModel *>(model())
              ->mapFromSource(lastExpansion);
    }
    else
    {
        index = model()->index(0, 0, QModelIndex());
    }
    expand(index); // or alternatively: setRootIndex(index);
}
</const></pre></p>

<p>While <code>QPersistentModelIndex</code> and <code>QModelIndex</code> are two distinct classes, the Trolls made them easily interchangable without special casting magic.</p>

<p>Note that you always need to save the source index and never the proxy index which might be invalidated if it is removed from the view. Things get of course even more complex if you have not one, but two proxy models which filter your view&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/03/31/qt-itemviews-trouble/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>guitone 1.0rc1 released</title>
		<link>http://www.thomaskeller.biz/blog/2010/02/15/guitone-1-0rc1-released/</link>
		<comments>http://www.thomaskeller.biz/blog/2010/02/15/guitone-1-0rc1-released/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 14:16:03 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[guitone]]></category>
		<category><![CDATA[monotone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=553</guid>
		<description><![CDATA[I&#8217;m proud to announce the immediate release of guitone-1.0rc1. This is the first release in a series of smaller releases which aims at the stabilization of the guitone codebase. Many (if not most) of the features one would consider needed for a &#8220;1.0&#8243; release have been implemented, a couple of outstanding bugs (noticable FS#39, FS#41 [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m proud to announce the immediate release of guitone-1.0rc1. This is the first release in a series of smaller releases which aims at the stabilization of the guitone codebase. Many (if not most) of the features one would consider needed for a &#8220;1.0&#8243; release have been implemented, a couple of outstanding bugs (noticable <a href="https://guitone.thomaskeller.biz/flyspray/index.php?do=details&#038;task_id=39&#038;project=2&#038;status%5B0%5D=open">FS#39</a>, <a href="https://guitone.thomaskeller.biz/flyspray/index.php?do=details&#038;task_id=41&#038;project=2&#038;status%5B0%5D=open">FS#41</a> and
<a href="https://guitone.thomaskeller.biz/flyspray/index.php?do=details&#038;task_id=42&#038;project=2&#038;status%5B0%5D=open">FS#42</a>) have to get fixed beforehand though before that happens. Please test and <a href="https://guitone.thomaskeller.biz/g/tracker">report bugs</a> if possible.</p>

<p>Outstanding news of this release:</p>

<ul>
<li>Synchronization with other monotone nodes is no possible</li>
<li>Workspace action implementation almost feature-complete (add, drop, revert, rename, ignore, unignore and update finally work)</li>
<li>guitone can now create new monotone databases and setup new projects</li>
<li>Much improved key management with the ability to change the passphrase of keys, filter the key output and also drop keys</li>
<li>Many more bugfixes and smaller improvements as well as stabilization of the codebase</li>
</ul>

<p>For a complete list of changes please check the <a href="https://guitone.thomaskeller.biz/releases/latest/NEWS">NEWS</a> file. I&#8217;ll try and prepare a Windows binary in the next couple of days, but probably won&#8217;t get to that before Wednesday, so if you want to help out, drop me
a note. A binary for Mac OS X should arrive shortly as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2010/02/15/guitone-1-0rc1-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SSL Verification with Qt and a custom CA certificate</title>
		<link>http://www.thomaskeller.biz/blog/2009/01/03/ssl-verification-with-qt-and-a-custom-ca-certificate/</link>
		<comments>http://www.thomaskeller.biz/blog/2009/01/03/ssl-verification-with-qt-and-a-custom-ca-certificate/#comments</comments>
		<pubDate>Sat, 03 Jan 2009 00:30:26 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Free Software]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=304</guid>
		<description><![CDATA[So I wanted to make my application updater for guitone SSL-aware the other day. The server setup was an easy job: Add the new domain (guitone.thomaskeller.biz) to cacert.org, create a new certificate request with the new SubjectAltName (and all the other, existing alternative names &#8211; a procedure where this script becomes handy), upload to CAcert, [...]]]></description>
			<content:encoded><![CDATA[<p>So I wanted to make my application updater for guitone SSL-aware the other day. The server setup was an easy job: Add the new domain (guitone.thomaskeller.biz) to <a href="http://www.cacert.org">cacert.org</a>, create a new certificate request with the new SubjectAltName (and all the other, existing alternative names &#8211; a procedure where <a href="http://adam.shand.net/iki/2007/The_Easy_Way_To_Generate_OpenSSL_CSRs_with_subjectAltNames/">this script</a> becomes handy), upload to CAcert, sign it there, download and install the new cert on my server, setup a SSL vhost for the domain &#8211; done!</p>

<p>Now, on Qt&#8217;s side of things using SSL is rather easy as well, the only thing you have to do is give the <code>setHost</code> method another parameter:
<pre>QHttp * con = new QHttp();
con-&gt;setHost("some.host.com", <strong>QHttp::ConnectionModeHttps</strong>);
con-&gt;get("/index.html");
// connect to QHttp's done() signal and read the response</pre>
This should actually work for all legit SSL setups <em>if</em> Qt (or, to be more precise, the underlying openssl setup) knows about the root certificate with which your server certificate has been signed. Unfortunately, CAcert&#8217;s root certificate is not installed in most cases, so you basically have two options:</p>

<ol>
    <li>Connect to QHttp&#8217;s <code>sslErrors(...)</code> signal to the <code>QHttp::ignoreSslErrors()</code> slot. This, of course, pretty much defeats the whole purpose of an SSL connection, because the user is not warned on any SSL error, so also legit errors (certificate expired or malicious) are just ignored. (*)</li>
    <li>Make the <a href="http://cacert.org/certs/root.crt">root certificate of CAcert</a> known to the local setup, so the verification process can proceed properly.</li>
</ol>

<p>I decided to do the latter thing. This is how the code should now look like:
<pre>QHttp * con = new QHttp();
<strong>QFile certFile("path/to/root.crt");
Q_ASSERT(certFile.open(QIODevice::ReadOnly));
QSslCertificate cert(&amp;certFile, QSsl::Pem);
</strong><strong></strong><strong>// this replaces the internal QTcpSocket QHttp uses; unfortunately
// we cannot reuse that one because Qt does not provide an accessor
// for it
</strong><strong>QSslSocket * sslSocket = new QSslSocket(this);
sslSocket-&gt;addCaCertificate(cert);
httpConnection-&gt;setSocket(sslSocket);</strong>
con-&gt;setHost("some.host.com", QHttp::ConnectionModeHttps);
con-&gt;get("/index.html");
// connect to QHttp's done() signal and read the response</pre>
Particularily interesting to note here is that the <code>QIODevice</code> (in my case the <code>QFile</code> instance) has to be opened explicitely before it is given to <code>QSslCertificate</code>. I did not do this previously, Qt neither gave me a warning nor an error, but simply refused to verify my server certificate, just because it didn&#8217;t load the root certificate properly.</p>

<p><small>(*) One could, of course, check the exact triggered SSL error from <code>QSslError::error()</code>, in our case this could be f.e. <code>QSslError::UnableToGetLocalIssuerCertificate</code>, but this is rather hacky and could certainly be abused by a man in the middle as well.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2009/01/03/ssl-verification-with-qt-and-a-custom-ca-certificate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt Creator</title>
		<link>http://www.thomaskeller.biz/blog/2008/11/01/qt-creator/</link>
		<comments>http://www.thomaskeller.biz/blog/2008/11/01/qt-creator/#comments</comments>
		<pubDate>Sat, 01 Nov 2008 02:19:26 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=280</guid>
		<description><![CDATA[Wow, I absolutely did not see this coming &#8211; finally the Trolls^WNokians offer a lean and nice cross-platform IDE for Qt which incorporates all other Qt tools and a gdb frontend! Formerly dubbed &#8220;Project Greenhouse&#8221; the baby just got a new name and fancy logo: Qt Creator. There is a pre-release version available for download, [...]]]></description>
			<content:encoded><![CDATA[<p>Wow, I absolutely did not see this coming &#8211; finally the Trolls^WNokians offer a lean and nice cross-platform IDE for Qt which incorporates all other Qt tools and a gdb frontend! Formerly dubbed &#8220;Project Greenhouse&#8221; the baby just got a new name and fancy logo: Qt Creator. There is a pre-release version available for <a href="http://trolltech.com/developer/qt-creator">download</a>, licensed under a special preview license. The final product should be dual-licensed though, like the rest of the Qt tools are.</p>

<p>Oh what a happy day for Qt users (ever wanted to look at the <em>value</em> of a QString in gdb&#8230;?) and what a sad one for all the other free Qt IDEs out there, like <a href="http://edyuk.org">edyuk</a> or <a href="http://qdevelop.org">QDevelop</a>. Especially edyuk looked very promising since it provided a lot of features and a good user interface.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2008/11/01/qt-creator/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Qt Framework introduction</title>
		<link>http://www.thomaskeller.biz/blog/2008/08/14/qt-framework-introduction/</link>
		<comments>http://www.thomaskeller.biz/blog/2008/08/14/qt-framework-introduction/#comments</comments>
		<pubDate>Thu, 14 Aug 2008 20:41:03 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[Work]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=163</guid>
		<description><![CDATA[I did a small workshop on Qt today in my company, mainly to introduce the framework to my fellow developers. I think I did a good job, because I&#8217;ve seen the glow in their eyes while presenting the graphics view demos and the 2d paint engine amongst many other things. Anyways, if you&#8217;re interested in [...]]]></description>
			<content:encoded><![CDATA[<p>I did a small workshop on Qt today <a href="http://www.itcampus.eu">in my company</a>, mainly to introduce the framework to my fellow developers. I think I did a good job, because I&#8217;ve seen the glow in their eyes while presenting the graphics view demos and the 2d paint engine amongst many other things.</p>

<p>Anyways, if you&#8217;re interested in Qt as well and want to get a short (German) introduction, snag the workshop slides from the <a href="/blog/stuff/">Stuff page</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2008/08/14/qt-framework-introduction/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>guitone 0.8 released &#8211; spring time is hacking time!</title>
		<link>http://www.thomaskeller.biz/blog/2008/05/25/guitone-08-released-spring-time-is-hacking-time/</link>
		<comments>http://www.thomaskeller.biz/blog/2008/05/25/guitone-08-released-spring-time-is-hacking-time/#comments</comments>
		<pubDate>Sun, 25 May 2008 20:08:24 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Qt]]></category>
		<category><![CDATA[guitone]]></category>
		<category><![CDATA[monotone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=71</guid>
		<description><![CDATA[guitone 0.8 has been released today. Major improvements happened under the hood, the outstanding changes are: guitone is now licensed under GNU GPL Version 3 or later. Please note that you&#8217;re now only allowed to legally distribute binaries which you&#8217;ve built with Qt 4.3.4 or later, since earlier versions of Qt are GPLv2-only new &#8220;driver&#8221; interface to call [...]]]></description>
			<content:encoded><![CDATA[<p>guitone 0.8 has been released today. Major improvements happened under the hood, the outstanding changes are:</p>

<ul>
    <li>guitone is now licensed under GNU GPL Version 3 or later. Please note that you&#8217;re now only allowed to legally distribute binaries which you&#8217;ve built with Qt 4.3.4 or later, since earlier versions of Qt are GPLv2-only</li>
    <li>new &#8220;driver&#8221; interface to call certain dialogs of guitone from the outside, which should help for all sorts of integration wishes ondifferent platforms. A &#8220;TortoiseMonotone&#8221; project has already been kicked off at the last summit &#8211; currently residing on the <a href="http://viewmtn.angrygoats.net/branch/changes/net.venge.monotone.tortoise">net.venge.monotone.tortoise</a> branch - and this project is still looking for help from people which are fluent in Python and / or the Windows API</li>
    <li>numerous improvement in workspace handling (faster, prettier, more configurable, yatta, yatta&#8230;)</li>
    <li>for a full list of changes check the <a href="http://guitone.thomaskeller.biz/count.php/from=default/0.8/NEWS">NEWS file</a></li>
</ul>

<p>You can download guitone at the <a href="http://guitone.thomaskeller.biz/g/download">usual location</a>, a win32 installer (yes, we&#8217;ll have one!) should follow shortly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2008/05/25/guitone-08-released-spring-time-is-hacking-time/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hide Qt GUI applications from the Mac OS X dock and menu</title>
		<link>http://www.thomaskeller.biz/blog/2008/05/07/hide-qt-gui-applications-from-the-mac-os-x-dock-and-menu/</link>
		<comments>http://www.thomaskeller.biz/blog/2008/05/07/hide-qt-gui-applications-from-the-mac-os-x-dock-and-menu/#comments</comments>
		<pubDate>Wed, 07 May 2008 12:56:26 +0000</pubDate>
		<dc:creator>Thomas Keller</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[guitone]]></category>

		<guid isPermaLink="false">http://www.thomaskeller.biz/blog/?p=66</guid>
		<description><![CDATA[Starting with Qt 4.4 which was released a few days ago Qt now honors the &#60;key&#62;LSUIElement&#60;/key&#62; &#60;string&#62;1&#60;/string&#62; setting in the Info.plist file of the application bundle. This is particularily useful to create bundled application which should not pop up in the global dock or menu, f.e. daemons which run in the background or applications like [...]]]></description>
			<content:encoded><![CDATA[<p>Starting with Qt 4.4 which was <a href="http://trolltech.com/company/newsroom/announcements/press.2008-05-02.5256347247" target="_blank">released a few days ago</a> Qt now honors the
<pre>&lt;key&gt;LSUIElement&lt;/key&gt;
&lt;string&gt;1&lt;/string&gt;</pre>
setting in the Info.plist file of the application bundle. This is particularily useful to create bundled application which should not pop up in the global dock or menu, f.e. daemons which run in the background or applications like <a href="http://www.blacktree.com/" target="_blank">Quicksilver</a> which are only accessible via a global key stroke or an icon in systray area of the menu bar.</p>

<p>Now, with guitone I recently had the problem that I wanted exactly this mode under OSX in its new &#8220;driver&#8221; mode, which lets you automate / script the access to internal dialogs (check the <a href="http://viewmtn.angrygoats.net/branch/changes/net.venge.monotone.guitone.app-driver" target="_blank">nvm.guitone.app-driver</a> branch for more information), but it should not interfere with the &#8220;standalone&#8221; mode, i.e. the dock icon and menu bar should be of course shown there.</p>

<dl>
<dt>One way of accomplishing that would have been to create a separate binary just for this usage and only set the setting in this property list. However, even without knowing much of OSX&#8217; Carbon API, I came up with a better solution, inspired by what Qt does itself deep inside qapplication_mac.cpp if it stumbles upon the LSUIElement entry:</dt>
<dt><pre>GuitoneStandalone::GuitoneStandalone(int &amp; argc, char** argv)</pre></dt>
<dd>GuitoneCore(argc, argv),
{</dd>
</dl>

<h1>ifdef Q_WS_MACX</h1>

<p>ProcessSerialNumber psn;
if (GetCurrentProcess(&amp;psn) == noErr)
{
TransformProcessType(&amp;psn,
kProcessTransformToForegroundApplication);
}</p>

<h1>endif</h1>

<p>...
}
This unconditionally transforms such a background application to a foreground application with a dock icon and menu bar. So all I had to do was to check my calling arguments if the driver interface should be used and if not, create the correct QApplication instance which brings the application to the foreground. Nice!</p>

<p>Now I only have to fix this one, very weird behaviour of QMetaMethod::invokeMethod which does not accept my argument list&#8230; <em>grumbles</em></p>
]]></content:encoded>
			<wfw:commentRss>http://www.thomaskeller.biz/blog/2008/05/07/hide-qt-gui-applications-from-the-mac-os-x-dock-and-menu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
