Dictionary Applet/4

In order to let others know how’s the status of GNOME Dictionary Breaking is progressing (and in order to force myself working on it regularly ;-)), I’m sending the

Not So Weekly Status Report on GNOME Dictionary

Containing the status of the review-slash-breaking-slash-rewrite process of the GNOME Dictionary application and applet. Okay, it won’t be weekly, and I could simply use my blog instead of email; nevertheless, having someone to report to makes room for public discussion, and since I’m breaking (mostly) working stuff better be sure that some discussion actually happens at all.

So, what have you been doing so far?

First of all, I tried to salvage the ugly mess that was implementing the dictionary protocol (gnome-utils/gdictsrc/dict.[ch]). For the lack of better (or non 12-years-old-sister safe) words, I won’t use the ones I came up while auditing the said code. Suffice is to say that the code couldn’t be salvaged without a massive rewrite process anyway, so I scrapped out the implementation, and created a new, GObject-based one. You can see a preliminary version of the API usage on my weblog. How’s the rewrite going? I’ve pretty much implemented all the needed client commands for a RFC2229-compliant client, testing it both on dict.org and on my local dictionary server. The MATCH command is still missing, but I evaluate that will be a matter of 15 minutes worth of coding, in the new infrastructure. About the new infrastructure: I’m pretty proud of GdictContext; for example, now the client will advertise itself (using a predefined string or a custom one), and all the commands get queued; thus, you can set up a batch of commands (e.g. connect-lookup databases-lookup strategies-disconnect) without having to actually *wait* inside the callback for a command to complete its run. This will allow lazy data loading, and close one of my pet peeves about the current GNOME Dictionary, that is the absence of a CLI output; I’d like to write into a terminal:

$ gnome-dictionary --lookup "GNOME" --no-window

and have my definition of “GNOME” with no fuss (yes, I know that there already is “dict”, but what’s the point of having a dictionary client in GNOME if I also have to install dict?).

Another point of the new infrastructure is that lives all inside a shared library; which means that we can now have the much needed separation between the back-end code and the UI and the application/applet. Also, this means we can provide language bindings for it, allowing other applications to interface to dictionary servers (and I specifically thinking about the Deskbar Applet, here, even though I think there already is a dictionary protocol implementation in Python, using one based only on platform stuff would shorten the dependency chain).

What are you planning to do next?

First of all, finishing the client implementation (also, authentication could be added, if I can come up with a UI for it); adding a way to get some data like server’s capabilities, caching of the databases and strategies lists, etc. Also, I’ll do some code polishing and consolidation. This shouldn’t take long – probably no more than a week.

The UI is what comes next. The GdictEntry will be the first to be checked; I’d like to use the SexyIconEntry by Christian Hammond as a base for this widget, in order to have something more appealing (for the applet, mostly)- but first I’ve got to check how that behaves with GtkEntryCompletion.

The next widget to be targeted will be GdictSpeller; I’m still dubious about the form of this widget, or if it’s useful at all.

Finally, GdictDefbox. The main widget is pretty much right as it is, so I’ll just update it in order to use the new GdictContext; I’ll move the “find” dialog into a bottom pane a la Firefox, and I think that will be the most relevant change, UI-wise.

This would complete the road-map for the GNOME Dictionary Library (libgdict): the application and the applet would simply fall into place, once this has been sorted out.

When do we see the code?

This is the worst part of all. Since I’m basically rewriting everything, up until I can actually provide a working version of GNOME Dictionary I’d like not to taint the CVS repository; but I also understand the need for looking at the code, and comment on it – so, as soon as I’m able to create a full text client using libgdict, I’ll upload a tarball of it on my web space. If it passes a review from the maintainer, I’ll begin by creating a branch of gnome-utils HEAD with the new code, and keep working on it.

[]
[]
[]
[]

Chemical Brothers

I saw today on the Planet that Miguel linked the documentary filmed by italian jorunalists working for the italian public broadcaster (RAI, which oddly enough should be, and is written as, an acronym but it expands to nothing). It was broadcasted on the satellite channels, and announced the day before broadcasting on various national media.

I saw the documentary, but I do fear that I’m in the minority of people that actually did so – not just because it was broadcasted on satellite only (Marta says that it was the only way to be broadcasted at all; it simply would have been “lost” in the archives, were it to be seen on national television), but it was also broadcasted at 7:30 in the morning, and the day of a national, 24-hours strike of the journalists guild (I know, don’t even get me started on this), which was protesting against the so-called “work flexibility” – which roughly means that your employee has the right to fuck you over by hiring you on a six to twelve months time-scale, paying you with a third world country wage because this way of hiring is not regulated, not even by minimal wages (it’s funny: when the bill permitting this major fuck up of the jobs and welfare system was signed, journalists were nowhere to be found to write about it; now they’re all upset).

So, to sum up: satellite broadcast + wrong broadcast time + no media coverage = no-one saw it.

I assume that the fact the italian Prime Minister, who’s also a direct and indirect owner of basically the 80% of the italian media, considers himself a big pal of Dubya has nothing to do with this.

Dictionary Applet/3

In case you’ve been wondering if I had disappeared or something…

I’m in the middle of a session of exams, this week (four of them, to be precise), and I’ve had to cut down hacking time; nevertheless, I’ve been able to commit a set of fixes for the RecentChooser/BookmarkFile code and wrap up a new version of the desktop-bookmark storage spec.

GNOME Dictionary

I’ve also started the rewriting of the low-level implementation of the dictionary protocol client object for the GNOME Dictionary application. I’ve tried one last time to salvage the sane bits of the old code, but it was practically useless. Instead, I designed a new, object-oriented, approach. It’s been three years since I’ve done some networking with C, and I had to do some catch-up in order to write some decent code.

The new client object is called (with a certain lack of creativity) GDictContext; you create a new context by using the gdict_context_new() function, and since it inherits from GObject, all you have to do to destroy it is to call g_object_unref() on it.

All the querying and replying is done asynchronously; but instead of having callback functions for each command, I preferred a more GTK-like approach; now, you’ll have to connect to signals, which are emitted by the context object when something comes along the wire; thus, creating a client for the dictionary protocol is just a matter of a few lines of code:

static void
on_connect (GDictContext *context
            gpointer      user_data)
{
  GError *error = NULL;

  gdict_context_define (context, NULL, "penguin", &error);
  if (error)
    {
      g_warning ("Error: %s", error->message);
      g_error_free (error);

      g_main_loop_quit (main_loop);
    }
}

static void
on_def_found (GDictContext    *context,
              GDictDefinition *definition,
	      gpointer         user_data)
{
  g_print ("Definition for '%s' (from: %s)\n%s\n",
           gdict_definition_get_word (definition),
	   gdict_definition_get_from (definition),
	   gdict_definition_get_definition (definition));
}

...

  GDictContext *context;

  main_loop = g_main_loop_new (NULL, FALSE);

  context = gdict_context_new ("dict.org", NULL);
  g_signal_connect (context, "connect",
                    G_CALLBACK (on_connect), NULL);
  g_signal_connect (context, "definition-found",
                    G_CALLBACK (on_def_found), NULL);

  gdict_context_connect (context, &connect_error);
  if (connect_error)
    {
      g_warning ("Error: %s", connect_error->message);
      g_error_free (connect_error);
      g_object_unref (G_OBJECT (context));

      return -1;
    }

  g_main_loop_run (main_loop);

  g_object_unref (G_OBJECT (context));

  return 0;

As you can see, no more silly creation of commands and contextes, using redundant, badly defined or over-designed API (which, by the way, badly leaks strings and objects): just lean and mean, OO, event-driven code; I plan to make this a shared library (it already is, albeit it’s not exported), so every public function comes with documentation and follows the same style rules of the other platform libraries; I could even add bindings to it, and write the whole application/applet in an high-level language, like Perl or Python, and the effort would really be minimal.

Right now, the code is still flaky on the response parsing; I plan to make it more robust as soon as the week ends, and I’m free to use more time on it. After that, I’ll attack the UI side – and get a hold on the messy situation of the definition box, the speller tab and the preferences window. This should really take less than the low-level stuff: the code is a lot saner, even though requiring much love. The self-imposed deadline of late November/early December should be fully respected.