<?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>Pontus Östlund &#187; Gnome</title>
	<atom:link href="http://www.poppa.se/blog/tag/gnome/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.poppa.se/blog</link>
	<description>My blog about web development and such</description>
	<lastBuildDate>Mon, 16 Jan 2012 00:38:45 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>GTK TreeViewColumn with icon and text</title>
		<link>http://www.poppa.se/blog/gtk-treeviewcolumn-with-both-icon-and-text-in-the-same-column/</link>
		<comments>http://www.poppa.se/blog/gtk-treeviewcolumn-with-both-icon-and-text-in-the-same-column/#comments</comments>
		<pubDate>Mon, 21 Nov 2011 20:18:51 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[CellRenderer]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[GTK]]></category>
		<category><![CDATA[GTK3]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[TreeViewColumn]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=534</guid>
		<description><![CDATA[
The other day I wanted to put both an icon and text in the same GTK+ TreeViewColumn, and I had absolutely no idea how to do that. So I Google&#8217;d and Google&#8217;d but had trouble finding any examples. I even downloaded the source code of the Gnome System Monitor &#8211; where exactly what I wanted [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/blog/data/images/gtk-tvcol.png"><img src="/blog/data/images/gtk-tvcol.png/680" alt="TreeViewColumn with icon and text" /></a></p>
<p>The other day I wanted to put both an icon and text in the same <a href="http://www.gtk.org/">GTK+</a> <code>TreeViewColumn</code>, and I had absolutely no idea how to do that. So I Google&#8217;d and Google&#8217;d but had trouble finding any examples. I even downloaded the <a href="https://code.launchpad.net/gnome-system-monitor">source code</a> of the <a href="http://library.gnome.org/users/gnome-system-monitor/stable/">Gnome System Monitor</a> &#8211; where exactly what I wanted exist &#8211; but that was mostly written in C++ which I know very little of. </p>
<p>But I&#8217;m stubborn, and after a while I found and example in <a href="http://python.org/">Python</a> which I managed to interpret. Even though I know very little Python it&#8217;s not that hard to follow, and the example was short.</p>
<p>In short what&#8217;s needed is packing two <code>CellRenderer</code>s in the same <code>TreeViewColumn</code>. Quite logical when you know about it. The example below is in <a href="http://live.gnome.org/Vala">Vala</a>:</p>
<pre><code lang="vala">
var tree_view = new TreeView ();

var col = new TreeViewColumn ();
col.title = title;
col.resizable = true;

var crp = new CellRendererPixbuf ();
col.pack_start (crp, false);
col.add_attribute (crp, "pixbuf", 0);

var crt = new CellRendererText ();
col.pack_start (crt, false);
col.add_attribute (crt, "text", 1);

tree_view.insert_column (col, -1);
</code></pre>
<p>I hacked up a simple application that shows all installed programs &#8211; that has a <code>.desktop</code> entry I guess &#8211; in a list (the screenshot above). The sources is available at my <a href="https://github.com/poppa/PlayStation/tree/master/Vala/Gtk3/treeview-with-pixbuf">Github repository</a>.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/gtk-treeviewcolumn-with-both-icon-and-text-in-the-same-column/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Roxen Application Launcher 1.0.3</title>
		<link>http://www.poppa.se/blog/roxen-application-launcher-1-0-3/</link>
		<comments>http://www.poppa.se/blog/roxen-application-launcher-1-0-3/#comments</comments>
		<pubDate>Thu, 23 Sep 2010 23:35:49 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Roxen]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[KDE]]></category>
		<category><![CDATA[Pike]]></category>
		<category><![CDATA[RAL]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=473</guid>
		<description><![CDATA[
In this release of Roxen Application Launcher (come again?) for Linux I&#8217;ve gotten rid of a few dependencies, namely: gconf, libgee and libgnome. The reason I dumped gconf and libgnome was to make it easier to install in KDE. I&#8217;ve verified it installs in KDE, although I noticed the translation doesn&#8217;t work and the Roxen [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/blog/data/images/ral-103.png" class="no-file"><img src="/blog/data/images/ral-103.png/680" alt="Screenshot of Roxen Application Launcher" /></a></p>
<p>In this release of <a href="http://www.roxen.com">Roxen</a> Application Launcher (<a href="/blog/stuff/#roxen-applauncher">come again?</a>) for <a href="http://www.linux.com/">Linux</a> I&#8217;ve gotten rid of a few dependencies, namely: gconf, libgee and libgnome. The reason I dumped gconf and libgnome was to make it easier to install in KDE. I&#8217;ve verified it installs in KDE, although I noticed the translation doesn&#8217;t work and the Roxen SVG logo doesn&#8217;t show up in the window top border. </p>
<p><a href="/blog/data/images/ral-kde.png" class="no-file"><img src="/blog/data/images/ral-kde.png/680" alt="Screenshot of Roxen Application Launcher" /></a><br />
<em>Roxen Application Launcher in KDE</em></p>
<p>Libgee is a collections API written in Vala and since I used a newer version than what is available in most package managers, and I&#8217;m not sure all Linux distros provide libgee, I decided to dump it and implement the same functionality with the generic collection classes in Vala. And since the collections used in RAL is quite simple that worked out just fine. </p>
<p>I have also tried to implement bundled download, which is only used in Roxen Editorial Portal. Since I don&#8217;t have access to such an installation I haven&#8217;t been able to verify it works as expected. I re-implemented the same behavior as in the launcher written in Pike by the Roxen guys.</p>
<p>Oh, and if you already have an installation of my RAL your previously downloaded files and settings will not be available to the new install. Since I dumped gconf I now store the settings in a plain text file and I have put the RAL application directory in <code>~/.conf/roxenlauncher</code> since <code>~/.conf</code> is where you should put application specific data according to <a href="http://freedesktop.org">freedesktop.org</a>. In previous versions of RAL I stored application data in <code>~/.roxenlauncher</code> so if you want your previously downloaded files copy <code>~/.roxenlauncher/files</code> to <code>~/.conf/roxenlauncher/files</code>.</p>
<p>The sources is available at <a href="http://github.com/poppa/Roxen-Application-Launcher">Github</a>.</p>
<p><a href="/blog/data/roxenlauncher-1.0.3.tar.gz">Roxen Appliction Launcher 1.0.3</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/roxen-application-launcher-1-0-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Roxen Application Launcher 1.0</title>
		<link>http://www.poppa.se/blog/roxen-application-launcher-1-0/</link>
		<comments>http://www.poppa.se/blog/roxen-application-launcher-1-0/#comments</comments>
		<pubDate>Sun, 12 Sep 2010 09:16:30 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Roxen]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[GTK]]></category>
		<category><![CDATA[RAL]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=467</guid>
		<description><![CDATA[
So I had a go at the Roxen Application Launcher (come again?) for Linux. I added a context menu &#8211; when you right click &#8211; to the file list. When you right click a file in the list you get the option to view that file in the Sitebuilder, edit it or remove it.
Other than [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/blog/data/images/ral-1.0.png" class="no-file"><img src="/blog/data/images/ral-1.0.png/680" alt="Screenshot of Roxen Application Launcher with context menu" /></a></p>
<p>So I had a go at the <a href="http://www.roxen.com">Roxen</a> Application Launcher (<a href="/blog/stuff/#roxen-applauncher">come again?</a>) for <a href="http://www.linux.com/">Linux</a>. I added a context menu &#8211; when you right click &#8211; to the file list. When you right click a file in the list you get the option to view that file in the Sitebuilder, edit it or remove it.</p>
<p>Other than that there&#8217;s nothing new. And since the application seems to be very stable I decided to bump the version number to 1.0.</p>
<p>The sources is available at <a href="http://github.com/poppa/Roxen-Application-Launcher">Github</a>.</p>
<p><a href="/blog/data/roxenlauncher-1.0.tar.gz">Roxen Appliction Launcher 1.0</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/roxen-application-launcher-1-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Roxen Application Launcher 0.4.5</title>
		<link>http://www.poppa.se/blog/roxen-application-launcher-0-4-5/</link>
		<comments>http://www.poppa.se/blog/roxen-application-launcher-0-4-5/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 21:52:52 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Roxen]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[RAL]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=421</guid>
		<description><![CDATA[
Okey, here comes an update of my Roxen Application Launcher (come again?) for Linux. 
There&#8217;s no major changes to this release. The connection to the Roxen server is now stored in a shared object so that it can use a &#8220;keep-alive&#8221; connection. Not that I think it matters a great deal.
There&#8217;s now an option to [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/blog/data/images/ral-045.jpg" class="no-file"><img src="/blog/data/images/ral-045.jpg/680" alt="Screenshot of Roxen Application Launcher" /></a></p>
<p>Okey, here comes an update of my <a href="http://roxen.se">Roxen</a> Application Launcher (<a href="/blog/stuff/#roxen-applauncher">come again?</a>) for <a href="http://www.linux.com/">Linux</a>. </p>
<p>There&#8217;s no major changes to this release. The connection to the Roxen server is now stored in a shared object so that it can use a &#8220;keep-alive&#8221; connection. Not that I think it matters a great deal.</p>
<p>There&#8217;s now an option to change the behavior of the applications window close button so that it hides the application to the tray &#8211; or notification area as it&#8217;s called in <a href="http://gnome.org">Gnome</a> &#8211; rather than closes the application. </p>
<p>More <a href="http://live.gnome.org/Vala">Vala</a> programming to the people &#8211; <a href="http://github.com/poppa/Roxen-Application-Launcher">Sources at Github</a>.</p>
<p><a href="/blog/data/roxenlauncher-0.4.5.tar.gz">Roxen Appliction Launcher 0.4.5</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/roxen-application-launcher-0-4-5/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>GTK hacking in Pike</title>
		<link>http://www.poppa.se/blog/gtk-hacking-in-pike/</link>
		<comments>http://www.poppa.se/blog/gtk-hacking-in-pike/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 23:40:59 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[GTK]]></category>
		<category><![CDATA[Pike]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=386</guid>
		<description><![CDATA[I&#8217;ve found out that it&#8217;s great fun programming desktop applications and of course it gets more fun the more you learn. Now I&#8217;m doing a Twitter client in Pike &#8211; my favorite programming language &#8211; mostly because I wanted to try out GTK programming in Pike. I use the good Twitter client Pino &#8211; written [...]]]></description>
			<content:encoded><![CDATA[<p><a href="/blog/data/images/tweepi.jpg" class="no-file"><img src="/blog/data/images/tweepi.jpg/220" class="alignright" alt="Tweepi, the Twitter client written in Pike" /></a>I&#8217;ve found out that it&#8217;s great fun programming desktop applications and of course it gets more fun the more you learn. Now I&#8217;m doing a <a href="http://twitter.com">Twitter</a> client in <a href="http://pike.ida.liu.se">Pike</a> &#8211; my favorite programming language &#8211; mostly because I wanted to try out <a href="http://www.gtk.org/">GTK</a> programming in Pike. I use the good Twitter client <a href="http://pino-app.appspot.com/">Pino</a> &#8211; written in <a href="http://live.gnome.org/Vala/">Vala</a> &#8211; and I have borrowed the concept and layout from it. I call it <strong>Tweepi</strong>.</p>
<p>The only major difference between Tweepi and Pino &#8211; besides they are written in different programming languages &#8211; is that Pino uses WebKit to draw the status messages where I am using good old GTK widgets &#8211; and I guess there are no bindings to WebKit in Pike for that matter <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>One thing I noticed is that the <code>Gtk.Label</code> widget sucks at displaying longer texts that line wraps. Since the label widget handles some HTML formatting I thought that it would be suitable for displaying the status messages, but the text looked like shit, line wrapping where ever it felt like. And the <code>Gtk.TextView</code> widget doesn&#8217;t handle formatting per default so I Googled some and found that you can format text in <code>Gtk.TextView</code>s by inserting <code>Gtk.TextTag</code>s at desired positions. And since Pike has the most awesome HTML parser It was just a matter of sending the text through the parser and create some <code>Gtk.TextTag</code>s and inserting them at the same position in the text buffer. (Well, actually it wasn&#8217;t that easy but with some help from a Python class I found on the web it was doable).</p>
<p>So now I have a start at something that is a <code>Gtk.HtmlTextView</code> &#8211; actually it inherits <code>Gtk.TextView</code> but has an additional method <code>insert_html_text(string text)</code> &#8211; and albeit quite simple at the moment it&#8217;s worth continuing on. The code for the <code>HtmlTextView</code> is available at my <a href="http://github.com/poppa/Pike-Modules/blob/master/Misc.pmod/GTK2.pmod/module.pmod">Github repository</a>.</p>
<p>In general I find the GTK implementation in Pike to be pretty OK, but there exist some verbose, and tedious, stuff like getting the text from a <code>Gtk.TextView</code>: </p>
<pre><code lang="pike">
Gtk.TextBuffer b = my_textview->get_buffer();
string text = b->get_text(b->get_start_iter(), b->get_end_iter(), 0);
</code></pre>
<p>which in Vala and C# would be done like:</p>
<pre><code lang="vala">
// Vala
string text = my_textview.get_buffer().text;

// C#
string text = myTextView.Buffer.Text;
</code></pre>
<p>Anyway! Tweepi isn&#8217;t done yet but I think I have solved the most tedious stuff and it&#8217;s starting to become useful. It&#8217;ll probably be done in a couple of weeks and I will of course release the sources then.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/gtk-hacking-in-pike/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Roxen Application Launcher 0.4.4</title>
		<link>http://www.poppa.se/blog/roxen-application-launcher-0-4-4/</link>
		<comments>http://www.poppa.se/blog/roxen-application-launcher-0-4-4/#comments</comments>
		<pubDate>Wed, 13 Jan 2010 22:58:28 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Roxen]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[GTK]]></category>
		<category><![CDATA[RAL]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=368</guid>
		<description><![CDATA[So, here&#8217;s a new release of the Roxen Application Launcher for Linux (RAL). The previous versions used my home made (sloppy so) HTTP client which didn&#8217;t handle redirects or secure connections &#8211; thank you tec for the feed back &#8211; since I had some major problems getting libsoup working with binary files like images and [...]]]></description>
			<content:encoded><![CDATA[<p>So, here&#8217;s a new release of the Roxen Application Launcher for Linux (RAL). The previous versions used my home made (sloppy so) HTTP client which didn&#8217;t handle redirects or secure connections &#8211; thank you <a href="/blog/new-roxen-application-launcher-for-linux-written-in-vala/#comments">tec</a> for the feed back &#8211; since I had some major problems getting <code>libsoup</code> working with binary files like images and such. Binary files was heavily scrambled when read from or written to disk so I made my own simple HTTP client that kept the data as a byte array to prevent some underlying libraries (GLib) from fiddling with it.</p>
<p>But I solved the <code>libsoup</code> issue so now the RAL handles redirects and secure connections. This is how I solved it:</p>
<h2>The <code>libsoup</code> issue</h2>
<p>When uploading a file back to the <a href="http://roxen.com">Roxen</a> server I use <code>IOChannel (g_io_channel in plain C)</code> instead of <code>Gio</code>. So the upload works like this:</p>
<pre><code lang="vala">
var sess = new Soup.SessionSync();
var mess = new Soup.Message("PUT", get_uri());
mess.request_headers.append("Cookie", get_cookie());
mess.request_headers.append("Translate", "f");

IOChannel ch = new IOChannel.file(local_file, "r");
ch.set_encoding(null); // Enables reading of binary data
string data;
size_t len;
ch.read_to_end(out data, out len);

mess.request_body.append(Soup.MemoryUse.COPY, data, len);
sess.send_message(mess);
</code></pre>
<p>And that seems to work like a charm!</p>
<p>When downloading data it&#8217;s a bit more tricky! Of course I tried using <code>IOChannel</code> in this case also but that made no difference. Downloaded images ended up 4 bytes long! But then I thought: You can make your own C bindings in Vala (remember the Vala compiler generates C code) through what is called Vapi files. So what I did was writing a C function that takes a <code>SoupMessageBody</code> object/struct passed from Vala and writes the data part to a file given as argument.</p>
<pre><code lang="cpp">
gboolean save_soup_data(SoupMessageBody *data, const char *file)
{
  FILE *fh;

  if ((fh = fopen(file, "w")) == NULL) {
    fprintf(stderr, "Unable to open file \"%s\" for writing!\n", file);
    return FALSE;
  }

  int wrote = fwrite(data->data, 1, data->length, fh);

  if (wrote != (int)data->length) {
    fprintf(stderr, "wrote (%d) != data->length (%d). Data may have been "
                    "truncated", wrote, (int)data->length);
  }

  fclose(fh);
  return TRUE;
}
</code></pre>
<p>And this was then made available to Vala by the following Vapi file:</p>
<pre><code lang="vala">
[CCode (cprefix = "", lower_case_cprefix = "", cheader_filename = "")]
namespace Soppa // Soppa is Swedish for Soup <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />
{
  [CCode (cname = "save_soup_data")]
  public bool save_soup_data(Soup.MessageBody data, string file);
}
</code></pre>
<p>And this is how the actual Vala code downloading the files looks like:</p>
<pre><code lang="vala">
var sess = new Soup.SessionSync();
var mess = new Soup.Message("GET", get_uri());
mess.request_headers.append("Cookie", get_cookie());
mess.request_headers.append("Translate", "f");
sess.send_message(mess);

if (mess.status_code == Soup.KnownStatusCode.OK) {
  // Here I call the C function made available through the Vapi file
  if (Soppa.save_soup_data(mess.response_body, local_file)) {
    message("The file was downloaded and written to disk OK");
  }
  else {
    message("Failed writing data to disk!");
  }
}
</code></pre>
<p>So that&#8217;s that on that! <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h2>The notification</h2>
<p><img src="/blog/data/images/libnotify.png" class="alignright"/> I also &#8211; just for fun &#8211; implemented a notification mechanism through <code>libnotify</code>. Since I believe that can be rather annoying it&#8217;s not activated by default but can easily be activated by a checkbox in the user interface.</p>
<h2>The packages</h2>
<p>The Roxen Application Launcher for Linux can be downloaded at the <a href="http://github.com/poppa/Roxen-Application-Launcher/downloads"><strong>download page</strong></a> at <a href="http://github.com">Github</a> where also the <a href="http://github.com/poppa/Roxen-Application-Launcher"><strong>work in progress sources</strong></a> is available or downloaded below!</p>
<p><a href="/blog/data/roxenlauncher-0.4.4.tar.gz">Roxen Application Launcher 0.4.4</a></p>
<p>Stay black!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/roxen-application-launcher-0-4-4/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Bitlyfier &#8211; A Bit.ly client for GNOME</title>
		<link>http://www.poppa.se/blog/bitlyfier-a-bit-ly-client-for-gnome/</link>
		<comments>http://www.poppa.se/blog/bitlyfier-a-bit-ly-client-for-gnome/#comments</comments>
		<pubDate>Wed, 06 Jan 2010 23:46:14 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=333</guid>
		<description><![CDATA[ For those of us tweeting &#8211; or sharing web addresses in general &#8211; these long addresses with extensive query strings you wan&#8217;t to share isn&#8217;t too user friendly. So we have Bit.ly, among others, that lets you shorten a URL &#8211; or give it an alias if you like &#8211; and also gives you [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/blog/data/images/bitlyfier/bitlyfier-about.png" alt="Bitlyfier" class="alignright nobg"/> For those of us tweeting &#8211; or sharing web addresses in general &#8211; these long addresses with extensive query strings you wan&#8217;t to share isn&#8217;t too user friendly. So we have <a href="http://bit.ly">Bit.ly</a>, among others, that lets you shorten a URL &#8211; or give it an alias if you like &#8211; and also gives you statistics on how many clicks it has and if it&#8217;s shared on Twitter and what not. </p>
<p>Since I&#8217;m on the quest of learning the programming language <a href="http://live.gnome.org/Vala/">Vala</a> I though why not making a Bit.ly desktop client for <a href="http://gnome.org/">GNOME</a>. So I did!</p>
<h2>The desktop client</h2>
<p>There&#8217;s really nothing extraordinary about it, in fact it&#8217;s quite simple. Put a long URL in the input field and hit &#8220;OK&#8221;. You&#8217;ll get the shortened URL back in the same input field.</p>
<p><em>NOTE! The screenshots is showing the Swedish translation but the interface is orginally in English.</em></p>
<p><em><small>Shortening a long URL</small></em><br />
<img src="/blog/data/images/bitlyfier/bitlyfier-2.png" alt="Shortening an URL with Bitlyfier" /></p>
<p><em><small>The shortened URL</small></em><br />
<img src="/blog/data/images/bitlyfier/bitlyfier-3.png" alt="The Bit.ly shortened URL" /></p>
<p>To use the application you will of course need a Bit.ly account. The first time Bitlyfier is launched it will ask for your Bit.ly account settings. Just fill in your username and API key (it&#8217;s found on your account page at <a href="http://bit.ly/account">http://bit.ly/account</a>).</p>
<p><em><small>Bitlyfier account settings</small></em><br />
<img src="/blog/data/images/bitlyfier/bitlyfier-settings.png" alt="The bitlyfier settings dialog" /></p>
<h2>The command line interface</h2>
<p>For the hacker you, Bitlyfier can also be used as a command line tool. These are the options:</p>
<pre><code lang="none">
Usage:
  bitlyfier [OPTION...] - Bitlyfier, URL shortener/expander

Help Options:
  -h, --help        Show help options

Application Options:
  -e, --expand      Expands the given URL
  -s, --shorten     Shortens the given URL
  -n, --no-gui      Sets the application in command line mode
  -g, --gconf       Invokes setting username and apikey
</code></pre>
<p>NOTE! You should quote the value of the &#8216;-s&#8217; flag. If the URL to be shortened<br />
contains a querystring with ampersands the URL will be truncated if it&#8217;s not<br />
quoted. </p>
<p>So to shorten a long URL do like:</p>
<pre>  user@machine:~$ bitlyfier -n -s "http://domain.com/long/url/to/shorten"</pre>
<h2>The Vala Bitly API classes</h2>
<p>The Bitly API class I&#8217;ve written can of course be used standalone (it&#8217;s located in <code><a href="http://bit.ly/4DsuVg">src/bitly.vala</a></code> in the sources package downloadable below). Here&#8217;s an example of usage:</p>
<pre><code lang="vala">
// main.vala
// Compile: valac --pkg gee-1.0 --pkg json-glib-1.0 --pkg libsoup-2.4 -o main

int main(string[] argv)
{
  Bitly.Api api = new Bitly.Api("username", "R_the_api_key");
  Bitly.Response response = api.shorten("http://domain.com/the/long/url");
  stdout.printf("Short URL: %s\n", response.get_string("shortUrl"));

  response = api.stats("A2ma2z");
  stdout.printf("Clicks: %d\n", response.get_integer("clicks"));

  return 0;
}
</code></pre>
<p>More about the Bit.ly API and what the API methods do can be read about at <a href="http://bit.ly/6HIqjS">http://bit.ly/6HIqjS</a>.</p>
<h2>The sources</h2>
<p>The development sources of this application is available at <a href="http://bit.ly/7QFHvC"><strong>Bitlyfier at Github</strong></a>. The current stable release can be found at the <a href="http://github.com/poppa/Bitlyfier/downloads"><strong>Download page</strong></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/bitlyfier-a-bit-ly-client-for-gnome/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>New Roxen Application Launcher for Linux written in Vala</title>
		<link>http://www.poppa.se/blog/new-roxen-application-launcher-for-linux-written-in-vala/</link>
		<comments>http://www.poppa.se/blog/new-roxen-application-launcher-for-linux-written-in-vala/#comments</comments>
		<pubDate>Sun, 20 Dec 2009 20:21:04 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Roxen]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[RAL]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=301</guid>
		<description><![CDATA[A couple of weeks ago I stumbled upon a fairly new programming language named Vala. I thought it looked promising and since Vala is developed by the GNOME project &#8211; with the purpose of making software development for, primarily, GNOME easier &#8211; and I&#8217;m an avid GNOME user I wanted to look deeper into the [...]]]></description>
			<content:encoded><![CDATA[<p>A couple of weeks ago I stumbled upon a fairly new programming language named <a href="http://live.gnome.org/Vala/">Vala</a>. I thought it looked promising and since Vala is developed by the <a href="http://www.gnome.org/">GNOME</a> project &#8211; with the purpose of making software development for, primarily, GNOME easier &#8211; and I&#8217;m an avid GNOME user I wanted to look deeper into the world of Vala.</p>
<p>I, and most programmers I believe, work in that way that I need a real and useful project when learning a new programming language. So I thought why not re-writing the <a href="/blog/stuff/#roxen-applauncher">Roxen Application Launcher</a> I wrote in C#/Mono a couple of years ago in Vala &#8211; which by the way is syntactically very, very similar to C# and Java. I&#8217;d gotten tired of always having to fiddle with the C# code with every new version of Mono since something always broke when Mono was updated so a re-write wasn&#8217;t going to be totally pointless. The good thing about Vala is that the Vala compiler generates C code and that&#8217;s what you compile the program from. Fast code and hopefully more mature and stable libraries that won&#8217;t break backwards compatibility with every new release.</p>
<h2>What about Vala</h2>
<p>So, on I went about it and I think that Vala is a really promising language. It&#8217;s still a very young language so some library bindings isn&#8217;t behaving exactly as expected and the documentation isn&#8217;t directly redundant &#8211; although the <a href="http://references.valadoc.org/">Vala reference documentation site</a> isn&#8217;t half bad. But since Vala pretty much is a wrapper for, or binding to, the underlying C libraries you can find answers to your questions that way. All in all I think Vala has a promising future: Way more simple than C and almost as fast and light on memory (remember the Vala compiler generates C code) and way faster than C#/Mono and free from any Microsoft associations <img src='http://www.poppa.se/blog/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> .</p>
<h2>What about the Roxen Application Launcher</h2>
<p>In this new version I utilize <a href="http://en.wikipedia.org/wiki/GConf">GConf</a> for storing application settings. I also made use of &#8211; for the first time &#8211; the <a href="http://en.wikipedia.org/wiki/GNU_Build_Tools">GNU Build Tools</a> for compilation which also makes it easier to distribute and for others to compile from the sources. This also means that the distributed version compiles from the C sources and not the Vala sources so there&#8217;s no need for the Vala compiler to build the program.</p>
<p>Other than that there&#8217;s nothing fancy about it. The Vala sources is available at my <a href="http://github.com/poppa/Roxen-Application-Launcher">Github repository</a>. </p>
<p><a href="/blog/data/roxenlauncher-0.4.2.tar.gz">Roxen Appliction Launcher 0.4.2</a></p>
<h3>Screenshots</h3>
<p>The screenshots is showing the Swedish translation.</p>
<p><strong>List of downloaded files</strong><br />
<a href="/blog/data/images/ral-vala-1.png"><img src="/blog/data/images/ral-vala-1.png/680" alt="Screenshot 1 of the Roxen Application Launcher" /></a></p>
<p><strong>Adding support for new file type</strong><br />
<a href="/blog/data/images/ral-vala-2.png"><img src="/blog/data/images/ral-vala-2.png/680" alt="Screenshot 2 of the Roxen Application Launcher" /></a></p>
<p><strong>The GNOME status icon</strong><br />
<a href="/blog/data/images/ral-vala-3.png"><img src="/blog/data/images/ral-vala-3.png/680" alt="Screenshot 3 of the Roxen Application Launcher" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/new-roxen-application-launcher-for-linux-written-in-vala/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Vala &#8211; the new programming language for Gnome</title>
		<link>http://www.poppa.se/blog/vala-the-new-programming-language-for-gnome/</link>
		<comments>http://www.poppa.se/blog/vala-the-new-programming-language-for-gnome/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 21:29:59 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[Vala]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=268</guid>
		<description><![CDATA[This Friday when I read the last issue (in Sweden) of Linux Format there was an article on a new programming language named Vala. The goal for Vala is to provide a modern programming language for, primarily, developing Gnome applications. There is of course Mono, but Vala doesn&#8217;t run in a virtual machine but is [...]]]></description>
			<content:encoded><![CDATA[<p>This Friday when I read the last issue (in Sweden) of <a href="http://www.linuxformat.co.uk/">Linux Format</a> there was an article on a new programming language named <a href="http://live.gnome.org/Vala/">Vala</a>. The goal for Vala is to provide a modern programming language for, primarily, developing <a href="http://www.gnome.org/">Gnome</a> applications. There is of course <a href="http://www.mono-project.com/">Mono</a>, but Vala doesn&#8217;t run in a virtual machine but is complied to machine code. But Vala resembles C# syntactically and has borrowed a lot of concepts from C#.</p>
<p>From what I understand Vala code is first translated into plain old C code, and then compiled with the ordinary GCC compiler. The benefit is that you don&#8217;t have to get head aches about memory management and so forth.</p>
<p>Vala seems pretty interesting and I downloaded it and compiled it without any difficulties. There are precompiled packages for most Linux distros &#8211; it&#8217;s available in the Ubuntu repository &#8211; but since Vala is new and still under development the distro packages is far behind in version.</p>
<p>There&#8217;s also <a href="http://www.valaide.org/">a Vala IDE</a> and <a href="http://live.gnome.org/Vala/#head-6c397c4077ef096e78ea90d62f6d511a82e1e9ea">plugins for GEdit, Anjuta and Eclipse</a>. </p>
<p>Anyway, just to try Vala out I made a little program &#8211; using <a href="http://www.valaide.org/">Val(a)ide</a> &#8211; that changes the desktop wallpaper on a per interval basis. Send the program a path to a directory with images and the background will change among those images every <code>*nth</code> minutes.</p>
<p>This program needs <a href="http://live.gnome.org/Libgee"><code>libgee</code></a> which at the moment needs to be added manually.</p>
<p><code>Compile: valac --pkg gconf-2.0 --pkg gee-1.0 --pkg gio-2.0 main.vala -o wallpaper-iterator</code></p>
<pre><code lang="vala">
/* main.vala
 *
 * Copyright (C) 2009 Pontus Östlund <spam@poppa.se>
 *
 * No license what so ever. Do what ever you like...
 *
 * Author:
 * 	Pontus Östlund <spam@poppa.se>
 */

// GLib isn't really neccessary since it's imported automatically
using GLib, Gee, GConf;

/**
 * User defined exception types
 */
errordomain IOError {
	FILE_NOT_FOUND,
	NOT_A_DIRECTORY
}

/**
 * Main class
 */
public class Main
{
	/**
	 * Used as reference in option parser
	 */
	static int arg_delay;

	/**
	 * Application command line options
	 */
	const OptionEntry[] options = {
		{ "delay", 'd', 0, OptionArg.INT, ref arg_delay,
			"Number of minutes to wait before swapping background", null },
		{ null }
	};

	/**
	 * Main method
	 *
	 * @param args
	 *  Command line arguments
	 */
  public static int main (string[] args)
  {
		try {
			var opt = new OptionContext("\"/path/to/wallpapers\"");
			opt.set_help_enabled(true);
			opt.add_main_entries(options, null);
			opt.parse(ref args);
		}
		catch (GLib.Error e) {
			stderr.printf("Error: %s\n", e.message);
			stderr.printf("Run '%s --help' to see a full list of available "+
			              "options\n", args[0]);
			return 1;
		}

		if (args.length < 2) {
			stderr.printf("Missing argument!\n");
			stderr.printf("Run '%s --help' for usage\n", args[0]);
			return 1;
		}

		// Default time before changing background is 30 minutes
		int delay = arg_delay > 0 ? arg_delay*60 : 60*30;

		try {
			WallpaperIterator bg = new WallpaperIterator(args[1], delay);
			bg.run();
			bg.stop();
		}
		catch (IOError e) {
			stderr.printf("Error: %s\n", e.message);
			return 1;
		}
		finally {
			stderr.printf("Finally block reached!\n");
		}

    return 0;
  }
}

/**
 * Class that handles changeing of desktop wallpapers on a per interval way
 */
public class WallpaperIterator : GLib.Object
{
	/**
	 * Number of seconds to wait before changeing wallpaper
	 */
	private int delay = 0;
	/**
	 * Current index in the images list
	 */
	private int index = 0;
	/**
	 * List of images to change between
	 */
	private ArrayList<string> files = new ArrayList<string>();
	/**
	 * List of allowed content types
	 */
	private ArrayList<string> allow = new ArrayList<string>();
	/**
	 * GConf client object
	 */
	private GConf.Client gclient = null;
	/**
	 * GConf registry where the background image is set
	 */
	private string gconf_key = "/desktop/gnome/background/picture_filename";
	/**
	 * Background being used when the application is started
	 */
	private string default_bg = null;

	/**
	 * Constructor
	 *
	 * @param dir
	 *  The directory to collect wallpapers in
	 * @param delay
	 *  Time to wait - in seconds - before swapping wallpaper
	 */
	public WallpaperIterator(string dir, int delay)
		throws IOError
	{
		assert(delay > 0);

		allow.add("image/jpeg");
		allow.add("image/png");

		var f = File.new_for_path(dir);

		if (!f.query_exists(null))
			throw new IOError.FILE_NOT_FOUND(" \"%s\" doesn't exits!".printf(dir));

		if (f.query_file_type(0, null) != FileType.DIRECTORY) {
			throw new IOError.NOT_A_DIRECTORY(" \"%s\" is not a directory!"
			                                  .printf(dir));
		}

		collect(f.get_path());

		if (files.size < 2) {
			warning("Not enough images found for this application to be useful!\n");
			return;
		}

		this.delay = delay;
	}

	/**
	 * Run the application. Starts a MainLoop
	 */
	public void run()
	{
		gclient = GConf.Client.get_default();
		default_bg = gclient.get_string(gconf_key);

		MainLoop loop = new MainLoop(null, false);
		var time = new TimeoutSource(delay*1000);
		time.set_callback(() => { swap(); });
		time.attach(loop.get_context());
		loop.run();
	}

	/**
	 * Stop the application. Tries to reset the background
	 */
	public void stop()
	{
		try {
			if (default_bg != null)
				gclient.set_string(gconf_key, default_bg);
		}
		catch (GLib.Error e) {
			warning("Failed to restore background!\n");
		}
	}

	/**
	 * Does the actual background swapping
	 */
	private void swap()
	{
		if (index >= files.size) {
			debug("Restart...\n");
			index = 0;
		}

		debug("Callback...%-2d (%s)\n", index, files[index]);

		try {
			gclient.set_string(gconf_key, files[index]);
		}
		catch (GLib.Error e) {
			warning("Failed to set background: %s\n", e.message);
		}
		index++;
	}

	/**
	 * Collect images
	 *
	 * @param path
	 */
	private void collect(string path)
	{
		try {
			var dir = File.new_for_path(path).enumerate_children(
				"standard::name,standard::type,standard::content-type",
				0, null
			);

			FileInfo fi;
			string fp;
			while ((fi = dir.next_file(null)) != null) {
				fp = path + "/" + fi.get_name();
				if (fi.get_file_type() == FileType.DIRECTORY)
					collect(fp);
				else {
					if (fi.get_content_type() in allow)
						files.add(fp);
					else
						warning("Skipping \"%s\" due to unallowed content type\n", fp);
				}
			}
		}
		catch (GLib.Error e) {
			warning("Error: %s\n", e.message);
		}
	}
}
</code></pre>
<p>I think Vala looks promising and I will try it out trying to write a more complex application when I find the time.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/vala-the-new-programming-language-for-gnome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Roxen Application Launcher 0.3</title>
		<link>http://www.poppa.se/blog/roxen-application-launcher-1/</link>
		<comments>http://www.poppa.se/blog/roxen-application-launcher-1/#comments</comments>
		<pubDate>Wed, 18 Jun 2008 15:54:19 +0000</pubDate>
		<dc:creator>Pontus</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Roxen]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Gnome]]></category>
		<category><![CDATA[Share]]></category>

		<guid isPermaLink="false">http://www.poppa.se/blog/?p=178</guid>
		<description><![CDATA[I just created an updated version of Roxen Launcher. I got an error report from one who tried to build the application:
./ApplCon.cs(232,24): error CS0122:
&#8216;System.Net.Sockets.TcpListener.Server&#8217; is inaccessible due
to its protection level
An explanation of the error can be found at MSDN. The reason seems to be due to TcpListener.Server being a protected property but I tried to [...]]]></description>
			<content:encoded><![CDATA[<p>I just created an updated version of Roxen Launcher. I got an error report from one who tried to build the application:</p>
<p style="padding-left: 30px;">./ApplCon.cs(232,24): error CS0122:<br />
&#8216;System.Net.Sockets.TcpListener.Server&#8217; is inaccessible due<br />
to its protection level</p>
<p>An <a href="http://msdn.microsoft.com/en-us/library/ha94aebs.aspx">explanation of the error</a> can be found at MSDN. The reason seems to be due to <code>TcpListener.Server</code> being a protected property but I tried to access it as public. The strange thing is that I didn&#8217;t get an error about it nor on my machine at home or at work. Now I created a derived class of <code>TcpListener.Server</code> so that I can access the protected property.</p>
<p>We&#8217;ll see if it works!</p>
<p><a href="/blog/data/roxenlauncher-0.3.tar.gz">Roxen Application Launcher</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.poppa.se/blog/roxen-application-launcher-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

