]> git.meshlink.io Git - catta/blobdiff - avahi-ui/avahi-ui.c
avahi-ui: gtk3 fix
[catta] / avahi-ui / avahi-ui.c
index 4bd836b008e45ad18cfd3f521ec1cf11d2f3de1d..92d765aa1a8b40f426771d094b5d1e0834a63d08 100644 (file)
@@ -1,18 +1,16 @@
-/* $Id$ */
-
 /***
   This file is part of avahi.
+
   avahi is free software; you can redistribute it and/or modify it
   under the terms of the GNU Lesser General Public License as
   published by the Free Software Foundation; either version 2.1 of the
   License, or (at your option) any later version.
+
   avahi is distributed in the hope that it will be useful, but WITHOUT
   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
   Public License for more details.
+
   You should have received a copy of the GNU Lesser General Public
   License along with avahi; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
@@ -37,6 +35,7 @@
 #include <avahi-common/error.h>
 #include <avahi-common/address.h>
 #include <avahi-common/domain.h>
+#include <avahi-common/i18n.h>
 
 #include "avahi-ui.h"
 
@@ -52,13 +51,13 @@ struct _AuiServiceDialogPrivate {
     AvahiServiceBrowser **browsers;
     AvahiServiceResolver *resolver;
     AvahiDomainBrowser *domain_browser;
-    
+
     gchar **browse_service_types;
     gchar *service_type;
     gchar *domain;
     gchar *service_name;
     AvahiProtocol address_family;
-        
+
     AvahiAddress address;
     gchar *host_name;
     AvahiStringList *txt_data;
@@ -66,13 +65,14 @@ struct _AuiServiceDialogPrivate {
 
     gboolean resolve_service, resolve_service_done;
     gboolean resolve_host_name, resolve_host_name_done;
-    
+
     GtkWidget *domain_label;
     GtkWidget *domain_button;
     GtkWidget *service_tree_view;
     GtkWidget *service_progress_bar;
 
     GtkListStore *service_list_store, *domain_list_store;
+    GHashTable *service_type_names;
 
     guint service_pulse_timeout;
     guint domain_pulse_timeout;
@@ -128,34 +128,34 @@ static void aui_service_dialog_get_property(GObject *object, guint prop_id, GVal
 static int get_default_response(GtkDialog *dlg) {
     gint ret = GTK_RESPONSE_NONE;
 
-    if (GTK_WINDOW(dlg)->default_widget)
+    if (gtk_window_get_default_widget(GTK_WINDOW(dlg)))
         /* Use the response of the default widget, if possible */
-        ret = gtk_dialog_get_response_for_widget(dlg, GTK_WINDOW(dlg)->default_widget);
+        ret = gtk_dialog_get_response_for_widget(dlg, gtk_window_get_default_widget(GTK_WINDOW(dlg)));
 
     if (ret == GTK_RESPONSE_NONE) {
         /* Fall back to finding the first positive response */
         GList *children, *t;
         gint bad = GTK_RESPONSE_NONE;
-        
-        t = children = gtk_container_get_children(GTK_CONTAINER(dlg->action_area));
-        
+
+        t = children = gtk_container_get_children(GTK_CONTAINER(gtk_dialog_get_action_area(dlg)));
+
         while (t) {
             GtkWidget *child = t->data;
-            
+
             ret = gtk_dialog_get_response_for_widget(dlg, child);
-            
+
             if (ret == GTK_RESPONSE_ACCEPT ||
                 ret == GTK_RESPONSE_OK ||
                 ret == GTK_RESPONSE_YES ||
                 ret == GTK_RESPONSE_APPLY)
                 break;
-            
+
             if (ret != GTK_RESPONSE_NONE && bad == GTK_RESPONSE_NONE)
                 bad = ret;
-            
+
             t = t->next;
         }
-        
+
         g_list_free (children);
 
         /* Fall back to finding the first negative response */
@@ -170,7 +170,9 @@ G_DEFINE_TYPE(AuiServiceDialog, aui_service_dialog, GTK_TYPE_DIALOG)
 
 static void aui_service_dialog_class_init(AuiServiceDialogClass *klass) {
     GObjectClass *object_class;
-    
+
+    avahi_init_i18n();
+
     object_class = (GObjectClass*) klass;
 
     object_class->finalize = aui_service_dialog_finalize;
@@ -180,64 +182,64 @@ static void aui_service_dialog_class_init(AuiServiceDialogClass *klass) {
     g_object_class_install_property(
             object_class,
             PROP_BROWSE_SERVICE_TYPES,
-            g_param_spec_pointer("browse_service_types", "Browse Service Types", "A NULL terminated list of service types to browse for",
+            g_param_spec_pointer("browse_service_types", _("Browse Service Types"), _("A NULL terminated list of service types to browse for"),
                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
     g_object_class_install_property(
             object_class,
             PROP_DOMAIN,
-            g_param_spec_string("domain", "Domain", "The domain to browse in, or NULL for the default domain",
+            g_param_spec_string("domain", _("Domain"), _("The domain to browse in, or NULL for the default domain"),
                                 NULL,
                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
     g_object_class_install_property(
             object_class,
             PROP_SERVICE_TYPE,
-            g_param_spec_string("service_type", "Service Type", "The service type of the selected service",
+            g_param_spec_string("service_type", _("Service Type"), _("The service type of the selected service"),
                                 NULL,
                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
     g_object_class_install_property(
             object_class,
             PROP_SERVICE_NAME,
-            g_param_spec_string("service_name", "Service Name", "The service name of the selected service",
+            g_param_spec_string("service_name", _("Service Name"), _("The service name of the selected service"),
                                 NULL,
                                 G_PARAM_READABLE | G_PARAM_WRITABLE));
     g_object_class_install_property(
             object_class,
             PROP_ADDRESS,
-            g_param_spec_pointer("address", "Address", "The address of the resolved service",
-                                G_PARAM_READABLE));    
+            g_param_spec_pointer("address", _("Address"), _("The address of the resolved service"),
+                                G_PARAM_READABLE));
     g_object_class_install_property(
             object_class,
             PROP_PORT,
-            g_param_spec_uint("port", "Port", "The IP port number of the resolved service",
+            g_param_spec_uint("port", _("Port"), _("The IP port number of the resolved service"),
                              0, 0xFFFF, 0,
                              G_PARAM_READABLE));
     g_object_class_install_property(
             object_class,
             PROP_HOST_NAME,
-            g_param_spec_string("host_name", "Host Name", "The host name of the resolved service",
+            g_param_spec_string("host_name", _("Host Name"), _("The host name of the resolved service"),
                                 NULL,
                                 G_PARAM_READABLE));
     g_object_class_install_property(
             object_class,
             PROP_TXT_DATA,
-            g_param_spec_pointer("txt_data", "TXT Data", "The TXT data of the resolved service",
+            g_param_spec_pointer("txt_data", _("TXT Data"), _("The TXT data of the resolved service"),
                                 G_PARAM_READABLE));
     g_object_class_install_property(
             object_class,
             PROP_RESOLVE_SERVICE,
-            g_param_spec_boolean("resolve_service", "Resolve service", "Resolve service",
+            g_param_spec_boolean("resolve_service", _("Resolve Service"), _("Resolve the selected service automatically before returning"),
                                  TRUE,
                                  G_PARAM_READABLE | G_PARAM_WRITABLE));
     g_object_class_install_property(
             object_class,
             PROP_RESOLVE_HOST_NAME,
-            g_param_spec_boolean("resolve_host_name", "Resolve service host name", "Resolve service host name",
+            g_param_spec_boolean("resolve_host_name", _("Resolve Service Host Name"), _("Resolve the host name of the selected service automatically before returning"),
                                  TRUE,
                                  G_PARAM_READABLE | G_PARAM_WRITABLE));
     g_object_class_install_property(
             object_class,
             PROP_ADDRESS_FAMILY,
-            g_param_spec_int("address_family", "Address family", "The address family for host name resolution",
+            g_param_spec_int("address_family", _("Address family"), _("The address family for host name resolution"),
                              AVAHI_PROTO_UNSPEC, AVAHI_PROTO_INET6, AVAHI_PROTO_UNSPEC,
                              G_PARAM_READABLE | G_PARAM_WRITABLE));
 }
@@ -248,15 +250,17 @@ GtkWidget *aui_service_dialog_new_valist(
         GtkWindow *parent,
         const gchar *first_button_text,
         va_list varargs) {
-    
+
     const gchar *button_text;
     gint dr;
-    
-    GtkWidget *w = GTK_WIDGET(g_object_new(
+
+    GtkWidget *w = (GtkWidget*)g_object_new(
                                       AUI_TYPE_SERVICE_DIALOG,
+#if !GTK_CHECK_VERSION (2,21,8)
                                       "has-separator", FALSE,
+#endif
                                       "title", title,
-                                      NULL));
+                                      NULL);
 
     if (parent)
         gtk_window_set_transient_for(GTK_WINDOW(w), parent);
@@ -264,12 +268,12 @@ GtkWidget *aui_service_dialog_new_valist(
     button_text = first_button_text;
     while (button_text) {
         gint response_id;
-        
+
         response_id = va_arg(varargs, gint);
         gtk_dialog_add_button(GTK_DIALOG(w), button_text, response_id);
         button_text = va_arg(varargs, const gchar *);
     }
-    
+
     gtk_dialog_set_response_sensitive(GTK_DIALOG(w), GTK_RESPONSE_ACCEPT, FALSE);
     gtk_dialog_set_response_sensitive(GTK_DIALOG(w), GTK_RESPONSE_OK, FALSE);
     gtk_dialog_set_response_sensitive(GTK_DIALOG(w), GTK_RESPONSE_YES, FALSE);
@@ -288,12 +292,12 @@ GtkWidget* aui_service_dialog_new(
         ...) {
 
     GtkWidget *w;
-    
+
     va_list varargs;
     va_start(varargs, first_button_text);
     w = aui_service_dialog_new_valist(title, parent, first_button_text, varargs);
     va_end(varargs);
-    
+
     return w;
 }
 
@@ -319,11 +323,11 @@ static void client_callback(AvahiClient *c, AvahiClientState state, void *userda
                                               GTK_DIALOG_DESTROY_WITH_PARENT,
                                               GTK_MESSAGE_ERROR,
                                               GTK_BUTTONS_CLOSE,
-                                              "Avahi client failure: %s",
+                                              _("Avahi client failure: %s"),
                                               avahi_strerror(avahi_client_errno(c)));
         gtk_dialog_run(GTK_DIALOG(m));
         gtk_widget_destroy(m);
-        
+
         gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
     }
 }
@@ -366,7 +370,7 @@ static void resolve_callback(
 
             avahi_string_list_free(d->priv->txt_data);
             d->priv->txt_data = avahi_string_list_copy(txt);
-            
+
             if (a) {
                 d->priv->resolve_host_name_done = 1;
                 d->priv->address = *a;
@@ -381,11 +385,11 @@ static void resolve_callback(
                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                                   GTK_MESSAGE_ERROR,
                                                   GTK_BUTTONS_CLOSE,
-                                                  "Avahi resolver failure: %s",
+                                                  _("Avahi resolver failure: %s"),
                                                   avahi_strerror(avahi_client_errno(d->priv->client)));
             gtk_dialog_run(GTK_DIALOG(m));
             gtk_widget_destroy(m);
-            
+
             gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
             break;
         }
@@ -405,12 +409,12 @@ static void browse_callback(
         void* userdata) {
 
     AuiServiceDialog *d = AUI_SERVICE_DIALOG(userdata);
-    
+
     switch (event) {
 
         case AVAHI_BROWSER_NEW: {
             gchar *ifs;
-            const gchar *pretty_type;
+            const gchar *pretty_type = NULL;
             char ifname[IFNAMSIZ];
             GtkTreeIter iter;
             GtkTreeSelection *selection;
@@ -420,12 +424,17 @@ static void browse_callback(
 
             ifs = g_strdup_printf("%s %s", ifname, protocol == AVAHI_PROTO_INET ? "IPv4" : "IPv6");
 
+            if (d->priv->service_type_names)
+                pretty_type = g_hash_table_lookup (d->priv->service_type_names, type);
+
+            if (!pretty_type) {
 #if defined(HAVE_GDBM) || defined(HAVE_DBM)
-            pretty_type = stdb_lookup(type);
+                pretty_type = stdb_lookup(type);
 #else
-            pretty_type = type;
-#endif            
-            
+                pretty_type = type;
+#endif
+            }
+
             gtk_list_store_append(d->priv->service_list_store, &iter);
 
             gtk_list_store_set(d->priv->service_list_store, &iter,
@@ -438,7 +447,7 @@ static void browse_callback(
                                -1);
 
             g_free(ifs);
-                    
+
             if (d->priv->common_protocol == AVAHI_PROTO_UNSPEC)
                 d->priv->common_protocol = protocol;
 
@@ -457,19 +466,19 @@ static void browse_callback(
                     !d->priv->service_name ||
                     (avahi_domain_equal(d->priv->service_type, type) && strcasecmp(d->priv->service_name, name) == 0)) {
                     GtkTreePath *path;
-                    
+
                     gtk_tree_selection_select_iter(selection, &iter);
 
                     path = gtk_tree_model_get_path(GTK_TREE_MODEL(d->priv->service_list_store), &iter);
                     gtk_tree_view_set_cursor(GTK_TREE_VIEW(d->priv->service_tree_view), path, NULL, FALSE);
                     gtk_tree_path_free(path);
                 }
-                
+
             }
-            
+
             break;
         }
-            
+
         case AVAHI_BROWSER_REMOVE: {
             GtkTreeIter iter;
             gboolean valid;
@@ -479,7 +488,7 @@ static void browse_callback(
                 gint _interface, _protocol;
                 gchar *_name, *_type;
                 gboolean found;
-                
+
                 gtk_tree_model_get(GTK_TREE_MODEL(d->priv->service_list_store), &iter,
                                    SERVICE_COLUMN_IFACE, &_interface,
                                    SERVICE_COLUMN_PROTO, &_protocol,
@@ -494,10 +503,10 @@ static void browse_callback(
                     gtk_list_store_remove(d->priv->service_list_store, &iter);
                     break;
                 }
-                
+
                 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(d->priv->service_list_store), &iter);
             }
-            
+
             break;
         }
 
@@ -506,8 +515,8 @@ static void browse_callback(
                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                                   GTK_MESSAGE_ERROR,
                                                   GTK_BUTTONS_CLOSE,
-                                                  "Browsing for service type %s in domain %s failed: %s",
-                                                  type, domain ? domain : "n/a",
+                                                  _("Browsing for service type %s in domain %s failed: %s"),
+                                                  type, domain ? domain : _("n/a"),
                                                   avahi_strerror(avahi_client_errno(d->priv->client)));
             gtk_dialog_run(GTK_DIALOG(m));
             gtk_widget_destroy(m);
@@ -530,20 +539,20 @@ static void browse_callback(
 
 static void domain_make_default_selection(AuiServiceDialog *d, const gchar *name, GtkTreeIter *iter) {
     GtkTreeSelection *selection;
-    
+
     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(d->priv->domain_tree_view));
     if (!gtk_tree_selection_get_selected(selection, NULL, NULL)) {
-        
+
         if (avahi_domain_equal(gtk_entry_get_text(GTK_ENTRY(d->priv->domain_entry)), name)) {
             GtkTreePath *path;
-            
+
             gtk_tree_selection_select_iter(selection, iter);
-            
+
             path = gtk_tree_model_get_path(GTK_TREE_MODEL(d->priv->domain_list_store), iter);
             gtk_tree_view_set_cursor(GTK_TREE_VIEW(d->priv->domain_tree_view), path, NULL, FALSE);
             gtk_tree_path_free(path);
         }
-        
+
     }
 }
 
@@ -557,7 +566,7 @@ static void domain_browse_callback(
         void* userdata) {
 
     AuiServiceDialog *d = AUI_SERVICE_DIALOG(userdata);
-    
+
     switch (event) {
 
         case AVAHI_BROWSER_NEW: {
@@ -568,7 +577,7 @@ static void domain_browse_callback(
             valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
             while (valid) {
                 gchar *_name;
-                
+
                 gtk_tree_model_get(GTK_TREE_MODEL(d->priv->domain_list_store), &iter,
                                    DOMAIN_COLUMN_NAME, &_name,
                                    DOMAIN_COLUMN_REF, &ref,
@@ -579,15 +588,15 @@ static void domain_browse_callback(
 
                 if (found)
                     break;
-                
+
                 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
             }
 
-            if (found) 
+            if (found)
                 gtk_list_store_set(d->priv->domain_list_store, &iter, DOMAIN_COLUMN_REF, ref + 1, -1);
             else {
                 gtk_list_store_append(d->priv->domain_list_store, &iter);
-                
+
                 gtk_list_store_set(d->priv->domain_list_store, &iter,
                                    DOMAIN_COLUMN_NAME, name,
                                    DOMAIN_COLUMN_REF, 1,
@@ -595,20 +604,20 @@ static void domain_browse_callback(
             }
 
             domain_make_default_selection(d, name, &iter);
-            
+
             break;
         }
 
         case AVAHI_BROWSER_REMOVE: {
             gboolean valid;
             GtkTreeIter iter;
-            
+
             valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
             while (valid) {
                 gint ref;
                 gchar *_name;
                 gboolean found;
-                
+
                 gtk_tree_model_get(GTK_TREE_MODEL(d->priv->domain_list_store), &iter,
                                    DOMAIN_COLUMN_NAME, &_name,
                                    DOMAIN_COLUMN_REF, &ref,
@@ -624,20 +633,20 @@ static void domain_browse_callback(
                         gtk_list_store_set(d->priv->domain_list_store, &iter, DOMAIN_COLUMN_REF, ref - 1, -1);
                     break;
                 }
-                
+
                 valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(d->priv->domain_list_store), &iter);
             }
-            
+
             break;
         }
-            
+
 
         case AVAHI_BROWSER_FAILURE: {
             GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                                   GTK_MESSAGE_ERROR,
                                                   GTK_BUTTONS_CLOSE,
-                                                  "Avahi domain browser failure: %s",
+                                                  _("Avahi domain browser failure: %s"),
                                                   avahi_strerror(avahi_client_errno(d->priv->client)));
             gtk_dialog_run(GTK_DIALOG(m));
             gtk_widget_destroy(m);
@@ -660,10 +669,10 @@ static void domain_browse_callback(
 
 static const gchar *get_domain_name(AuiServiceDialog *d) {
     const gchar *domain;
-    
+
     g_return_val_if_fail(d, NULL);
     g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);
-    
+
     if (d->priv->domain)
         return d->priv->domain;
 
@@ -672,7 +681,7 @@ static const gchar *get_domain_name(AuiServiceDialog *d) {
                                               GTK_DIALOG_DESTROY_WITH_PARENT,
                                               GTK_MESSAGE_ERROR,
                                               GTK_BUTTONS_CLOSE,
-                                              "Failed to read Avahi domain : %s",
+                                              _("Failed to read Avahi domain: %s"),
                                               avahi_strerror(avahi_client_errno(d->priv->client)));
         gtk_dialog_run(GTK_DIALOG(m));
         gtk_widget_destroy(m);
@@ -692,24 +701,24 @@ static gboolean start_callback(gpointer data) {
     const char *domain;
 
     d->priv->start_idle = 0;
-    
+
     if (!d->priv->browse_service_types || !*d->priv->browse_service_types) {
-        g_warning("Browse service type list is empty!");
+        g_warning(_("Browse service type list is empty!"));
         return FALSE;
     }
 
     if (!d->priv->client) {
         if (!(d->priv->client = avahi_client_new(avahi_glib_poll_get(d->priv->glib_poll), 0, client_callback, d, &error))) {
-            
+
             GtkWidget *m = gtk_message_dialog_new(GTK_WINDOW(d),
                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                                   GTK_MESSAGE_ERROR,
                                                   GTK_BUTTONS_CLOSE,
-                                                  "Failed to connect to Avahi server: %s",
+                                                  _("Failed to connect to Avahi server: %s"),
                                                   avahi_strerror(error));
             gtk_dialog_run(GTK_DIALOG(m));
             gtk_widget_destroy(m);
-            
+
             gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
             return FALSE;
         }
@@ -723,13 +732,13 @@ static gboolean start_callback(gpointer data) {
     g_assert(domain);
 
     if (avahi_domain_equal(domain, "local."))
-        gtk_label_set_markup(GTK_LABEL(d->priv->domain_label), "Browsing for services on <b>local network</b>:");
+        gtk_label_set_markup(GTK_LABEL(d->priv->domain_label), _("Browsing for services on <b>local network</b>:"));
     else {
-        gchar *t = g_strdup_printf("Browsing for services in domain <b>%s</b>:", domain);
+        gchar *t = g_strdup_printf(_("Browsing for services in domain <b>%s</b>:"), domain);
         gtk_label_set_markup(GTK_LABEL(d->priv->domain_label), t);
         g_free(t);
     }
-    
+
     if (d->priv->browsers) {
         for (sb = d->priv->browsers; *sb; sb++)
             avahi_service_browser_free(*sb);
@@ -743,7 +752,7 @@ static gboolean start_callback(gpointer data) {
     d->priv->common_protocol = AVAHI_PROTO_UNSPEC;
 
     gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 0), FALSE);
-    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(d->priv->service_tree_view), gtk_tree_view_column_get_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 2)));
+    gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(d->priv->service_tree_view), FALSE);
     gtk_widget_show(d->priv->service_progress_bar);
 
     if (d->priv->service_pulse_timeout <= 0)
@@ -761,12 +770,12 @@ static gboolean start_callback(gpointer data) {
                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                                   GTK_MESSAGE_ERROR,
                                                   GTK_BUTTONS_CLOSE,
-                                                  "Failed to create browser for %s: %s",
+                                                  _("Failed to create browser for %s: %s"),
                                                   *st,
                                                   avahi_strerror(avahi_client_errno(d->priv->client)));
             gtk_dialog_run(GTK_DIALOG(m));
             gtk_widget_destroy(m);
-            
+
             gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
             return FALSE;
 
@@ -787,21 +796,21 @@ static void aui_service_dialog_finalize(GObject *object) {
 
     if (d->priv->start_idle > 0)
         g_source_remove(d->priv->start_idle);
-    
+
     g_free(d->priv->host_name);
     g_free(d->priv->domain);
     g_free(d->priv->service_name);
 
     avahi_string_list_free(d->priv->txt_data);
-    
+
     g_strfreev(d->priv->browse_service_types);
 
     if (d->priv->domain_browser)
         avahi_domain_browser_free(d->priv->domain_browser);
-    
+
     if (d->priv->resolver)
         avahi_service_resolver_free(d->priv->resolver);
-    
+
     if (d->priv->browsers) {
         AvahiServiceBrowser **sb;
 
@@ -817,6 +826,13 @@ static void aui_service_dialog_finalize(GObject *object) {
     if (d->priv->glib_poll)
         avahi_glib_poll_free(d->priv->glib_poll);
 
+    if (d->priv->service_list_store)
+        g_object_unref(d->priv->service_list_store);
+    if (d->priv->domain_list_store)
+        g_object_unref(d->priv->domain_list_store);
+    if (d->priv->service_type_names)
+        g_hash_table_unref (d->priv->service_type_names);
+
     g_free(d->priv);
     d->priv = NULL;
 
@@ -849,7 +865,7 @@ static void response_callback(GtkDialog *dialog, gint response, gpointer user_da
         response == GTK_RESPONSE_APPLY) &&
         ((d->priv->resolve_service && !d->priv->resolve_service_done) ||
          (d->priv->resolve_host_name && !d->priv->resolve_host_name_done))) {
-        
+
         GtkTreeIter iter;
         gint interface, protocol;
         gchar *name, *type;
@@ -873,8 +889,8 @@ static void response_callback(GtkDialog *dialog, gint response, gpointer user_da
 
         gtk_widget_set_sensitive(GTK_WIDGET(dialog), FALSE);
         cursor = gdk_cursor_new(GDK_WATCH);
-        gdk_window_set_cursor(GTK_WIDGET(dialog)->window, cursor);
-        gdk_cursor_unref(cursor);
+        gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(dialog)), cursor);
+        g_object_unref(G_OBJECT(cursor));
 
         if (!(d->priv->resolver = avahi_service_resolver_new(
                       d->priv->client, interface, protocol, name, type, d->priv->domain,
@@ -884,12 +900,12 @@ static void response_callback(GtkDialog *dialog, gint response, gpointer user_da
                                                   GTK_DIALOG_DESTROY_WITH_PARENT,
                                                   GTK_MESSAGE_ERROR,
                                                   GTK_BUTTONS_CLOSE,
-                                                  "Failed to create resolver for %s of type %s in domain %s: %s",
+                                                  _("Failed to create resolver for %s of type %s in domain %s: %s"),
                                                   name, type, d->priv->domain,
                                                   avahi_strerror(avahi_client_errno(d->priv->client)));
             gtk_dialog_run(GTK_DIALOG(m));
             gtk_widget_destroy(m);
-            
+
             gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
             return;
         }
@@ -898,7 +914,7 @@ static void response_callback(GtkDialog *dialog, gint response, gpointer user_da
 
 static gboolean is_valid_domain_suffix(const gchar *n) {
     gchar label[AVAHI_LABEL_MAX];
-    
+
     if (!avahi_is_valid_domain_name(n))
         return FALSE;
 
@@ -906,7 +922,7 @@ static gboolean is_valid_domain_suffix(const gchar *n) {
         return FALSE;
 
     /* At least one label */
-    
+
     return !!label[0];
 }
 
@@ -959,23 +975,25 @@ static void domain_button_clicked(GtkButton *button G_GNUC_UNUSED, gpointer user
                                               GTK_DIALOG_DESTROY_WITH_PARENT,
                                               GTK_MESSAGE_ERROR,
                                               GTK_BUTTONS_CLOSE,
-                                              "Failed to create domain browser: %s",
+                                              _("Failed to create domain browser: %s"),
                                               avahi_strerror(avahi_client_errno(p->client)));
         gtk_dialog_run(GTK_DIALOG(m));
         gtk_widget_destroy(m);
-        
+
         gtk_dialog_response(GTK_DIALOG(d), GTK_RESPONSE_CANCEL);
         return;
     }
-    
+
     p->domain_dialog = gtk_dialog_new();
     gtk_container_set_border_width(GTK_CONTAINER(p->domain_dialog), 5);
-    gtk_window_set_title(GTK_WINDOW(p->domain_dialog), "Change domain");
+    gtk_window_set_title(GTK_WINDOW(p->domain_dialog), _("Change domain"));
+#if !GTK_CHECK_VERSION(2,21,8)
     gtk_dialog_set_has_separator(GTK_DIALOG(p->domain_dialog), FALSE);
-    
+#endif
+
     vbox = gtk_vbox_new(FALSE, 8);
     gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(p->domain_dialog)->vbox), vbox, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(p->domain_dialog))), vbox, TRUE, TRUE, 0);
 
     p->domain_entry = gtk_entry_new();
     gtk_entry_set_max_length(GTK_ENTRY(p->domain_entry), AVAHI_DOMAIN_NAME_MAX);
@@ -983,7 +1001,7 @@ static void domain_button_clicked(GtkButton *button G_GNUC_UNUSED, gpointer user
     gtk_entry_set_activates_default(GTK_ENTRY(p->domain_entry), TRUE);
     g_signal_connect(p->domain_entry, "changed", G_CALLBACK(domain_entry_changed_callback), d);
     gtk_box_pack_start(GTK_BOX(vbox), p->domain_entry, FALSE, FALSE, 0);
-    
+
     vbox2 = gtk_vbox_new(FALSE, 8);
     gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);
 
@@ -1002,7 +1020,7 @@ static void domain_button_clicked(GtkButton *button G_GNUC_UNUSED, gpointer user
     g_signal_connect(selection, "changed", G_CALLBACK(domain_selection_changed_callback), d);
 
     renderer = gtk_cell_renderer_text_new();
-    column = gtk_tree_view_column_new_with_attributes("Service Name", renderer, "text", DOMAIN_COLUMN_NAME, NULL);
+    column = gtk_tree_view_column_new_with_attributes(_("Service Name"), renderer, "text", DOMAIN_COLUMN_NAME, NULL);
     gtk_tree_view_column_set_expand(column, TRUE);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p->domain_tree_view), column);
 
@@ -1010,10 +1028,10 @@ static void domain_button_clicked(GtkButton *button G_GNUC_UNUSED, gpointer user
     gtk_container_add(GTK_CONTAINER(scrolled_window), p->domain_tree_view);
 
     p->domain_progress_bar = gtk_progress_bar_new();
-    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(p->domain_progress_bar), "Browsing ...");
+    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(p->domain_progress_bar), _("Browsing..."));
     gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(p->domain_progress_bar), 0.1);
     gtk_box_pack_end(GTK_BOX(vbox2), p->domain_progress_bar, FALSE, FALSE, 0);
-    
+
     gtk_dialog_add_button(GTK_DIALOG(p->domain_dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL);
     p->domain_ok_button = GTK_WIDGET(gtk_dialog_add_button(GTK_DIALOG(p->domain_dialog), GTK_STOCK_OK, GTK_RESPONSE_ACCEPT));
     gtk_dialog_set_default_response(GTK_DIALOG(p->domain_dialog), GTK_RESPONSE_ACCEPT);
@@ -1023,7 +1041,7 @@ static void domain_button_clicked(GtkButton *button G_GNUC_UNUSED, gpointer user
     gtk_widget_grab_focus(p->domain_entry);
 
     gtk_window_set_default_size(GTK_WINDOW(p->domain_dialog), 300, 300);
-    
+
     gtk_widget_show_all(vbox);
 
     gtk_list_store_append(p->domain_list_store, &iter);
@@ -1031,7 +1049,7 @@ static void domain_button_clicked(GtkButton *button G_GNUC_UNUSED, gpointer user
     domain_make_default_selection(d, "local", &iter);
 
     p->domain_pulse_timeout = g_timeout_add(100, domain_pulse_callback, d);
-    
+
     if (gtk_dialog_run(GTK_DIALOG(p->domain_dialog)) == GTK_RESPONSE_ACCEPT)
         aui_service_dialog_set_domain(d, gtk_entry_get_text(GTK_ENTRY(p->domain_entry)));
 
@@ -1055,7 +1073,7 @@ static void aui_service_dialog_init(AuiServiceDialog *d) {
     AuiServiceDialogPrivate *p;
 
     p = d->priv = g_new(AuiServiceDialogPrivate, 1);
-    
+
     p->host_name = NULL;
     p->domain = NULL;
     p->service_name = NULL;
@@ -1089,20 +1107,21 @@ static void aui_service_dialog_init(AuiServiceDialog *d) {
     p->forward_response_id = GTK_RESPONSE_NONE;
 
     p->service_list_store = p->domain_list_store = NULL;
-    
+    p->service_type_names = NULL;
+
     gtk_widget_push_composite_child();
 
     gtk_container_set_border_width(GTK_CONTAINER(d), 5);
 
     vbox = gtk_vbox_new(FALSE, 8);
     gtk_container_set_border_width(GTK_CONTAINER(vbox), 8);
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(d)->vbox), vbox, TRUE, TRUE, 0);
+    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(d))), vbox, TRUE, TRUE, 0);
 
-    p->domain_label = gtk_label_new("Initializing...");
+    p->domain_label = gtk_label_new(_("Initializing..."));
     gtk_label_set_ellipsize(GTK_LABEL(p->domain_label), TRUE);
     gtk_misc_set_alignment(GTK_MISC(p->domain_label), 0, 0.5);
     gtk_box_pack_start(GTK_BOX(vbox), p->domain_label, FALSE, FALSE, 0);
-    
+
 
     vbox2 = gtk_vbox_new(FALSE, 8);
     gtk_box_pack_start(GTK_BOX(vbox), vbox2, TRUE, TRUE, 0);
@@ -1120,19 +1139,19 @@ static void aui_service_dialog_init(AuiServiceDialog *d) {
     selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(p->service_tree_view));
     gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
     g_signal_connect(selection, "changed", G_CALLBACK(service_selection_changed_callback), d);
-    
+
     renderer = gtk_cell_renderer_text_new();
-    column = gtk_tree_view_column_new_with_attributes("Location", renderer, "text", SERVICE_COLUMN_PRETTY_IFACE, NULL);
+    column = gtk_tree_view_column_new_with_attributes(_("Location"), renderer, "text", SERVICE_COLUMN_PRETTY_IFACE, NULL);
     gtk_tree_view_column_set_visible(column, FALSE);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p->service_tree_view), column);
-    
+
     renderer = gtk_cell_renderer_text_new();
-    column = gtk_tree_view_column_new_with_attributes("Name", renderer, "text", SERVICE_COLUMN_NAME, NULL);
+    column = gtk_tree_view_column_new_with_attributes(_("Name"), renderer, "text", SERVICE_COLUMN_NAME, NULL);
     gtk_tree_view_column_set_expand(column, TRUE);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p->service_tree_view), column);
 
     renderer = gtk_cell_renderer_text_new();
-    column = gtk_tree_view_column_new_with_attributes("Type", renderer, "text", SERVICE_COLUMN_PRETTY_TYPE, NULL);
+    column = gtk_tree_view_column_new_with_attributes(_("Type"), renderer, "text", SERVICE_COLUMN_PRETTY_TYPE, NULL);
     gtk_tree_view_column_set_visible(column, FALSE);
     gtk_tree_view_append_column(GTK_TREE_VIEW(p->service_tree_view), column);
 
@@ -1140,23 +1159,23 @@ static void aui_service_dialog_init(AuiServiceDialog *d) {
     gtk_container_add(GTK_CONTAINER(scrolled_window), p->service_tree_view);
 
     p->service_progress_bar = gtk_progress_bar_new();
-    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(p->service_progress_bar), "Browsing ...");
+    gtk_progress_bar_set_text(GTK_PROGRESS_BAR(p->service_progress_bar), _("Browsing..."));
     gtk_progress_bar_set_pulse_step(GTK_PROGRESS_BAR(p->service_progress_bar), 0.1);
     gtk_box_pack_end(GTK_BOX(vbox2), p->service_progress_bar, FALSE, FALSE, 0);
 
-    p->domain_button = gtk_button_new_with_mnemonic("_Domain..."); 
-    gtk_button_set_image(GTK_BUTTON(p->domain_button), gtk_image_new_from_stock(GTK_STOCK_NETWORK, GTK_ICON_SIZE_BUTTON)); 
+    p->domain_button = gtk_button_new_with_mnemonic(_("_Domain..."));
+    gtk_button_set_image(GTK_BUTTON(p->domain_button), gtk_image_new_from_stock(GTK_STOCK_NETWORK, GTK_ICON_SIZE_BUTTON));
     g_signal_connect(p->domain_button, "clicked", G_CALLBACK(domain_button_clicked), d);
-    gtk_box_pack_start(GTK_BOX(GTK_DIALOG(d)->action_area), p->domain_button, FALSE, TRUE, 0);
-    gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(GTK_DIALOG(d)->action_area), p->domain_button, TRUE);
-    gtk_widget_show(p->domain_button); 
-    
+    gtk_box_pack_start(GTK_BOX(gtk_dialog_get_action_area(GTK_DIALOG(d))), p->domain_button, FALSE, TRUE, 0);
+    gtk_button_box_set_child_secondary(GTK_BUTTON_BOX(gtk_dialog_get_action_area(GTK_DIALOG(d))), p->domain_button, TRUE);
+    gtk_widget_show(p->domain_button);
+
     gtk_dialog_set_default_response(GTK_DIALOG(d), GTK_RESPONSE_ACCEPT);
 
     gtk_widget_grab_focus(p->service_tree_view);
 
     gtk_window_set_default_size(GTK_WINDOW(d), 400, 300);
-    
+
     gtk_widget_show_all(vbox);
 
     gtk_widget_pop_composite_child();
@@ -1180,12 +1199,12 @@ void aui_service_dialog_set_browse_service_types(AuiServiceDialog *d, const char
     va_list ap;
     const char *t;
     unsigned u;
-    
+
     g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
     g_return_if_fail(type);
 
     g_strfreev(d->priv->browse_service_types);
-    
+
     va_start(ap, type);
     for (u = 1; va_arg(ap, const char *); u++)
         ;
@@ -1193,16 +1212,14 @@ void aui_service_dialog_set_browse_service_types(AuiServiceDialog *d, const char
 
     d->priv->browse_service_types = g_new0(gchar*, u+1);
     d->priv->browse_service_types[0] = g_strdup(type);
-    
+
     va_start(ap, type);
-    for (u = 1; (t = va_arg(apcopy, const char*)); u++)
+    for (u = 1; (t = va_arg(ap, const char*)); u++)
         d->priv->browse_service_types[u] = g_strdup(t);
     va_end(ap);
 
     if (d->priv->browse_service_types[0] && d->priv->browse_service_types[1]) {
-        /* Multiple service types, enable headers */
-    
-        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(d->priv->service_tree_view), TRUE);
+        /* Multiple service types, show type-column */
         gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 2), TRUE);
     }
 
@@ -1210,7 +1227,7 @@ void aui_service_dialog_set_browse_service_types(AuiServiceDialog *d, const char
 }
 
 void aui_service_dialog_set_browse_service_typesv(AuiServiceDialog *d, const char *const*types) {
-    
+
     g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
     g_return_if_fail(types);
     g_return_if_fail(*types);
@@ -1219,9 +1236,7 @@ void aui_service_dialog_set_browse_service_typesv(AuiServiceDialog *d, const cha
     d->priv->browse_service_types = g_strdupv((char**) types);
 
     if (d->priv->browse_service_types[0] && d->priv->browse_service_types[1]) {
-        /* Multiple service types, enable headers */
-    
-        gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(d->priv->service_tree_view), TRUE);
+        /* Multiple service types, show type-column */
         gtk_tree_view_column_set_visible(gtk_tree_view_get_column(GTK_TREE_VIEW(d->priv->service_tree_view), 2), TRUE);
     }
 
@@ -1234,19 +1249,47 @@ const gchar*const* aui_service_dialog_get_browse_service_types(AuiServiceDialog
     return (const char* const*) d->priv->browse_service_types;
 }
 
+void aui_service_dialog_set_service_type_name(AuiServiceDialog *d, const gchar *type, const gchar *name) {
+    GtkTreeModel *m = NULL;
+    GtkTreeIter iter;
+
+    g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
+    g_return_if_fail(NULL != type);
+    g_return_if_fail(NULL != name);
+
+    if (NULL == d->priv->service_type_names)
+        d->priv->service_type_names = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
+
+    g_hash_table_insert(d->priv->service_type_names, g_strdup(type), g_strdup(name));
+
+    if (d->priv->service_list_store)
+        m = GTK_TREE_MODEL(d->priv->service_list_store);
+
+    if (m && gtk_tree_model_get_iter_first(m, &iter)) {
+        do {
+            char *stored_type = NULL;
+
+            gtk_tree_model_get(m, &iter, SERVICE_COLUMN_TYPE, &stored_type, -1);
+
+            if (stored_type && g_str_equal(stored_type, type))
+                gtk_list_store_set(d->priv->service_list_store, &iter, SERVICE_COLUMN_PRETTY_TYPE, name, -1);
+        } while (gtk_tree_model_iter_next(m, &iter));
+    }
+}
+
 void aui_service_dialog_set_domain(AuiServiceDialog *d, const char *domain) {
     g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
     g_return_if_fail(!domain || is_valid_domain_suffix(domain));
 
     g_free(d->priv->domain);
     d->priv->domain = domain ? avahi_normalize_name_strdup(domain) : NULL;
-    
+
     restart_browsing(d);
 }
 
 const char* aui_service_dialog_get_domain(AuiServiceDialog *d) {
     g_return_val_if_fail(AUI_IS_SERVICE_DIALOG(d), NULL);
-    
+
     return d->priv->domain;
 }
 
@@ -1306,7 +1349,7 @@ const AvahiStringList *aui_service_dialog_get_txt_data(AuiServiceDialog *d) {
 
 void aui_service_dialog_set_resolve_service(AuiServiceDialog *d, gboolean resolve) {
     g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
-    
+
     d->priv->resolve_service = resolve;
 }
 
@@ -1318,7 +1361,7 @@ gboolean aui_service_dialog_get_resolve_service(AuiServiceDialog *d) {
 
 void aui_service_dialog_set_resolve_host_name(AuiServiceDialog *d, gboolean resolve) {
     g_return_if_fail(AUI_IS_SERVICE_DIALOG(d));
-    
+
     d->priv->resolve_host_name = resolve;
 }
 
@@ -1343,7 +1386,7 @@ AvahiProtocol aui_service_dialog_get_address_family(AuiServiceDialog *d) {
 
 static void aui_service_dialog_set_property(GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) {
     AuiServiceDialog *d = AUI_SERVICE_DIALOG(object);
-    
+
     switch (prop_id) {
         case PROP_BROWSE_SERVICE_TYPES:
             aui_service_dialog_set_browse_service_typesv(d, g_value_get_pointer(value));
@@ -1360,7 +1403,7 @@ static void aui_service_dialog_set_property(GObject *object, guint prop_id, cons
         case PROP_SERVICE_NAME:
             aui_service_dialog_set_service_name(d, g_value_get_string(value));
             break;
-            
+
         case PROP_RESOLVE_SERVICE:
             aui_service_dialog_set_resolve_service(d, g_value_get_boolean(value));
             break;
@@ -1372,7 +1415,7 @@ static void aui_service_dialog_set_property(GObject *object, guint prop_id, cons
         case PROP_ADDRESS_FAMILY:
             aui_service_dialog_set_address_family(d, g_value_get_int(value));
             break;
-            
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
             break;
@@ -1381,7 +1424,7 @@ static void aui_service_dialog_set_property(GObject *object, guint prop_id, cons
 
 static void aui_service_dialog_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
     AuiServiceDialog *d = AUI_SERVICE_DIALOG(object);
-    
+
     switch (prop_id) {
         case PROP_BROWSE_SERVICE_TYPES:
             g_value_set_pointer(value, (gpointer) aui_service_dialog_get_browse_service_types(d));
@@ -1410,11 +1453,11 @@ static void aui_service_dialog_get_property(GObject *object, guint prop_id, GVal
         case PROP_HOST_NAME:
             g_value_set_string(value, aui_service_dialog_get_host_name(d));
             break;
-                               
+
         case PROP_TXT_DATA:
             g_value_set_pointer(value, (gpointer) aui_service_dialog_get_txt_data(d));
             break;
-            
+
         case PROP_RESOLVE_SERVICE:
             g_value_set_boolean(value, aui_service_dialog_get_resolve_service(d));
             break;
@@ -1426,10 +1469,9 @@ static void aui_service_dialog_get_property(GObject *object, guint prop_id, GVal
         case PROP_ADDRESS_FAMILY:
             g_value_set_int(value, aui_service_dialog_get_address_family(d));
             break;
-            
+
         default:
             G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
             break;
     }
 }
-