vinagre r286 - in trunk: . data src



Author: jwendell
Date: Thu Apr 10 03:35:47 2008
New Revision: 286
URL: http://svn.gnome.org/viewvc/vinagre?rev=286&view=rev

Log:
Merge from unstable branch


Added:
   trunk/src/gossip-cell-renderer-expander.c
      - copied unchanged from r285, /branches/unstable/src/gossip-cell-renderer-expander.c
   trunk/src/gossip-cell-renderer-expander.h
      - copied unchanged from r285, /branches/unstable/src/gossip-cell-renderer-expander.h
   trunk/src/vinagre-mdns.c
      - copied unchanged from r285, /branches/unstable/src/vinagre-mdns.c
   trunk/src/vinagre-mdns.h
      - copied unchanged from r285, /branches/unstable/src/vinagre-mdns.h
Modified:
   trunk/   (props changed)
   trunk/ChangeLog
   trunk/configure.ac
   trunk/data/vinagre-ui.xml
   trunk/src/   (props changed)
   trunk/src/Makefile.am
   trunk/src/vinagre-bookmarks.c
   trunk/src/vinagre-bookmarks.h
   trunk/src/vinagre-commands.c
   trunk/src/vinagre-commands.h
   trunk/src/vinagre-connect.c
   trunk/src/vinagre-connection.c
   trunk/src/vinagre-connection.h
   trunk/src/vinagre-fav.c
   trunk/src/vinagre-fav.h
   trunk/src/vinagre-main.c
   trunk/src/vinagre-notebook.c
   trunk/src/vinagre-tab.c
   trunk/src/vinagre-tab.h
   trunk/src/vinagre-ui.h
   trunk/src/vinagre-utils.c
   trunk/src/vinagre-utils.h
   trunk/src/vinagre-window-private.h
   trunk/src/vinagre-window.c
   trunk/src/vinagre-window.h

Modified: trunk/configure.ac
==============================================================================
--- trunk/configure.ac	(original)
+++ trunk/configure.ac	Thu Apr 10 03:35:47 2008
@@ -38,7 +38,8 @@
 LIBGLADE_REQUIRED=2.6.0
 GCONF_REQUIRED=2.16.0
 GTHREAD_REQUIRED=2.0.0
-GTK_VNC_REQUIRED=0.3.3
+GTK_VNC_REQUIRED=0.3.5
+AVAHI_REQUIRED=0.6.22
 
 PKG_CHECK_MODULES(VINAGRE, \ 
   glib-2.0 >= $GLIB_REQUIRED \
@@ -48,7 +49,9 @@
   gconf-2.0 >= $GCONF_REQUIRED \
   gthread-2.0 >= $GTHREAD_REQUIRED \
   gnome-keyring-1 \
-  gtk-vnc-1.0 >= $GTK_VNC_REQUIRED)
+  gtk-vnc-1.0 >= $GTK_VNC_REQUIRED \
+  avahi-ui >= $AVAHI_REQUIRED \
+  avahi-gobject >= $AVAHI_REQUIRED)
 AC_SUBST(VINAGRE_CFLAGS)
 AC_SUBST(VINAGRE_LIBS)
 
@@ -60,31 +63,17 @@
 AM_GCONF_SOURCE_2
 
 
-#*******************************************************************************
-# Check for Avahi
-#*******************************************************************************
-
-AVAHI_REQUIRED=0.6.18
-
-AC_ARG_ENABLE(avahi,
-        AS_HELP_STRING([--enable-avahi],[Enable use of avahi]),
-        [case "${enableval}" in
-                yes) VINAGRE_ENABLE_AVAHI=yes ;;
-                no)  VINAGRE_ENABLE_AVAHI=no ;;
-                *) AC_MSG_ERROR(bad value ${enableval} for --enable-avahi) ;;
-        esac],
-        [VINAGRE_ENABLE_AVAHI=no])
-
-AVAHI_CFLAGS=
-AVAHI_LIBS=
-if test "x$VINAGRE_ENABLE_AVAHI" = "xyes" ; then
-    PKG_CHECK_MODULES(AVAHI,
-		      [avahi-ui >= $AVAHI_REQUIRED])
-    AVAHI_CFLAGS="$AVAHI_CFLAGS -DVINAGRE_HAVE_AVAHI"
+dnl define a MAINT-like variable REBUILD which is set
+dnl if Perl, so autogenerated sources can be rebuilt
+AC_PATH_PROGS(PERL, perl5 perl)
+AC_ARG_ENABLE(rebuilds, [  --disable-rebuilds      disable all source autogeneration rules],,enable_rebuilds=yes)
+REBUILD=\#
+if test "x$enable_rebuilds" = "xyes" && \
+     test -n "$PERL" && \
+     $PERL -e 'exit !($] >= 5.002)' > /dev/null 2>&1 ; then
+  REBUILD=
 fi
-AC_SUBST(AVAHI_CFLAGS)
-AC_SUBST(AVAHI_LIBS)
-AM_CONDITIONAL(VINAGRE_AVAHI, [test "x$VINAGRE_ENABLE_AVAHI" = "xyes"])
+AC_SUBST(REBUILD)
 
 #*******************************************************************************
 
@@ -109,6 +98,4 @@
 
 	Compiler ...................:  ${CC} 
 	Compiler Flags .............:  ${CFLAGS}
-
-	Avahi support ..............:  ${VINAGRE_ENABLE_AVAHI}
 "

Modified: trunk/data/vinagre-ui.xml
==============================================================================
--- trunk/data/vinagre-ui.xml	(original)
+++ trunk/data/vinagre-ui.xml	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-ui.xml
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -38,9 +38,10 @@
     <menu name="ViewMenu" action="View">
       <menuitem name="ViewToolbarMenu" action="ViewToolbar"/>
       <menuitem name="ViewStatusbarMenu" action="ViewStatusbar"/>
-      <menuitem name="ViewBookmarksMenu" action="ViewBookmarks"/>
+      <menuitem name="ViewSidePanelMenu" action="ViewSidePanel"/>
       <separator/>
       <menuitem name="ViewFullScreenMenu" action="ViewFullScreen"/>
+      <menuitem name="ViewScalingMenu" action="ViewScaling"/>
     </menu>
 
     <menu name="BookmarksMenu" action="Bookmarks">
@@ -50,6 +51,8 @@
       <menuitem name="BookmarksDelMenu" action="BookmarksDel"/>
       <separator/>
       <placeholder name="BookmarksList"/>
+      <separator/>
+      <placeholder name="AvahiList"/>
     </menu>
 
     <menu name="HelpMenu" action="Help">

Modified: trunk/src/Makefile.am
==============================================================================
--- trunk/src/Makefile.am	(original)
+++ trunk/src/Makefile.am	Thu Apr 10 03:35:47 2008
@@ -1,3 +1,5 @@
+NULL =
+
 INCLUDES = 						\
 	-DBINDIR=\"$(bindir)\"			 	\
 	-DDATADIR=\"$(datadir)\"			\
@@ -7,7 +9,7 @@
 	-DVINAGRE_DATADIR=\""$(datadir)/vinagre"\"	\
 	-DPACKAGE_LOCALE_DIR=\""$(datadir)/locale"\"	\
 	$(VINAGRE_CFLAGS)				\
-	$(AVAHI_CFLAGS)
+	$(NULL)
 
 bin_PROGRAMS = vinagre
 
@@ -23,10 +25,54 @@
 	vinagre-tab.c vinagre-tab.h			\
 	vinagre-utils.c vinagre-utils.h			\
 	vinagre-window.c vinagre-window.h		\
-	vinagre-ui.h vinagre-window-private.h
+	vinagre-ui.h vinagre-window-private.h		\
+	vinagre-enums.h vinagre-enums.c			\
+	gossip-cell-renderer-expander.c gossip-cell-renderer-expander.h \
+	vinagre-mdns.h vinagre-mdns.c \
+	$(NULL)
 
 vinagre_LDADD = \
 	$(VINAGRE_LIBS)		\
 	$(GTKVNC_LIBS)		\
-	$(AVAHI_LIBS)
+	$(NULL)
+
+vinagre_enum_headers = \
+	$(top_srcdir)/src/vinagre-connection.h \
+	$(NULL)
+
+vinagre-enums.c: @REBUILD@ $(vinagre_enum_headers)
+	glib-mkenums    --fhead "#include <glib-object.h>\n" \
+			--fhead "#include \"vinagre-enums.h\"\n\n" \
+			--fprod "\n/* enumerations from \"@filename \" */" \
+			--fprod "\n#include \"@filename \"\n" \
+			--vhead "static const G Type@Value _ enum_name@_values[] = {" \
+			--vprod "  { @VALUENAME@, \"@VALUENAME \", \"@valuenick \" }," \
+			--vtail "  { 0, NULL, NULL }\n};\n\n" \
+			--vtail "GType\n enum_name@_get_type (void)\n{\n" \
+			--vtail "  static GType type = 0;\n\n" \
+			--vtail "  if (!type)\n" \
+			--vtail "    type = g_ type@_register_static (\"@EnumName \", _ enum_name@_values);\n\n" \
+			--vtail "  return type;\n}\n\n" \
+		$(vinagre_enum_headers) > $@
+
+vinagre-enums.h: @REBUILD@ $(vinagre_enum_headers)
+	glib-mkenums    --fhead "#ifndef __VINAGRE_ENUMS_H__\n" \
+			--fhead "#define __VINAGRE_ENUMS_H__ 1\n\n" \
+			--fhead "G_BEGIN_DECLS\n\n" \
+			--ftail "G_END_DECLS\n\n" \
+			--ftail "#endif /* __VINAGRE_ENUMS_H__ */\n" \
+			--fprod "\n/* --- @filename@ --- */" \
+			--eprod "#define VINAGRE_TYPE_ ENUMSHORT@ @enum_name _get_type()\n" \
+			--eprod "GType @enum_name _get_type (void);\n" \
+		$(vinagre_enum_headers) >  $@
+
+BUILT_SOURCES = \
+	vinagre-enums.c \
+	vinagre-enums.h \
+	$(NULL)
+
+DISTCLEANFILES = \
+	$(BUILT_SOURCES) \
+	$(NULL)
 
+$(vinagre_OBJECTS): $(BUILT_SOURCES)

Modified: trunk/src/vinagre-bookmarks.c
==============================================================================
--- trunk/src/vinagre-bookmarks.c	(original)
+++ trunk/src/vinagre-bookmarks.c	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-bookmarks.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007  Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008  Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -23,108 +23,187 @@
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
+#include <gio/gio.h>
 #include <glade/glade.h>
 #include <string.h>
 
-#define VINAGRE_FAVORITES_FILE  "vinagre.bookmarks"
-
-GKeyFile *bookmarks = NULL;
+struct _VinagreBookmarksPrivate
+{
+  GKeyFile     *file;
+  gchar        *filename;
+  GSList       *conns;
+  GFileMonitor *monitor;
+};
 
-static gchar *
-filename (void)
+enum
 {
-  return g_build_filename (g_get_home_dir (),
-			   ".gnome2",
-			   VINAGRE_FAVORITES_FILE,
-			   NULL);
-}
+  BOOKMARK_CHANGED,
+  LAST_SIGNAL
+};
+
+#define VINAGRE_BOOKMARKS_FILE  "vinagre.bookmarks"
+
+G_DEFINE_TYPE (VinagreBookmarks, vinagre_bookmarks, G_TYPE_OBJECT);
+
+static VinagreBookmarks *book_singleton = NULL;
+static guint signals[LAST_SIGNAL] = { 0 };
+
+/* Prototypes */
+static void vinagre_bookmarks_update_file  (VinagreBookmarks *book);
+static void vinagre_bookmarks_update_conns (VinagreBookmarks *book);
+static void vinagre_bookmarks_save_file    (VinagreBookmarks *book);
+static void vinagre_bookmarks_clear_conns  (VinagreBookmarks *book);
+static void vinagre_bookmarks_file_changed (GFileMonitor     *monitor,
+		                            GFile             *file,
+		                            GFile             *other_file,
+		                            GFileMonitorEvent  event_type,
+		                            VinagreBookmarks  *book);
+
 
 static void
-vinagre_bookmarks_save_file (void)
+vinagre_bookmarks_init (VinagreBookmarks *book)
 {
-  gchar    *file;
-  gchar    *data;
-  gsize    length;
-  GError   *error;
+  GFile *gfile;
 
-  error = NULL;
-  data = g_key_file_to_data (bookmarks,
-			     &length,
-			     &error);
-  if (!data)
-    {
-      if (error)
-	{
-	  g_warning (_("Error while saving bookmarks: %s"), error->message);
-	  g_error_free (error);
-	}
+  book->priv = G_TYPE_INSTANCE_GET_PRIVATE (book, VINAGRE_TYPE_BOOKMARKS, VinagreBookmarksPrivate);
 
-      return;
+  book->priv->conns = NULL;
+  book->priv->file = NULL;
+  book->priv->filename = g_build_filename (g_get_home_dir (),
+			                   ".gnome2",
+			                   VINAGRE_BOOKMARKS_FILE,
+			                   NULL);
+  vinagre_bookmarks_update_file (book);
+  vinagre_bookmarks_update_conns (book);
+
+  gfile = g_file_new_for_path (book->priv->filename);
+  book->priv->monitor = g_file_monitor_file (gfile,
+                                             G_FILE_MONITOR_NONE,
+                                             NULL,
+                                             NULL);
+  g_signal_connect (book->priv->monitor,
+                    "changed",
+                    G_CALLBACK (vinagre_bookmarks_file_changed),
+                    book);
+  g_object_unref (gfile);
+}
 
-    }
+static void
+vinagre_bookmarks_finalize (GObject *object)
+{
+  VinagreBookmarks *book = VINAGRE_BOOKMARKS (object);
 
-  file  = filename ();
-  error = NULL;
+  g_key_file_free (book->priv->file);
+  book->priv->file = NULL;
+  vinagre_bookmarks_clear_conns (book);
 
-  if (!g_file_set_contents (file,
-			    data,
-			    length,
-			    &error))
-    {
-      if (error)
-	{
-	  g_warning (_("Error while saving bookmarks: %s"), error->message);
-	  g_error_free (error);
-	}
-    }
+  g_free (book->priv->filename);
+  book->priv->filename = NULL;
 
-  g_free (file);
-  g_free (data);
+  g_file_monitor_cancel (book->priv->monitor);
+  g_object_unref (book->priv->monitor);
+
+  G_OBJECT_CLASS (vinagre_bookmarks_parent_class)->finalize (object);
 }
 
-void
-vinagre_bookmarks_init (void)
+static void
+vinagre_bookmarks_class_init (VinagreBookmarksClass *klass)
 {
-  gchar    *file;
-  gboolean loaded;
-  GError   *error;
+  GObjectClass* object_class = G_OBJECT_CLASS (klass);
+  GObjectClass* parent_class = G_OBJECT_CLASS (klass);
 
-  g_return_if_fail (bookmarks == NULL);
+  g_type_class_add_private (klass, sizeof (VinagreBookmarksPrivate));
 
-  bookmarks = g_key_file_new ();
+  object_class->finalize = vinagre_bookmarks_finalize;
 
-  loaded = FALSE;
-  error  = NULL;
+  signals[BOOKMARK_CHANGED] =
+		g_signal_new ("changed",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (VinagreBookmarksClass, changed),
+			      NULL, NULL,
+			      g_cclosure_marshal_VOID__VOID,
+			      G_TYPE_NONE,
+			      0);
+}
 
-  file = filename ();
-  if (g_file_test (file, G_FILE_TEST_EXISTS))
-    loaded = g_key_file_load_from_file (bookmarks,
-					file,
-					G_KEY_FILE_NONE,
-					&error);
-  g_free (file);
+VinagreBookmarks *
+vinagre_bookmarks_get_default (void)
+{
+  if (G_UNLIKELY (!book_singleton))
+    book_singleton = VINAGRE_BOOKMARKS (g_object_new (VINAGRE_TYPE_BOOKMARKS,
+                                                      NULL));
+  return book_singleton;
+}
 
-  if (!loaded)
+static VinagreConnection *
+vinagre_bookmarks_find_conn (VinagreBookmarks  *book,
+                             VinagreConnection *conn)
+{
+  GSList *l, *next;
+
+  for (l = book->priv->conns; l; l = next)
     {
-      if (error)
-	{
-	  g_warning (_("Error while initializing bookmarks: %s"), error->message);
-	  g_error_free (error);
-	}
+      VinagreConnection *local = VINAGRE_CONNECTION (l->data);
+
+      if ( (g_str_equal (vinagre_connection_get_host (conn),
+                         vinagre_connection_get_host (local)))
+          &&
+            (vinagre_connection_get_port (conn) == vinagre_connection_get_port (local) ) )
+        return local;
+
+      next = l->next;
     }
+
+  return NULL;
 }
 
-void
-vinagre_bookmarks_finalize (void)
+static void
+vinagre_bookmarks_add_conn (VinagreBookmarks  *book,
+                            VinagreConnection *conn)
 {
-  g_return_if_fail (bookmarks != NULL);
+  book->priv->conns = g_slist_prepend (book->priv->conns,
+                                       vinagre_connection_clone (conn));
+  vinagre_bookmarks_save_file (book);
+}
 
-  g_key_file_free (bookmarks);
+static void
+vinagre_bookmarks_edit_conn (VinagreBookmarks  *book,
+                             VinagreConnection *old_conn,
+                             VinagreConnection *conn)
+{
+  VinagreConnection *local = vinagre_bookmarks_find_conn (book, old_conn);
+
+  g_return_if_fail (VINAGRE_IS_CONNECTION (local));
+
+  g_object_unref (local);
+  book->priv->conns = g_slist_remove (book->priv->conns,
+                                      local);
+  book->priv->conns = g_slist_prepend (book->priv->conns,
+                                       vinagre_connection_clone (conn));
+  
+  vinagre_bookmarks_save_file (book);
+}
+
+static void
+vinagre_bookmarks_del_conn (VinagreBookmarks  *book,
+                            VinagreConnection *conn)
+{
+  VinagreConnection *local = vinagre_bookmarks_find_conn (book, conn);
+
+  g_return_if_fail (VINAGRE_IS_CONNECTION (local));
+
+  book->priv->conns = g_slist_remove (book->priv->conns,
+                                      local);
+  g_object_unref (local);
+  
+  vinagre_bookmarks_save_file (book);
 }
 
 gboolean
-vinagre_bookmarks_add (VinagreConnection *conn,
-		       VinagreWindow     *window)
+vinagre_bookmarks_add (VinagreBookmarks  *book,
+                       VinagreConnection *conn,
+		       GtkWindow         *window)
 {
   gint result;
   GladeXML    *xml;
@@ -132,12 +211,15 @@
   GtkWidget   *dialog;
   const gchar *name;
 
-  g_return_val_if_fail (conn != NULL, FALSE);
+  g_return_val_if_fail (VINAGRE_IS_BOOKMARKS (book), FALSE);
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), FALSE);
+
+  g_object_ref (conn);
 
   glade_file = vinagre_utils_get_glade_filename ();
   xml = glade_xml_new (glade_file, "add_to_bookmarks_dialog", NULL);
   dialog = glade_xml_get_widget (xml, "add_to_bookmarks_dialog");
-  gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(window));
+  gtk_window_set_transient_for (GTK_WINDOW(dialog), window);
 
   gtk_widget_show_all (dialog);
  
@@ -147,51 +229,53 @@
     {
       name = gtk_entry_get_text (GTK_ENTRY (glade_xml_get_widget (xml, "bookmark_name_entry")));
       if (strlen(name) < 1)
-	name = conn->host;
+	name = vinagre_connection_get_host (conn);
 
-      g_key_file_set_string (bookmarks,
+      g_key_file_set_string (book->priv->file,
 			     name,
 			     "host",
-			     conn->host);
-      g_key_file_set_integer (bookmarks,
+			     vinagre_connection_get_host (conn));
+      g_key_file_set_integer (book->priv->file,
 			      name,
 			      "port",
-			      conn->port);
+			      vinagre_connection_get_port (conn));
 
       vinagre_connection_set_name (conn, name);
-      vinagre_bookmarks_save_file ();
+      vinagre_bookmarks_add_conn (book, conn);
     }
 
   gtk_widget_destroy (GTK_WIDGET (dialog));
   g_object_unref (G_OBJECT (xml));
+  g_object_unref (conn);
 
   return (result == GTK_RESPONSE_OK);
 }
 
 gboolean
-vinagre_bookmarks_edit (VinagreConnection *conn,
-		        VinagreWindow     *window)
+vinagre_bookmarks_edit (VinagreBookmarks  *book,
+                        VinagreConnection *conn,
+		        GtkWindow         *window)
 {
   gint result;
   GladeXML    *xml;
   const gchar *glade_file;
   GtkWidget   *dialog, *host_entry, *name_entry, *port_entry;
-  const gchar *name;
 
-  g_return_val_if_fail (conn != NULL, FALSE);
+  g_return_val_if_fail (VINAGRE_IS_BOOKMARKS (book), FALSE);
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), FALSE);
 
   glade_file = vinagre_utils_get_glade_filename ();
   xml = glade_xml_new (glade_file, "edit_bookmark_dialog", NULL);
   dialog = glade_xml_get_widget (xml, "edit_bookmark_dialog");
-  gtk_window_set_transient_for (GTK_WINDOW(dialog), GTK_WINDOW(window));
+  gtk_window_set_transient_for (GTK_WINDOW(dialog), window);
 
   name_entry = glade_xml_get_widget (xml, "edit_bookmark_name_entry");
   host_entry = glade_xml_get_widget (xml, "edit_bookmark_host_entry");
   port_entry = glade_xml_get_widget (xml, "edit_bookmark_port_entry");
 
-  gtk_entry_set_text (GTK_ENTRY(name_entry), conn->name);
-  gtk_entry_set_text (GTK_ENTRY(host_entry), conn->host);
-  gtk_spin_button_set_value (GTK_SPIN_BUTTON (port_entry), conn->port);
+  gtk_entry_set_text (GTK_ENTRY(name_entry), vinagre_connection_get_name (conn));
+  gtk_entry_set_text (GTK_ENTRY(host_entry), vinagre_connection_get_host (conn));
+  gtk_spin_button_set_value (GTK_SPIN_BUTTON (port_entry), vinagre_connection_get_port (conn));
 
   gtk_widget_show_all (dialog);
  
@@ -199,27 +283,33 @@
 
   if (result == GTK_RESPONSE_OK)
     {
+      const gchar *name;
+      VinagreConnection *old_conn = vinagre_connection_clone (conn);
 
-      g_key_file_remove_group (bookmarks, conn->name, NULL);
+      g_key_file_remove_group (book->priv->file, vinagre_connection_get_name (conn), NULL);
 
       name = gtk_entry_get_text (GTK_ENTRY (name_entry));
       vinagre_connection_set_host (conn, gtk_entry_get_text (GTK_ENTRY (host_entry)));
       vinagre_connection_set_port (conn, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (port_entry)));
 
-      if (strlen(conn->name) < 1)
-	name = conn->host;
+      if (strlen (name) < 1)
+        if (strlen(vinagre_connection_get_name (conn)) < 1)
+	  name = vinagre_connection_get_host (conn);
+        else
+          name = vinagre_connection_get_name (conn);
 
-      g_key_file_set_string (bookmarks,
+      g_key_file_set_string (book->priv->file,
 			     name,
 			     "host",
-			     conn->host);
-      g_key_file_set_integer (bookmarks,
+			     vinagre_connection_get_host (conn));
+      g_key_file_set_integer (book->priv->file,
 			      name,
 			      "port",
-			      conn->port);
+			      vinagre_connection_get_port (conn));
 
       vinagre_connection_set_name (conn, name);
-      vinagre_bookmarks_save_file ();
+      vinagre_bookmarks_edit_conn (book, old_conn, conn);
+      g_object_unref (old_conn);
     }
 
   gtk_widget_destroy (GTK_WIDGET (dialog));
@@ -228,54 +318,27 @@
   return (result == GTK_RESPONSE_OK);
 }
 
-GList *
-vinagre_bookmarks_get_all (void)
-{
-  GList *list = NULL;
-  gsize length, i;
-  gchar **conns;
-  VinagreConnection *conn;
-  gchar *s_value;
-  gint i_value;
-
-  g_return_val_if_fail (bookmarks != NULL, NULL);
-
-  conns = g_key_file_get_groups (bookmarks, &length);
-  for (i=0; i<length; i++)
-    {
-      conn = vinagre_connection_new ();
-      vinagre_connection_set_name (conn, conns[i]);
-
-      s_value = g_key_file_get_string (bookmarks, conns[i], "host", NULL);
-      vinagre_connection_set_host (conn, s_value);
-      g_free (s_value);
-
-      i_value = g_key_file_get_integer (bookmarks, conns[i], "port", NULL);
-      vinagre_connection_set_port (conn, i_value);
-
-      list = g_list_append (list, conn);
-    }
-  g_strfreev (conns);
-
-  return list;
-}
-
 gboolean
-vinagre_bookmarks_del (VinagreConnection *conn,
-		       VinagreWindow     *window)
+vinagre_bookmarks_del (VinagreBookmarks  *book,
+                       VinagreConnection *conn,
+		       GtkWindow         *window)
 {
   gint       result;
   GtkWidget *dialog;
   gchar     *name;
   GError    *error = NULL;
 
-  g_return_val_if_fail (bookmarks != NULL, FALSE);
-  g_return_val_if_fail (conn != NULL, FALSE);
+  g_return_val_if_fail (VINAGRE_IS_BOOKMARKS (book), FALSE);
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), FALSE);
 
-  name = vinagre_connection_best_name (conn);
-  g_return_val_if_fail (g_key_file_has_group (bookmarks, name), FALSE);
+  name = vinagre_connection_get_best_name (conn);
+  if (!g_key_file_has_group (book->priv->file, name))
+    {
+      g_free (name);
+      return FALSE;
+    }
 
-  dialog = gtk_message_dialog_new (GTK_WINDOW (window),
+  dialog = gtk_message_dialog_new (window,
 				   GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
 				   GTK_MESSAGE_QUESTION,
 				   GTK_BUTTONS_OK_CANCEL,
@@ -290,7 +353,7 @@
 
   if (result == GTK_RESPONSE_OK)
     {
-      g_key_file_remove_group (bookmarks, name, &error);
+      g_key_file_remove_group (book->priv->file, name, &error);
       if (error)
 	{
 	  g_warning (_("Error while removing %s from bookmarks: %s"),
@@ -300,57 +363,174 @@
 	  g_free (name);
 	  return FALSE;
 	}
-      g_free (name);
-      vinagre_bookmarks_save_file ();
+      vinagre_bookmarks_del_conn (book, conn);
     }
 
+  g_free (name);
   return (result == GTK_RESPONSE_OK);
 }
 
 VinagreConnection *
-vinagre_bookmarks_exists (const char *host, int port)
+vinagre_bookmarks_exists (VinagreBookmarks *book,
+                          const gchar *host,
+                          gint port)
 {
   VinagreConnection *conn = NULL;
-  gsize length, i;
-  gchar **conns = NULL;
-  gchar *s_host = NULL;
-  gint  i_port;
+  GSList *l, *next;
 
-  g_return_val_if_fail (bookmarks != NULL, NULL);
+  g_return_val_if_fail (VINAGRE_IS_BOOKMARKS (book), NULL);
 
-  conns = g_key_file_get_groups (bookmarks, &length);
-  for (i=0; i<length; i++)
+  for (l = book->priv->conns; l; l = next)
     {
-      s_host = g_key_file_get_string (bookmarks, conns[i], "host", NULL);
-      i_port = g_key_file_get_integer (bookmarks, conns[i], "port", NULL);
+      VinagreConnection *con = VINAGRE_CONNECTION (l->data);
+
+      if ( (g_str_equal (host, vinagre_connection_get_host (con))) &&
+            (port == vinagre_connection_get_port (con) ) )
+        {
+          conn = vinagre_connection_clone (con);
+          break;
+        }
+      next = l->next;
+    }
+  
+  return conn;
+}
 
-      if ( (g_str_equal (host, s_host)) && (port == i_port) )
+GSList *
+vinagre_bookmarks_get_all (VinagreBookmarks *book)
+{
+  g_return_val_if_fail (VINAGRE_IS_BOOKMARKS (book), NULL);
+
+  return book->priv->conns;
+}
+
+static void
+vinagre_bookmarks_update_file (VinagreBookmarks *book)
+{
+  gboolean loaded = TRUE;
+  GError   *error = NULL;
+
+  if (book->priv->file)
+    g_key_file_free (book->priv->file);
+  book->priv->file = g_key_file_new ();
+
+  if (g_file_test (book->priv->filename, G_FILE_TEST_EXISTS))
+    loaded = g_key_file_load_from_file (book->priv->file,
+					book->priv->filename,
+					G_KEY_FILE_NONE,
+					&error);
+  if (!loaded)
+    {
+      if (error)
 	{
-	  conn = vinagre_connection_new ();
-	  vinagre_connection_set_name (conn, conns[i]);
+	  g_warning (_("Error while initializing bookmarks: %s"), error->message);
+	  g_error_free (error);
+	}
+    }
+}
+
+static void
+vinagre_bookmarks_save_file (VinagreBookmarks *book)
+{
+  gchar    *data;
+  gsize    length;
+  GError   *error;
+
+  error = NULL;
+  data = g_key_file_to_data (book->priv->file,
+			     &length,
+			     &error);
+  if (!data)
+    {
+      if (error)
+	{
+	  g_warning (_("Error while saving bookmarks: %s"), error->message);
+	  g_error_free (error);
+	}
 
-	  vinagre_connection_set_host (conn, host);
-	  vinagre_connection_set_port (conn, port);
+      return;
 
-	  g_free (s_host);
-	  s_host = NULL;
+    }
 
-	  break;
+  error = NULL;
+
+  if (!g_file_set_contents (book->priv->filename,
+			    data,
+			    length,
+			    &error))
+    {
+      if (error)
+	{
+	  g_warning (_("Error while saving bookmarks: %s"), error->message);
+	  g_error_free (error);
+          g_free (data);
+          return;
 	}
+    }
 
-      if (s_host)
-        {
-	  g_free (s_host);
-          s_host = NULL;
-        }
+  g_free (data);
+}
+
+static void
+vinagre_bookmarks_clear_conns (VinagreBookmarks *book)
+{
+  g_slist_foreach (book->priv->conns, (GFunc) g_object_unref, NULL);
+  g_slist_free (book->priv->conns);
+
+  book->priv->conns = NULL;
+}
+
+static void
+vinagre_bookmarks_update_conns (VinagreBookmarks *book)
+{
+  gsize length, i;
+  gchar **conns;
+
+  vinagre_bookmarks_clear_conns (book);
+
+  conns = g_key_file_get_groups (book->priv->file, &length);
+  for (i=0; i<length; i++)
+    {
+      VinagreConnection *conn;
+      gchar *s_value;
+      gint i_value;
+
+      s_value = g_key_file_get_string (book->priv->file, conns[i], "host", NULL);
+      if (!s_value)
+        continue;
+
+      conn = vinagre_connection_new ();
+      vinagre_connection_set_name (conn, conns[i]);
+      vinagre_connection_set_host (conn, s_value);
+      g_free (s_value);
+
+      i_value = g_key_file_get_integer (book->priv->file, conns[i], "port", NULL);
+      if (i_value == 0)
+        i_value = 5900;
+      vinagre_connection_set_port (conn, i_value);
+
+      book->priv->conns = g_slist_prepend (book->priv->conns, conn);
     }
 
-  if (s_host)
-    g_free (s_host);
+  g_strfreev (conns);
+}
 
-  if (conns)
-    g_strfreev (conns);
+static void
+vinagre_bookmarks_file_changed (GFileMonitor      *monitor,
+		                GFile             *file,
+		                GFile             *other_file,
+		                GFileMonitorEvent  event_type,
+		                VinagreBookmarks  *book)
+{
+  if (event_type != G_FILE_MONITOR_EVENT_CHANGED &&
+      event_type != G_FILE_MONITOR_EVENT_CREATED &&
+      event_type != G_FILE_MONITOR_EVENT_DELETED)
+    return;
 
-  return conn;
+  vinagre_bookmarks_update_file (book);
+  vinagre_bookmarks_update_conns (book);
+
+  g_signal_emit (book, signals[BOOKMARK_CHANGED], 0);
 }
+
 /* vim: ts=8 */

Modified: trunk/src/vinagre-bookmarks.h
==============================================================================
--- trunk/src/vinagre-bookmarks.h	(original)
+++ trunk/src/vinagre-bookmarks.h	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-bookmarks.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007  Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008  Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -18,27 +18,61 @@
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef __VINAGRE_FAVORITES_H__
-#define __VINAGRE_FAVORITES_H__
+#ifndef __VINAGRE_BOOKMARKS_H__
+#define __VINAGRE_BOOKMARKS_H__
 
 #include <glib.h>
-#include <gtk/gtk.h>
 
 #include "vinagre-connection.h"
+
+G_BEGIN_DECLS
+
+#define VINAGRE_TYPE_BOOKMARKS             (vinagre_bookmarks_get_type ())
+#define VINAGRE_BOOKMARKS(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), VINAGRE_TYPE_BOOKMARKS, VinagreBookmarks))
+#define VINAGRE_BOOKMARKS_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), VINAGRE_TYPE_BOOKMARKS, VinagreBookmarksClass))
+#define VINAGRE_IS_BOOKMARKS(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VINAGRE_TYPE_BOOKMARKS))
+#define VINAGRE_IS_BOOKMARKS_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), VINAGRE_TYPE_BOOKMARKS))
+#define VINAGRE_BOOKMARKS_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), VINAGRE_TYPE_BOOKMARKS, VinagreBookmarksClass))
+
+typedef struct _VinagreBookmarksClass   VinagreBookmarksClass;
+typedef struct _VinagreBookmarks        VinagreBookmarks;
+typedef struct _VinagreBookmarksPrivate VinagreBookmarksPrivate;
+
+struct _VinagreBookmarksClass
+{
+  GObjectClass parent_class;
+
+  /* Signals */
+  void (* changed) (VinagreBookmarks *book);
+};
+
+struct _VinagreBookmarks
+{
+  GObject parent_instance;
+  VinagreBookmarksPrivate *priv;
+};
+
 #include "vinagre-window.h"
 
-void			vinagre_bookmarks_init		(void);
-void			vinagre_bookmarks_finalize	(void);
+GType vinagre_bookmarks_get_type (void) G_GNUC_CONST;
 
-gboolean		vinagre_bookmarks_add		(VinagreConnection *conn,
-							 VinagreWindow     *window);
-gboolean		vinagre_bookmarks_del		(VinagreConnection *conn,
-							 VinagreWindow     *window);
-gboolean		vinagre_bookmarks_edit		(VinagreConnection *conn,
-							 VinagreWindow     *window);
+VinagreBookmarks   *vinagre_bookmarks_get_default (void);
 
-GList			*vinagre_bookmarks_get_all	(void);
-VinagreConnection	*vinagre_bookmarks_exists	(const char *host, int port);
+gboolean            vinagre_bookmarks_add   (VinagreBookmarks  *book,
+                                             VinagreConnection *conn,
+                                             GtkWindow         *window);
+gboolean            vinagre_bookmarks_del   (VinagreBookmarks  *book,
+                                             VinagreConnection *conn,
+                                             GtkWindow         *window);
+gboolean            vinagre_bookmarks_edit  (VinagreBookmarks  *book,
+                                             VinagreConnection *conn,
+                                             GtkWindow         *window);
+
+GSList             *vinagre_bookmarks_get_all (VinagreBookmarks *book);
+VinagreConnection  *vinagre_bookmarks_exists  (VinagreBookmarks *book,
+                                               const gchar *host,
+                                               gint port);
 
-#endif  /* __VINAGRE_FAVORITES_H__ */
+G_END_DECLS
+#endif  /* __VINAGRE_BOOKMARKS_H__ */
 /* vim: ts=8 */

Modified: trunk/src/vinagre-commands.c
==============================================================================
--- trunk/src/vinagre-commands.c	(original)
+++ trunk/src/vinagre-commands.c	Thu Apr 10 03:35:47 2008
@@ -204,6 +204,33 @@
   vinagre_window_toggle_fullscreen (window);
 }
 
+void
+vinagre_cmd_view_scaling (GtkAction     *action,
+			  VinagreWindow *window)
+{
+  gboolean active;
+
+  g_return_if_fail (VINAGRE_IS_WINDOW (window));
+
+  active = gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action));
+
+  if (active &&
+      gdk_screen_is_composited (gtk_widget_get_screen (GTK_WIDGET (window))))
+    {
+      gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
+      vinagre_utils_show_error (_("Scaling does not work properly on composited windows. Disable the visual effects and try again."),
+				GTK_WINDOW (window));
+      return;
+    }
+
+  if (!vinagre_tab_set_scaling (vinagre_window_get_active_tab (window), active))
+    {
+      gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
+      vinagre_utils_show_error (_("Scaling is not supported on this installation.\n\nRead the README file (shipped with Vinagre) in order to know how to enable this feature."),
+				GTK_WINDOW (window));
+    }
+}
+
 /* Bookmarks Menu */
 void
 vinagre_cmd_open_bookmark (VinagreWindow     *window,
@@ -226,42 +253,58 @@
 vinagre_cmd_bookmarks_add (GtkAction     *action,
 			   VinagreWindow *window)
 {
+  GtkWidget         *tab;
   VinagreConnection *conn;
   gchar             *name;
 
-  conn = vinagre_tab_get_conn (VINAGRE_TAB (window->priv->active_tab));
-  g_return_if_fail (conn != NULL);
-
-  name = vinagre_connection_best_name (conn);
-
-  vinagre_bookmarks_add (conn, window);
-  vinagre_tab_set_title (VINAGRE_TAB (window->priv->active_tab),
-			 name);
+  g_return_if_fail (VINAGRE_IS_WINDOW (window));
 
-  vinagre_fav_update_list (VINAGRE_FAV (window->priv->fav_panel));
-  vinagre_window_update_bookmarks_list_menu (window);
+  tab = window->priv->active_tab;
+  conn = vinagre_tab_get_conn (VINAGRE_TAB (tab));
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
+
+  vinagre_bookmarks_add (vinagre_bookmarks_get_default (),
+                         conn,
+                         GTK_WINDOW (window));
 
-  g_free (name);
+  if (window->priv->active_tab == tab)
+    {
+      name = vinagre_connection_get_best_name (conn);
+      vinagre_tab_set_title (VINAGRE_TAB (window->priv->active_tab),
+			     name);
+      g_free (name);
+    }
 }
 
 void
 vinagre_cmd_bookmarks_edit (GtkAction     *action,
 			    VinagreWindow *window)
 {
-  g_return_if_fail (window->priv->fav_conn_selected != NULL);
+  g_return_if_fail (VINAGRE_IS_WINDOW (window));
+  g_return_if_fail (VINAGRE_IS_CONNECTION (window->priv->fav_conn_selected));
 
-  if (vinagre_bookmarks_edit (window->priv->fav_conn_selected, window))
-    {
-      vinagre_fav_update_list (VINAGRE_FAV (window->priv->fav_panel));
-      vinagre_window_update_bookmarks_list_menu (window);
-    }
+  vinagre_bookmarks_edit (vinagre_bookmarks_get_default (),
+                          window->priv->fav_conn_selected,
+                          GTK_WINDOW (window));
+}
+
+void
+vinagre_cmd_bookmarks_del (GtkAction     *action,
+			   VinagreWindow *window)
+{
+  g_return_if_fail (VINAGRE_IS_WINDOW (window));
+  g_return_if_fail (VINAGRE_IS_CONNECTION (window->priv->fav_conn_selected));
+
+  vinagre_bookmarks_del (vinagre_bookmarks_get_default (),
+                         window->priv->fav_conn_selected,
+                         GTK_WINDOW (window));
 }
 
 void
 vinagre_cmd_bookmarks_open (GtkAction     *action,
 			    VinagreWindow *window)
 {
-  VinagreConnection *conn = NULL;
+  VinagreConnection *conn;
 
   g_return_if_fail (VINAGRE_IS_WINDOW (window));
 
@@ -269,24 +312,11 @@
   if (!conn)
     conn = window->priv->fav_conn_selected;
 
-  g_return_if_fail (conn != NULL);
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
   vinagre_cmd_open_bookmark (window, conn);
 }
 
-void
-vinagre_cmd_bookmarks_del (GtkAction     *action,
-			   VinagreWindow *window)
-{
-  g_return_if_fail (window->priv->fav_conn_selected != NULL);
-
-  if (vinagre_bookmarks_del (window->priv->fav_conn_selected, window))
-    {
-      vinagre_fav_update_list (VINAGRE_FAV (window->priv->fav_panel));
-      vinagre_window_update_bookmarks_list_menu (window);
-    }
-}
-
 /* Make url in about dialog clickable */
 static void
 vinagre_about_dialog_handle_url (GtkAboutDialog *about,

Modified: trunk/src/vinagre-commands.h
==============================================================================
--- trunk/src/vinagre-commands.h	(original)
+++ trunk/src/vinagre-commands.h	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-commands.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -48,6 +48,8 @@
 						 VinagreWindow *window);
 void		vinagre_cmd_view_show_fav_panel	(GtkAction     *action,
 						 VinagreWindow *window);
+void		vinagre_cmd_view_scaling	(GtkAction     *action,
+						 VinagreWindow *window);
 void		vinagre_cmd_view_fullscreen	(GtkAction     *action,
 						 VinagreWindow *window);
 

Modified: trunk/src/vinagre-connect.c
==============================================================================
--- trunk/src/vinagre-connect.c	(original)
+++ trunk/src/vinagre-connect.c	Thu Apr 10 03:35:47 2008
@@ -22,19 +22,12 @@
 #include <glib/gi18n.h>
 #include <glib.h>
 #include <glade/glade.h>
+#include <avahi-ui/avahi-ui.h>
 
 #include "vinagre-connect.h"
 #include "vinagre-utils.h"
 #include "vinagre-bookmarks.h"
 
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef VINAGRE_HAVE_AVAHI
-#include <avahi-ui/avahi-ui.h>
-#endif
-
 typedef struct {
   GladeXML  *xml;
   GtkWidget *dialog;
@@ -43,7 +36,6 @@
   GtkWidget *find_button;
 } VinagreConnectDialog;
 
-#ifdef VINAGRE_HAVE_AVAHI
 static void
 vinagre_connect_find_button_cb (GtkButton            *button,
 				VinagreConnectDialog *dialog)
@@ -73,7 +65,6 @@
 
   gtk_widget_destroy (d);
 }
-#endif
 
 VinagreConnection *vinagre_connect (VinagreWindow *window)
 {
@@ -91,13 +82,11 @@
   dialog.port_entry  = glade_xml_get_widget (dialog.xml, "port_entry");
   dialog.find_button = glade_xml_get_widget (dialog.xml, "find_button");
 
-#ifdef VINAGRE_HAVE_AVAHI
   gtk_widget_show (dialog.find_button);
   g_signal_connect (dialog.find_button,
 		    "clicked",
 		    G_CALLBACK (vinagre_connect_find_button_cb),
 		    &dialog);
-#endif
 
   gtk_widget_show_all (dialog.dialog);
   result = gtk_dialog_run (GTK_DIALOG (dialog.dialog));
@@ -109,7 +98,9 @@
 
       gtk_widget_hide (GTK_WIDGET (dialog.dialog));
 
-      conn = vinagre_bookmarks_exists (host, port);
+      conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (),
+                                       host,
+                                       port);
       if (!conn)
 	{
 	  conn = vinagre_connection_new ();

Modified: trunk/src/vinagre-connection.c
==============================================================================
--- trunk/src/vinagre-connection.c	(original)
+++ trunk/src/vinagre-connection.c	Thu Apr 10 03:35:47 2008
@@ -21,108 +21,401 @@
 #include <stdlib.h>
 #include <glib/gi18n.h>
 #include <gio/gio.h>
+#include <gtk/gtkicontheme.h>
 
 #include "vinagre-connection.h"
+#include "vinagre-enums.h"
 #include "vinagre-bookmarks.h"
 
+struct _VinagreConnectionPrivate
+{
+  VinagreConnectionProtocol protocol;
+  gchar *host;
+  gint   port;
+  gchar *name;
+  gchar *password;
+  gchar *desktop_name;
+};
+
+enum
+{
+  PROP_0,
+  PROP_PROTOCOL,
+  PROP_HOST,
+  PROP_PORT,
+  PROP_NAME,
+  PROP_PASSWORD,
+  PROP_DESKTOP_NAME,
+  PROP_BEST_NAME,
+  PROP_ICON
+};
+
+#define VINAGRE_CONNECTION_PRIVATE(o)  (G_TYPE_INSTANCE_GET_PRIVATE ((o), VINAGRE_TYPE_CONNECTION, VinagreConnectionPrivate))
+G_DEFINE_TYPE (VinagreConnection, vinagre_connection, G_TYPE_OBJECT);
+
+static void
+vinagre_connection_init (VinagreConnection *conn)
+{
+  conn->priv = G_TYPE_INSTANCE_GET_PRIVATE (conn, VINAGRE_TYPE_CONNECTION, VinagreConnectionPrivate);
+
+  conn->priv->protocol = VINAGRE_CONNECTION_PROTOCOL_VNC;
+  conn->priv->host = NULL;
+  conn->priv->port = 0;
+  conn->priv->password = NULL;
+  conn->priv->name = NULL;
+  conn->priv->desktop_name = NULL;
+}
+
+static void
+vinagre_connection_finalize (GObject *object)
+{
+  VinagreConnection *conn = VINAGRE_CONNECTION (object);
+
+  if (conn->priv->host)
+    g_free (conn->priv->host);
+  conn->priv->host = NULL;
+
+  if (conn->priv->password)
+    g_free (conn->priv->password);
+  conn->priv->password = NULL;
+
+  if (conn->priv->name)
+    g_free (conn->priv->name);
+  conn->priv->name = NULL;
+
+  if (conn->priv->desktop_name)
+    g_free (conn->priv->desktop_name);
+  conn->priv->desktop_name = NULL;
+
+  G_OBJECT_CLASS (vinagre_connection_parent_class)->finalize (object);
+}
+
+static void
+vinagre_connection_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
+{
+  VinagreConnection *conn;
+
+  g_return_if_fail (VINAGRE_IS_CONNECTION (object));
+
+  conn = VINAGRE_CONNECTION (object);
+
+  switch (prop_id)
+    {
+      case PROP_PROTOCOL:
+	vinagre_connection_set_protocol (conn, g_value_get_enum (value));
+	break;
+
+      case PROP_HOST:
+	vinagre_connection_set_host (conn, g_value_get_string (value));
+	break;
+
+      case PROP_PORT:
+	vinagre_connection_set_port (conn, g_value_get_int (value));
+	break;
+
+      case PROP_PASSWORD:
+	vinagre_connection_set_password (conn, g_value_get_string (value));
+	break;
+
+      case PROP_NAME:
+	vinagre_connection_set_name (conn, g_value_get_string (value));
+	break;
+
+      case PROP_DESKTOP_NAME:
+	vinagre_connection_set_desktop_name (conn, g_value_get_string (value));
+	break;
+
+      default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;
+    }
+}
+
+static void
+vinagre_connection_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
+{
+  VinagreConnection *conn;
+
+  g_return_if_fail (VINAGRE_IS_CONNECTION (object));
+
+  conn = VINAGRE_CONNECTION (object);
+
+
+  switch (prop_id)
+    {
+      case PROP_PROTOCOL:
+	g_value_set_enum (value, conn->priv->protocol);
+	break;
+
+      case PROP_HOST:
+	g_value_set_string (value, conn->priv->host);
+	break;
+
+      case PROP_PORT:
+	g_value_set_int (value, conn->priv->port);
+	break;
+
+      case PROP_PASSWORD:
+	g_value_set_string (value, conn->priv->password);
+	break;
+
+      case PROP_NAME:
+	g_value_set_string (value, conn->priv->name);
+	break;
+
+      case PROP_DESKTOP_NAME:
+	g_value_set_string (value, conn->priv->desktop_name);
+	break;
+
+      case PROP_BEST_NAME:
+	g_value_set_string (value, vinagre_connection_get_best_name (conn));
+	break;
+
+      case PROP_ICON:
+	g_value_set_object (value, vinagre_connection_get_icon (conn));
+	break;
+
+      default:
+	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+	break;
+    }
+}
+
+static void
+vinagre_connection_class_init (VinagreConnectionClass *klass)
+{
+  GObjectClass* object_class = G_OBJECT_CLASS (klass);
+  GObjectClass* parent_class = G_OBJECT_CLASS (klass);
+
+  g_type_class_add_private (klass, sizeof (VinagreConnectionPrivate));
+
+  object_class->finalize = vinagre_connection_finalize;
+  object_class->set_property = vinagre_connection_set_property;
+  object_class->get_property = vinagre_connection_get_property;
+
+  g_object_class_install_property (object_class,
+                                   PROP_PROTOCOL,
+                                   g_param_spec_enum ("protocol",
+                                                      "protocol",
+	                                              "connection protocol",
+                                                      VINAGRE_TYPE_CONNECTION_PROTOCOL,
+	                                              VINAGRE_CONNECTION_PROTOCOL_VNC,
+	                                              G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT |
+                                                      G_PARAM_STATIC_NICK |
+                                                      G_PARAM_STATIC_NAME |
+                                                      G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_HOST,
+                                   g_param_spec_string ("host",
+                                                        "hostname",
+	                                                "hostname or ip address of this connection",
+                                                        NULL,
+	                                                G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_PORT,
+                                   g_param_spec_int ("port",
+                                                     "port",
+	                                              "tcp/ip port of this connection",
+                                                      0,
+                                                      G_MAXINT,
+                                                      5900,
+	                                              G_PARAM_READWRITE |
+                                                      G_PARAM_CONSTRUCT |
+                                                      G_PARAM_STATIC_NICK |
+                                                      G_PARAM_STATIC_NAME |
+                                                      G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_PASSWORD,
+                                   g_param_spec_string ("password",
+                                                        "password",
+	                                                "password (if any) necessary for complete this connection",
+                                                        NULL,
+	                                                G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_NAME,
+                                   g_param_spec_string ("name",
+                                                        "connection name",
+	                                                "friendly name for this connection",
+                                                        NULL,
+	                                                G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_DESKTOP_NAME,
+                                   g_param_spec_string ("desktop-name",
+                                                        "desktop-name",
+	                                                "name of this connection as reported by the server",
+                                                        NULL,
+	                                                G_PARAM_READWRITE |
+                                                        G_PARAM_CONSTRUCT |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_BEST_NAME,
+                                   g_param_spec_string ("best-name",
+                                                        "best-name",
+	                                                "preferred name for this connection",
+                                                        NULL,
+	                                                G_PARAM_READABLE |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+  g_object_class_install_property (object_class,
+                                   PROP_ICON,
+                                   g_param_spec_object ("icon",
+                                                        "icon",
+	                                                "icon of this connection",
+                                                        GDK_TYPE_PIXBUF,
+	                                                G_PARAM_READABLE |
+                                                        G_PARAM_STATIC_NICK |
+                                                        G_PARAM_STATIC_NAME |
+                                                        G_PARAM_STATIC_BLURB));
+
+}
+
 VinagreConnection *
 vinagre_connection_new ()
 {
-  VinagreConnection *conn;
+  return g_object_new (VINAGRE_TYPE_CONNECTION, NULL);
+}
 
-  conn = g_new (VinagreConnection, 1);
-  conn->host = NULL;
-  conn->port = 0;
-  conn->name = NULL;
-  conn->password = NULL;
-  conn->desktop_name = NULL;
-  conn->type = VINAGRE_CONNECTION_TYPE_VNC;
+void
+vinagre_connection_set_protocol (VinagreConnection *conn,
+			         VinagreConnectionProtocol protocol)
+{
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-  return conn;
+  conn->priv->protocol = protocol;
 }
+VinagreConnectionProtocol
+vinagre_connection_get_protocol (VinagreConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn),
+                        VINAGRE_CONNECTION_PROTOCOL_INVALID);
 
-void 
+  return conn->priv->protocol;
+}
+
+void
 vinagre_connection_set_host (VinagreConnection *conn,
-			     const char *host)
+			     const gchar *host)
 {
-  if (conn->host)
-    g_free (conn->host);
-  conn->host = g_strdup (host);
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
+
+  if (conn->priv->host)
+    g_free (conn->priv->host);
+  conn->priv->host = g_strdup (host);
+}
+const gchar *
+vinagre_connection_get_host (VinagreConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+
+  return conn->priv->host;
 }
 
 void
 vinagre_connection_set_port (VinagreConnection *conn,
-			     int port)
+			     gint port)
 {
-  conn->port = port;
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
+
+  conn->priv->port = port;
+}
+gint
+vinagre_connection_get_port (VinagreConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), 0);
+
+  return conn->priv->port;
 }
 
 void
 vinagre_connection_set_password (VinagreConnection *conn,
-				 const char *password)
+			         const gchar *password)
 {
-  if (conn->password)
-    g_free (conn->password);
-  conn->password = g_strdup (password);
-}
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-void 
-vinagre_connection_set_name (VinagreConnection *conn,
-			     const char *name)
-{
-  if (conn->name)
-    g_free (conn->name);
-  conn->name = g_strdup (name);
+  if (conn->priv->password)
+    g_free (conn->priv->password);
+  conn->priv->password = g_strdup (password);
 }
-
-void 
-vinagre_connection_set_desktop_name (VinagreConnection *conn,
-				     const char *desktop_name)
+const gchar *
+vinagre_connection_get_password (VinagreConnection *conn)
 {
-  if (conn->desktop_name)
-    g_free (conn->desktop_name);
-  conn->desktop_name = g_strdup (desktop_name);
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+
+  return conn->priv->password;
 }
 
 void
-vinagre_connection_free (VinagreConnection *conn)
+vinagre_connection_set_name (VinagreConnection *conn,
+			     const gchar *name)
 {
-  if (conn) {
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-    if (conn->host)
-      g_free (conn->host);
-    conn->host = NULL;
+  if (conn->priv->name)
+    g_free (conn->priv->name);
+  conn->priv->name = g_strdup (name);
+}
+const gchar *
+vinagre_connection_get_name (VinagreConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
 
-    if (conn->password)
-      g_free (conn->password);
-    conn->password = NULL;
+  return conn->priv->name;
+}
 
-    if (conn->name)
-      g_free (conn->name);
-    conn->name = NULL;
+void
+vinagre_connection_set_desktop_name (VinagreConnection *conn,
+			             const gchar *desktop_name)
+{
+  g_return_if_fail (VINAGRE_IS_CONNECTION (conn));
 
-    if (conn->desktop_name)
-      g_free (conn->desktop_name);
-    conn->desktop_name = NULL;
+  if (conn->priv->desktop_name)
+    g_free (conn->priv->desktop_name);
+  conn->priv->desktop_name = g_strdup (desktop_name);
+}
+const gchar *
+vinagre_connection_get_desktop_name (VinagreConnection *conn)
+{
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
 
-    g_free (conn);
-    conn = NULL;
-  }
+  return conn->priv->desktop_name;
 }
 
 gchar *
-vinagre_connection_best_name (VinagreConnection *conn)
+vinagre_connection_get_best_name (VinagreConnection *conn)
 {
-  g_return_val_if_fail (conn != NULL, NULL);
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
 
-  if (conn->name)
-    return g_strdup (conn->name);
+  if (conn->priv->name)
+    return g_strdup (conn->priv->name);
 
-  if (conn->desktop_name)
-    return g_strdup (conn->desktop_name);
+  if (conn->priv->desktop_name)
+    return g_strdup (conn->priv->desktop_name);
 
-  if (conn->host)
-    return g_strdup_printf ("%s:%d", conn->host, conn->port);
+  if (conn->priv->host)
+        return g_strdup_printf ("%s:%d", conn->priv->host, conn->priv->port);
 
   return NULL;
 }
@@ -134,11 +427,11 @@
 
   new_conn = vinagre_connection_new ();
 
-  vinagre_connection_set_host (new_conn, conn->host);
-  vinagre_connection_set_port (new_conn, conn->port);
-  vinagre_connection_set_password (new_conn, conn->password);
-  vinagre_connection_set_name (new_conn, conn->name);
-  vinagre_connection_set_desktop_name (new_conn, conn->desktop_name);
+  vinagre_connection_set_host (new_conn, vinagre_connection_get_host (conn));
+  vinagre_connection_set_port (new_conn, vinagre_connection_get_port (conn));
+  vinagre_connection_set_password (new_conn, vinagre_connection_get_password (conn));
+  vinagre_connection_set_name (new_conn, vinagre_connection_get_name (conn));
+  vinagre_connection_set_desktop_name (new_conn, vinagre_connection_get_desktop_name (conn));
 
   return new_conn;
 }
@@ -172,7 +465,9 @@
   host = server[0];
   port = server[1] ? atoi (server[1]) : 5900;
 
-  conn = vinagre_bookmarks_exists (host, port);
+  conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (),
+                                   host,
+                                   port);
   if (!conn)
     {
       conn = vinagre_connection_new ();
@@ -235,7 +530,9 @@
       port = g_key_file_get_integer (file, "connection", "port", NULL);
       if (host)
 	{
-	  conn = vinagre_bookmarks_exists (host, port);
+	  conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (),
+                                           host,
+                                           port);
 	  if (!conn)
 	    {
 	      conn = vinagre_connection_new ();
@@ -269,6 +566,8 @@
   GdkPixbuf         *pixbuf;
   GtkIconTheme      *icon_theme;
 
+  g_return_val_if_fail (VINAGRE_IS_CONNECTION (conn), NULL);
+
   icon_theme = gtk_icon_theme_get_default ();
   pixbuf = gtk_icon_theme_load_icon (icon_theme,
 				     "application-x-vnc",

Modified: trunk/src/vinagre-connection.h
==============================================================================
--- trunk/src/vinagre-connection.h	(original)
+++ trunk/src/vinagre-connection.h	Thu Apr 10 03:35:47 2008
@@ -24,44 +24,75 @@
 #include <glib.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 
+G_BEGIN_DECLS
+
+#define VINAGRE_TYPE_CONNECTION             (vinagre_connection_get_type ())
+#define VINAGRE_CONNECTION(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), VINAGRE_TYPE_CONNECTION, VinagreConnection))
+#define VINAGRE_CONNECTION_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), VINAGRE_TYPE_CONNECTION, VinagreConnectionClass))
+#define VINAGRE_IS_CONNECTION(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VINAGRE_TYPE_CONNECTION))
+#define VINAGRE_IS_CONNECTION_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), VINAGRE_TYPE_CONNECTION))
+#define VINAGRE_CONNECTION_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), VINAGRE_TYPE_CONNECTION, VinagreConnectionClass))
+
+typedef struct _VinagreConnectionClass   VinagreConnectionClass;
+typedef struct _VinagreConnection        VinagreConnection;
+typedef struct _VinagreConnectionPrivate VinagreConnectionPrivate;
+
 typedef enum
 {
-  VINAGRE_CONNECTION_TYPE_VNC = 0
-} VinagreConnectionType;
+  VINAGRE_CONNECTION_PROTOCOL_VNC = 1,
+  VINAGRE_CONNECTION_PROTOCOL_RDP,
+  VINAGRE_CONNECTION_PROTOCOL_INVALID
+} VinagreConnectionProtocol;
+
+struct _VinagreConnectionClass
+{
+  GObjectClass parent_class;
+};
 
-typedef struct
+struct _VinagreConnection
 {
-  char *host;
-  int   port;
-  char *name;
-  char *password;
-  char *desktop_name;
-  VinagreConnectionType type;
-} VinagreConnection;
+  GObject parent_instance;
+  VinagreConnectionPrivate *priv;
+};
+
+GType vinagre_connection_get_type (void) G_GNUC_CONST;
 
 VinagreConnection *vinagre_connection_new (void);
 
-void		   vinagre_connection_set_host		(VinagreConnection *conn,
-							 const char *host);
-void		   vinagre_connection_set_port		(VinagreConnection *conn,
-							 int port);
-void		   vinagre_connection_set_password	(VinagreConnection *conn,
-							 const char *password);
-void		   vinagre_connection_set_name		(VinagreConnection *conn,
-							 const char *name);
-void		   vinagre_connection_set_desktop_name	(VinagreConnection *conn,
-							 const char *desktop_name);
-
-void               vinagre_connection_free		(VinagreConnection *conn);
+VinagreConnectionProtocol vinagre_connection_get_protocol (VinagreConnection *conn);
+void		          vinagre_connection_set_protocol (VinagreConnection *conn,
+							   VinagreConnectionProtocol protocol);
+
+const gchar*	    vinagre_connection_get_host		(VinagreConnection *conn);
+void		    vinagre_connection_set_host		(VinagreConnection *conn,
+							 const gchar *host);
+
+gint		    vinagre_connection_get_port		(VinagreConnection *conn);
+void		    vinagre_connection_set_port		(VinagreConnection *conn,
+							 gint port);
+
+const gchar*	    vinagre_connection_get_password	(VinagreConnection *conn);
+void		    vinagre_connection_set_password	(VinagreConnection *conn,
+							 const gchar *password);
+
+const gchar*	    vinagre_connection_get_name         (VinagreConnection *conn);
+void		    vinagre_connection_set_name	        (VinagreConnection *conn,
+							 const gchar *name);
+
+const gchar*	    vinagre_connection_get_desktop_name	(VinagreConnection *conn);
+void		    vinagre_connection_set_desktop_name	(VinagreConnection *conn,
+							 const gchar *desktop_name);
+
+gchar*		    vinagre_connection_get_best_name	(VinagreConnection *conn);
 
-gchar             *vinagre_connection_best_name		(VinagreConnection *conn);
+VinagreConnection*  vinagre_connection_clone		(VinagreConnection *conn);
 
-VinagreConnection *vinagre_connection_clone		(VinagreConnection *conn);
+VinagreConnection*  vinagre_connection_new_from_string	(const gchar *url, gchar **error_msg);
+VinagreConnection*  vinagre_connection_new_from_file	(const gchar *uri, gchar **error_msg);
 
-VinagreConnection *vinagre_connection_new_from_string	(const gchar *url, gchar **error_msg);
-VinagreConnection *vinagre_connection_new_from_file	(const gchar *uri, gchar **error_msg);
+GdkPixbuf*          vinagre_connection_get_icon	(VinagreConnection *conn);
 
-GdkPixbuf         *vinagre_connection_get_icon		(VinagreConnection *conn);
+G_END_DECLS
 
 #endif /* __VINAGRE_CONNECTION_H__  */
 /* vim: ts=8 */

Modified: trunk/src/vinagre-fav.c
==============================================================================
--- trunk/src/vinagre-fav.c	(original)
+++ trunk/src/vinagre-fav.c	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-fav.c
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -26,8 +26,10 @@
 #include "vinagre-fav.h"
 #include "vinagre-utils.h"
 #include "vinagre-bookmarks.h"
+#include "vinagre-mdns.h"
 #include "vinagre-window-private.h"
-
+#include "gossip-cell-renderer-expander.h"
+ 
 #define VINAGRE_FAV_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), VINAGRE_TYPE_FAV, VinagreFavPrivate))
 
 struct _VinagreFavPrivate
@@ -35,6 +37,7 @@
   VinagreWindow *window;
   GtkWidget     *tree;
   GtkTreeModel  *model;
+  GtkTreeViewColumn *main_column;
 };
 
 G_DEFINE_TYPE(VinagreFav, vinagre_fav, GTK_TYPE_VBOX)
@@ -52,6 +55,9 @@
   IMAGE_COL = 0,
   NAME_COL,
   CONN_COL,
+  IS_FOLDER_COL,
+  IS_GROUP_COL,
+  IS_AVAHI_COL,
   NUM_COLS
 };
 
@@ -68,8 +74,6 @@
 static void
 vinagre_fav_finalize (GObject *object)
 {
-//  VinagreFav *fav = VINAGRE_FAV (object);
-
   G_OBJECT_CLASS (vinagre_fav_parent_class)->finalize (object);
 }
 
@@ -164,13 +168,25 @@
 {
   GtkTreeIter iter;
   VinagreConnection *conn = NULL;
+  gboolean folder, group;
 
   gtk_tree_model_get_iter (fav->priv->model, &iter, path);
   gtk_tree_model_get (fav->priv->model, 
 		      &iter,
-		      CONN_COL, &conn, 
+		      CONN_COL, &conn,
+                      IS_FOLDER_COL, &folder,
+                      IS_GROUP_COL, &group,
 		      -1);
 
+  if (folder || group)
+    {
+      if (gtk_tree_view_row_expanded (treeview, path))
+        gtk_tree_view_collapse_row (treeview, path);
+      else
+        gtk_tree_view_expand_row (treeview, path, FALSE);
+      return;
+    }
+
   /* Emits the signal saying that user has activated a bookmark */
   g_signal_emit (G_OBJECT (fav), 
 		 signals[FAV_ACTIVATED],
@@ -184,15 +200,20 @@
 {
   GtkTreeIter iter;
   VinagreConnection *conn = NULL;
+  gboolean avahi;
 
   if (gtk_tree_selection_get_selected (selection, NULL, &iter))
     {
       gtk_tree_model_get (fav->priv->model, 
 			  &iter,
-			  CONN_COL, &conn, 
+			  CONN_COL, &conn,
+                          IS_AVAHI_COL, &avahi,
 			  -1);
     }
 
+  if (avahi)
+    conn = NULL;
+
   /* Emits the signal saying that user has selected a bookmark */
   g_signal_emit (G_OBJECT (fav), 
 		 signals[FAV_SELECTED],
@@ -301,36 +322,47 @@
 			GdkEventButton *event,
 			VinagreFav     *fav)
 {
-	if ((GDK_BUTTON_PRESS == event->type) && (3 == event->button))
-	{
-		GtkTreePath* path = NULL;
-		
-		if (event->window == gtk_tree_view_get_bin_window (treeview))
-		{
-			/* Change the cursor position */
-			if (gtk_tree_view_get_path_at_pos (treeview,
-							   event->x,
-							   event->y,
-							   &path,
-							   NULL,
-							   NULL,
-							   NULL))
-			{				
-			
-				gtk_tree_view_set_cursor (treeview,
-							  path,
-							  NULL,
-							  FALSE);
-					
-				gtk_tree_path_free (path);
-							   
-				/* A row exists at mouse position */
-				return show_popup_menu (fav, event);
-			}
-		}
-	}
-	
-	return FALSE;
+  GtkTreePath *path = NULL;
+  GtkTreeIter iter;
+  gboolean folder, group, avahi;
+
+  if (!((GDK_BUTTON_PRESS == event->type) && (3 == event->button)))
+    return FALSE;
+
+  if (event->window == gtk_tree_view_get_bin_window (treeview))
+    {
+    /* Change the cursor position */
+    if (gtk_tree_view_get_path_at_pos (treeview,
+				       event->x,
+				       event->y,
+				       &path,
+				       NULL,
+				       NULL,
+			               NULL))
+      {				
+        gtk_tree_model_get_iter (fav->priv->model, &iter, path);
+        gtk_tree_model_get (fav->priv->model, 
+		            &iter,
+                            IS_FOLDER_COL, &folder,
+                            IS_GROUP_COL, &group,
+                            IS_AVAHI_COL, &avahi,
+		            -1);
+        if (folder || group || avahi)
+          {
+            gtk_tree_path_free (path);
+            return FALSE;
+          }
+
+        gtk_tree_view_set_cursor (treeview,
+				  path,
+				  NULL,
+				  FALSE);
+	 gtk_tree_path_free (path);
+	 /* A row exists at mouse position */
+	 return show_popup_menu (fav, event);
+      }
+    }
+  return FALSE;
 }
 
 
@@ -345,6 +377,222 @@
   return FALSE;
 }
 
+static gboolean
+vinagre_fav_tooltip (GtkWidget *widget,
+                     gint x, gint y, gboolean k,
+                     GtkTooltip *tooltip,
+                     VinagreFav *fav)
+{
+  gchar *tip, *name;
+  GtkTreePath *path = NULL;
+  gint bx, by;
+  GtkTreeIter iter;
+  gboolean folder, group;
+  VinagreConnection *conn = NULL;
+
+  gtk_tree_view_convert_widget_to_bin_window_coords (GTK_TREE_VIEW (widget),
+                                                     x, y,
+                                                     &bx, &by);
+  
+  if (!gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (widget),
+				      bx,
+				      by,
+				      &path,
+				      NULL,
+				      NULL,
+			              NULL))
+    return FALSE;
+
+  gtk_tree_model_get_iter (fav->priv->model, &iter, path);
+  gtk_tree_model_get (fav->priv->model, 
+		      &iter,
+		      CONN_COL, &conn, 
+                      IS_FOLDER_COL, &folder,
+                      IS_GROUP_COL, &group,
+		      -1);
+
+  gtk_tree_path_free (path);
+
+  if (folder || group)
+    return FALSE;
+
+  name = vinagre_connection_get_best_name (conn);
+  tip = g_markup_printf_escaped ("<b>%s</b>\n"
+                                 "<small><b>%s</b> %s</small>\n"
+				 "<small><b>%s</b> %d</small>",
+                                 name,
+				 _("Host:"), vinagre_connection_get_host (conn),
+				 _("Port:"), vinagre_connection_get_port (conn));
+
+  gtk_tooltip_set_markup (tooltip, tip);
+  g_free (tip);
+  g_free (name);
+
+  return TRUE;
+}
+
+static void
+vinagre_fav_indent_level1_cell_data_func (GtkTreeViewColumn *tree_column,
+					  GtkCellRenderer   *cell,
+					  GtkTreeModel      *model,
+					  GtkTreeIter       *iter,
+					  VinagreFav        *fav)
+{
+  GtkTreePath *path;
+  int          depth;
+
+  path = gtk_tree_model_get_path (model, iter);
+  depth = gtk_tree_path_get_depth (path);
+  gtk_tree_path_free (path);
+  g_object_set (cell,
+	        "text", " ",
+		"visible", depth > 1,
+		NULL);
+}
+
+static void
+vinagre_fav_cell_set_background (VinagreFav       *fav,
+				 GtkCellRenderer  *cell,
+				 gboolean         is_group,
+				 gboolean         is_active)
+{
+  GdkColor  color;
+  GtkStyle *style;
+
+  g_return_if_fail (fav != NULL);
+  g_return_if_fail (cell != NULL);
+
+  style = gtk_widget_get_style (GTK_WIDGET (fav));
+
+  if (!is_group)
+    {
+      if (is_active)
+        {
+          color = style->bg[GTK_STATE_SELECTED];
+
+	  /* Here we take the current theme colour and add it to
+	   * the colour for white and average the two. This
+	   * gives a colour which is inline with the theme but
+	   * slightly whiter.
+	   */
+	  color.red = (color.red + (style->white).red) / 2;
+	  color.green = (color.green + (style->white).green) / 2;
+	  color.blue = (color.blue + (style->white).blue) / 2;
+
+	  g_object_set (cell,
+		        "cell-background-gdk", &color,
+		        NULL);
+	
+        }
+      else
+        {
+	  g_object_set (cell,
+	                "cell-background-gdk", NULL,
+		        NULL);
+        }
+      }
+    else
+      {
+        color = style->text_aa[GTK_STATE_INSENSITIVE];
+
+	color.red = (color.red + (style->white).red) / 2;
+	color.green = (color.green + (style->white).green) / 2;
+	color.blue = (color.blue + (style->white).blue) / 2;
+
+	g_object_set (cell,
+		      "cell-background-gdk", &color,
+		      NULL);
+      }
+}
+
+static void
+vinagre_fav_pixbuf_cell_data_func (GtkTreeViewColumn *tree_column,
+				   GtkCellRenderer   *cell,
+				   GtkTreeModel      *model,
+				   GtkTreeIter       *iter,
+				   VinagreFav        *fav)
+{
+  GdkPixbuf *pixbuf;
+  gboolean   is_group;
+  gboolean   is_active;
+
+  gtk_tree_model_get (model, iter,
+		      IS_GROUP_COL, &is_group,
+		      IMAGE_COL, &pixbuf,
+		      -1);
+
+  g_object_set (cell,
+	        "visible", !is_group,
+		"pixbuf", pixbuf,
+		NULL);
+
+  if (pixbuf != NULL)
+    g_object_unref (pixbuf);
+
+  is_active = FALSE;
+  vinagre_fav_cell_set_background (fav, cell, is_group, is_active);
+}
+
+static void
+vinagre_fav_title_cell_data_func (GtkTreeViewColumn *column,
+				  GtkCellRenderer   *renderer,
+				  GtkTreeModel      *tree_model,
+				  GtkTreeIter       *iter,
+				  VinagreFav        *fav)
+{
+  char    *str;
+  gboolean is_group;
+  gboolean is_active;
+
+  gtk_tree_model_get (GTK_TREE_MODEL (fav->priv->model), iter,
+		      NAME_COL, &str,
+		      IS_GROUP_COL, &is_group,
+		      -1);
+
+  g_object_set (renderer,
+	        "text", str,
+		NULL);
+
+  is_active = FALSE;
+  vinagre_fav_cell_set_background (fav, renderer, is_group, is_active);
+
+  g_free (str);
+}
+
+static void
+vinagre_fav_expander_cell_data_func (GtkTreeViewColumn *column,
+				     GtkCellRenderer   *cell,
+				     GtkTreeModel      *model,
+				     GtkTreeIter       *iter,
+				     VinagreFav        *fav)
+{
+  gboolean is_group;
+  gboolean is_active;
+
+  gtk_tree_model_get (model, iter,
+		      IS_GROUP_COL, &is_group,
+		      -1);
+
+  if (gtk_tree_model_iter_has_child (model, iter))
+    {
+      GtkTreePath *path;
+      gboolean     row_expanded;
+
+      path = gtk_tree_model_get_path (model, iter);
+      row_expanded = gtk_tree_view_row_expanded (GTK_TREE_VIEW (column->tree_view), path);
+      gtk_tree_path_free (path);
+
+      g_object_set (cell,
+		    "visible", TRUE,
+		    "expander-style", row_expanded ? GTK_EXPANDER_EXPANDED : GTK_EXPANDER_COLLAPSED,
+		    NULL);
+    }
+  else
+    g_object_set (cell, "visible", FALSE, NULL);
+
+  is_active = FALSE;
+  vinagre_fav_cell_set_background (fav, cell, is_group, is_active);
+}
 
 static void
 vinagre_fav_create_tree (VinagreFav *fav)
@@ -365,31 +613,73 @@
   gtk_box_pack_start (GTK_BOX(fav), scroll, TRUE, TRUE, 0);
 
   /* Create the model */
-  fav->priv->model = GTK_TREE_MODEL (gtk_list_store_new (NUM_COLS,
+  fav->priv->model = GTK_TREE_MODEL (gtk_tree_store_new (NUM_COLS,
 							 GDK_TYPE_PIXBUF,
 							 G_TYPE_STRING,
-							 G_TYPE_POINTER));
+							 VINAGRE_TYPE_CONNECTION,
+                                                         G_TYPE_BOOLEAN,
+                                                         G_TYPE_BOOLEAN,
+                                                         G_TYPE_BOOLEAN));
 
   fav->priv->tree = gtk_tree_view_new_with_model (fav->priv->model);
+  g_object_set (fav->priv->tree, "show-expanders", FALSE, NULL);
   gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (fav->priv->tree), FALSE);
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (fav->priv->tree));
   gtk_tree_selection_set_mode (selection, GTK_SELECTION_SINGLE);
   g_signal_connect (selection, "changed", G_CALLBACK (vinagre_fav_selection_changed_cb), fav);
 
+  fav->priv->main_column = gtk_tree_view_column_new ();
+//  gtk_tree_view_column_set_title (fav->priv->main_column, _("S_ource"));
+  gtk_tree_view_column_set_clickable (fav->priv->main_column, FALSE);
+  gtk_tree_view_append_column (GTK_TREE_VIEW (fav->priv->tree), fav->priv->main_column);
+
+  /* Set up the indent level1 column */
+  cell = gtk_cell_renderer_text_new ();
+  gtk_tree_view_column_pack_start (fav->priv->main_column, cell, FALSE);
+  gtk_tree_view_column_set_cell_data_func (fav->priv->main_column,
+					   cell,
+				           (GtkTreeCellDataFunc) vinagre_fav_indent_level1_cell_data_func,
+				           fav,
+					   NULL);
+  g_object_set (cell,
+		"xpad", 0,
+		"visible", FALSE,
+		NULL);
+
+  /* Set up the pixbuf column */
   cell = gtk_cell_renderer_pixbuf_new ();
-  gtk_tree_view_insert_column_with_attributes ( GTK_TREE_VIEW (fav->priv->tree),
-						-1,
-						_("Image"),
-						cell,
-						"pixbuf", IMAGE_COL,
-						NULL);
+  gtk_tree_view_column_pack_start (fav->priv->main_column, cell, FALSE);
+  gtk_tree_view_column_set_cell_data_func (fav->priv->main_column,
+					   cell,
+					   (GtkTreeCellDataFunc) vinagre_fav_pixbuf_cell_data_func,
+					    fav,
+					    NULL);
+  g_object_set (cell,
+		"xpad", 8,
+		"ypad", 1,
+		"visible", FALSE,
+		NULL);
+
+  /* Set up the name column */
   cell = gtk_cell_renderer_text_new ();
-  gtk_tree_view_insert_column_with_attributes ( GTK_TREE_VIEW (fav->priv->tree),
-						-1,
-						_("Name"),
-						cell,
-						"text", NAME_COL,
-						NULL);
+  g_object_set (cell,
+		"ellipsize", PANGO_ELLIPSIZE_END,
+		 NULL);
+  gtk_tree_view_column_pack_start (fav->priv->main_column, cell, TRUE);
+  gtk_tree_view_column_set_cell_data_func (fav->priv->main_column,
+				           cell,
+					   (GtkTreeCellDataFunc) vinagre_fav_title_cell_data_func,
+					    fav,
+					    NULL);
+
+  /* Expander */
+  cell = gossip_cell_renderer_expander_new ();
+  gtk_tree_view_column_pack_end (fav->priv->main_column, cell, FALSE);
+  gtk_tree_view_column_set_cell_data_func (fav->priv->main_column,
+					   cell,
+				           (GtkTreeCellDataFunc) vinagre_fav_expander_cell_data_func,
+                                           fav,
+					   NULL);
 
   g_signal_connect (fav->priv->tree,
 		    "row-activated",
@@ -406,25 +696,20 @@
 		    G_CALLBACK (fav_popup_menu),
 		    fav);
 
+  gtk_widget_set_has_tooltip (fav->priv->tree, TRUE);
+  g_signal_connect (fav->priv->tree,
+		    "query-tooltip",
+		    G_CALLBACK (vinagre_fav_tooltip),
+		    fav);
 
-  vinagre_fav_update_list (fav);
+  g_idle_add ((GSourceFunc)vinagre_fav_update_list, fav);
 
   gtk_container_add (GTK_CONTAINER(scroll), fav->priv->tree);
+
   gtk_widget_show (fav->priv->tree);
   g_object_unref (G_OBJECT (fav->priv->model));
 }
 
-
-static void
-vinagre_fav_hide (GtkButton *button, VinagreFav *fav)
-{
-  GtkAction *action;
-
-  action = gtk_action_group_get_action (fav->priv->window->priv->always_sensitive_action_group,
-					"ViewBookmarks");
-  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), FALSE);
-}
-
 static void
 vinagre_fav_init (VinagreFav *fav)
 {
@@ -432,25 +717,17 @@
 
   fav->priv = VINAGRE_FAV_GET_PRIVATE (fav);
 
-  /* setup label */
-  label_box = gtk_hbox_new (FALSE, 0);
-  label = gtk_label_new (_("Bookmarks"));
-  gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
-  gtk_misc_set_padding (GTK_MISC (label), 6, 6);
-  gtk_box_pack_start (GTK_BOX(label_box), label, TRUE, TRUE, 0);
-
-  /* setup small close button */
-  close_button = vinagre_utils_create_small_close_button ();
-  gtk_box_pack_start (GTK_BOX(label_box), close_button, FALSE, FALSE, 0);
-  gtk_widget_set_tooltip_text (close_button, _("Hide bookmarks"));
-  gtk_box_pack_start (GTK_BOX(fav), label_box, FALSE, FALSE, 0);
-  g_signal_connect (close_button,
-		    "clicked",
-		    G_CALLBACK (vinagre_fav_hide),
-		    fav);
-
   /* setup the tree */
   vinagre_fav_create_tree (fav);
+
+  g_signal_connect_swapped (vinagre_bookmarks_get_default (),
+                            "changed",
+                            G_CALLBACK (vinagre_fav_update_list),
+                            fav);
+  g_signal_connect_swapped (vinagre_mdns_get_default (),
+                            "changed",
+                            G_CALLBACK (vinagre_fav_update_list),
+                            fav);
 }
 
 GtkWidget *
@@ -463,41 +740,108 @@
 				   NULL));
 }
 
-void
+gboolean
 vinagre_fav_update_list (VinagreFav *fav)
 {
-  GtkTreeIter        iter;
-  GtkListStore      *store;
-  GList             *list;
-  VinagreConnection *conn;
-  gchar             *name;
+  GtkTreeIter        iter, parent_iter;
+  GtkTreeStore      *store;
+  GSList            *list, *l, *next;
   GdkPixbuf         *pixbuf;
+  GtkTreePath       *path;
+    
+  g_return_val_if_fail (VINAGRE_IS_FAV (fav), FALSE);
+
+  store = GTK_TREE_STORE (fav->priv->model);
+  gtk_tree_store_clear (store);
+
+  /* bookmarks */
+  list = vinagre_bookmarks_get_all (vinagre_bookmarks_get_default ());
+
+  gtk_tree_store_append (store, &parent_iter, NULL);
+  gtk_tree_store_set (store, &parent_iter,
+                      NAME_COL, _("Bookmarks"),
+                      IS_GROUP_COL, TRUE,
+                      IS_FOLDER_COL, FALSE,
+                      IS_AVAHI_COL, FALSE,
+                      -1);
 
-  g_return_if_fail (VINAGRE_IS_FAV (fav));
+  for (l = list; l; l = next)
+    {
+      gchar *name = NULL;
+      VinagreConnection *conn;
 
-  store = GTK_LIST_STORE (fav->priv->model);
-  gtk_list_store_clear (store);
+      next = l->next;
+
+      conn = (VinagreConnection *) l->data;
+      g_assert (VINAGRE_IS_CONNECTION (conn));
+
+      name = vinagre_connection_get_best_name (conn);
+      pixbuf = vinagre_connection_get_icon (conn);
 
-  list = vinagre_bookmarks_get_all ();
-  while (list)
+      gtk_tree_store_append (store, &iter, &parent_iter);
+      gtk_tree_store_set (store, &iter,
+                          IMAGE_COL, pixbuf,
+                          NAME_COL, name,
+                          CONN_COL, conn,
+                          IS_FOLDER_COL, FALSE,
+                          IS_GROUP_COL, FALSE,
+                          IS_AVAHI_COL, FALSE,
+                          -1);
+      if (name)
+        g_free (name);
+      if (pixbuf != NULL)
+	g_object_unref (pixbuf);
+    }
+
+  path = gtk_tree_path_new_from_string ("0");
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fav->priv->tree), path, FALSE);
+  g_free (path);
+
+  /* avahi */
+  list = vinagre_mdns_get_all (vinagre_mdns_get_default ());
+  if (!list)
+    return FALSE;
+
+  gtk_tree_store_append (store, &parent_iter, NULL);
+  gtk_tree_store_set (store, &parent_iter,
+                      NAME_COL, _("Hosts near to me"),
+                      IS_GROUP_COL, TRUE,
+                      IS_FOLDER_COL, FALSE,
+                      IS_AVAHI_COL, FALSE,
+                      -1);
+
+  for (l = list; l; l = next)
     {
-      conn = (VinagreConnection *) list->data;
-      name = vinagre_connection_best_name (conn);
+      gchar *name = NULL;
+      VinagreConnection *conn;
+
+      next = l->next;
 
+      conn = (VinagreConnection *) l->data;
+      g_assert (VINAGRE_IS_CONNECTION (conn));
+
+      name = vinagre_connection_get_best_name (conn);
       pixbuf = vinagre_connection_get_icon (conn);
 
-      gtk_list_store_append (store, &iter);
-      gtk_list_store_set (store, &iter,
+      gtk_tree_store_append (store, &iter, &parent_iter);
+      gtk_tree_store_set (store, &iter,
                           IMAGE_COL, pixbuf,
                           NAME_COL, name,
                           CONN_COL, conn,
+                          IS_FOLDER_COL, FALSE,
+                          IS_GROUP_COL, FALSE,
+                          IS_AVAHI_COL, TRUE,
                           -1);
-      list = list->next;
-      g_free (name);
+      if (name)
+        g_free (name);
       if (pixbuf != NULL)
 	g_object_unref (pixbuf);
     }
 
-  g_list_free (list);
+  path = gtk_tree_path_new_from_string ("1");
+  gtk_tree_view_expand_row (GTK_TREE_VIEW (fav->priv->tree), path, FALSE);
+  g_free (path);
+
+  return FALSE;
 }
 /* vim: ts=8 */

Modified: trunk/src/vinagre-fav.h
==============================================================================
--- trunk/src/vinagre-fav.h	(original)
+++ trunk/src/vinagre-fav.h	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-fav.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -50,18 +50,18 @@
   GtkVBoxClass parent_class;
 
   /* Signals */
-  void		(* fav_activated)		(VinagreFav *fav,
-						 VinagreConnection *conn);
+  void	(* fav_activated)   (VinagreFav *fav,
+			     VinagreConnection *conn);
 
-  void		(* fav_selected)		(VinagreFav *fav,
-						 VinagreConnection *conn);
+  void	(* fav_selected)    (VinagreFav *fav,
+			    VinagreConnection *conn);
 };
 
-GType 		vinagre_fav_get_type 		(void) G_GNUC_CONST;
+GType 	    vinagre_fav_get_type    (void) G_GNUC_CONST;
 
-GtkWidget 	*vinagre_fav_new 		(VinagreWindow *window);
+GtkWidget   *vinagre_fav_new        (VinagreWindow *window);
 
-void		vinagre_fav_update_list		(VinagreFav *fav);
+gboolean    vinagre_fav_update_list (VinagreFav *fav);
 
 G_END_DECLS
 

Modified: trunk/src/vinagre-main.c
==============================================================================
--- trunk/src/vinagre-main.c	(original)
+++ trunk/src/vinagre-main.c	Thu Apr 10 03:35:47 2008
@@ -30,6 +30,7 @@
 #include "vinagre-bookmarks.h"
 #include "vinagre-window.h"
 #include "vinagre-utils.h"
+#include <vncdisplay.h>
 
 /* command line */
 static gchar **files = NULL;
@@ -121,6 +122,7 @@
   context = g_option_context_new (_("- VNC Client for GNOME"));
   g_option_context_add_main_entries (context, options, GETTEXT_PACKAGE);
   g_option_context_add_group (context, gtk_get_option_group (TRUE));
+  g_option_context_add_group (context, vnc_display_get_option_group ());
   g_option_context_parse (context, &argc, &argv, &error);
   if (error)
     {
@@ -141,6 +143,8 @@
   main_window = vinagre_window_new ();
   gtk_widget_show (GTK_WIDGET(main_window));
 
+  vinagre_utils_handle_debug ();
+
   vinagre_main_process_command_line (main_window);
   for (l = servers; l; l = next)
     {

Modified: trunk/src/vinagre-notebook.c
==============================================================================
--- trunk/src/vinagre-notebook.c	(original)
+++ trunk/src/vinagre-notebook.c	Thu Apr 10 03:35:47 2008
@@ -94,7 +94,7 @@
 {
   gchar *message, *name;
 
-  name = vinagre_connection_best_name (vinagre_tab_get_conn (tab));
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
   message = g_strdup_printf (_("Connection to host \"%s\" was closed."),
 			     name);
   vinagre_utils_show_error (message, GTK_WINDOW (nb->priv->window));
@@ -157,7 +157,7 @@
   gtk_box_pack_start (GTK_BOX (label_hbox), icon, FALSE, FALSE, 0);
 	
   /* setup label */
-  name = vinagre_connection_best_name (vinagre_tab_get_conn (tab));
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
   label = gtk_label_new (name);
   g_free (name);
   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);

Modified: trunk/src/vinagre-tab.c
==============================================================================
--- trunk/src/vinagre-tab.c	(original)
+++ trunk/src/vinagre-tab.c	Thu Apr 10 03:35:47 2008
@@ -44,6 +44,7 @@
   guint              status_id;
   gboolean           save_password;
   guint32            keyring_item_id;
+  VinagreTabState    state;
 };
 
 G_DEFINE_TYPE(VinagreTab, vinagre_tab, GTK_TYPE_VBOX)
@@ -98,13 +99,13 @@
 
   if (event->new_window_state & GDK_WINDOW_STATE_FULLSCREEN)
     {
-      vnc_display_set_pointer_grab  (VNC_DISPLAY(tab->priv->vnc), TRUE);
+      vnc_display_force_grab  (VNC_DISPLAY(tab->priv->vnc), TRUE);
       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tab->priv->scroll),
 				      h, v);
     }
   else
     {
-      vnc_display_set_pointer_grab  (VNC_DISPLAY(tab->priv->vnc), FALSE);
+      vnc_display_force_grab  (VNC_DISPLAY(tab->priv->vnc), FALSE);
       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (tab->priv->scroll),
 				      GTK_POLICY_AUTOMATIC,
 				      GTK_POLICY_AUTOMATIC);
@@ -124,10 +125,10 @@
   switch (prop_id)
     {
       case PROP_CONN:
-        g_value_set_pointer (value, tab->priv->conn);
+        g_value_set_object (value, tab->priv->conn);
 	break;
       case PROP_WINDOW:
-        g_value_set_pointer (value, tab->priv->window);
+        g_value_set_object (value, tab->priv->window);
 	break;
       default:
 	G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@@ -146,10 +147,10 @@
   switch (prop_id)
     {
       case PROP_CONN:
-        tab->priv->conn = g_value_get_pointer (value);
+        tab->priv->conn = g_value_get_object (value);
         break;
       case PROP_WINDOW:
-        tab->priv->window = g_value_get_pointer (value);
+        tab->priv->window = g_value_get_object (value);
 	g_signal_connect (tab->priv->window,
 			  "window-state-event",
 			  G_CALLBACK (vinagre_tab_window_state_cb),
@@ -173,7 +174,8 @@
   g_signal_handlers_disconnect_by_func (tab->priv->window,
   					vinagre_tab_window_state_cb,
   					tab);
-  vinagre_connection_free (tab->priv->conn);
+  g_object_unref (tab->priv->conn);
+  tab->priv->conn = NULL;
 	
   G_OBJECT_CLASS (vinagre_tab_parent_class)->finalize (object);
 }
@@ -189,24 +191,26 @@
 
   g_object_class_install_property (object_class,
 				   PROP_CONN,
-				   g_param_spec_pointer ("conn",
-							 "Connection",
-							 "The connection",
-							 G_PARAM_READWRITE |
-							 G_PARAM_CONSTRUCT_ONLY |
-							 G_PARAM_STATIC_NAME |
-							 G_PARAM_STATIC_NICK |
-							 G_PARAM_STATIC_BLURB));
+				   g_param_spec_object ("conn",
+							"Connection",
+							"The connection",
+							VINAGRE_TYPE_CONNECTION,
+							G_PARAM_READWRITE |
+							G_PARAM_CONSTRUCT_ONLY |
+							G_PARAM_STATIC_NAME |
+							G_PARAM_STATIC_NICK |
+							G_PARAM_STATIC_BLURB));
   g_object_class_install_property (object_class,
 				   PROP_WINDOW,
-				   g_param_spec_pointer ("window",
-							 "Window",
-							 "The VinagreWindow",
-							 G_PARAM_READWRITE |
-							 G_PARAM_CONSTRUCT_ONLY |
-							 G_PARAM_STATIC_NAME |
-							 G_PARAM_STATIC_NICK |
-							 G_PARAM_STATIC_BLURB));
+				   g_param_spec_object ("window",
+							"Window",
+							"The VinagreWindow",
+							VINAGRE_TYPE_WINDOW,
+							G_PARAM_READWRITE |
+							G_PARAM_CONSTRUCT_ONLY |
+							G_PARAM_STATIC_NAME |
+							G_PARAM_STATIC_NICK |
+							G_PARAM_STATIC_BLURB));
 
   signals[TAB_CONNECTED] =
 		g_signal_new ("tab-connected",
@@ -249,9 +253,9 @@
   tab->priv->status = GTK_STATUSBAR (vinagre_window_get_statusbar (tab->priv->window));
   tab->priv->status_id = gtk_statusbar_get_context_id (tab->priv->status, "VNC Widget Messages");
   
-  port = g_strdup_printf ("%d", tab->priv->conn->port);
+  port = g_strdup_printf ("%d", vinagre_connection_get_port (tab->priv->conn));
   
-  if (!vnc_display_open_host (VNC_DISPLAY(tab->priv->vnc), tab->priv->conn->host, port))
+  if (!vnc_display_open_host (VNC_DISPLAY(tab->priv->vnc), vinagre_connection_get_host (tab->priv->conn), port))
     vinagre_utils_show_error (_("Error connecting to host."), NULL);
 
   vnc_display_set_pointer_local (VNC_DISPLAY(tab->priv->vnc), TRUE);
@@ -285,7 +289,7 @@
   gchar   *name;
 
   message = g_string_new (NULL);
-  name = vinagre_connection_best_name (vinagre_tab_get_conn (tab));
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
 
   g_string_printf (message, _("Authentication to host \"%s\" has failed"),
 		   name);
@@ -313,7 +317,7 @@
   gchar   *name;
 
   message = g_string_new (NULL);
-  name = vinagre_connection_best_name (vinagre_tab_get_conn (tab));
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (tab));
 
   g_string_printf (message, _("Authentication method to host \"%s\" is unsupported. (%u)"),
 		   name,
@@ -360,9 +364,11 @@
   data = g_slice_new (GtkRecentData);
 
   uri = g_string_new (NULL);
-  g_string_printf (uri, "vnc://%s:%d", tab->priv->conn->host, tab->priv->conn->port);
+  g_string_printf (uri, "vnc://%s:%d",
+                   vinagre_connection_get_host (tab->priv->conn),
+                   vinagre_connection_get_port (tab->priv->conn));
 
-  data->display_name = vinagre_connection_best_name (tab->priv->conn);
+  data->display_name = vinagre_connection_get_best_name (tab->priv->conn);
   data->description = NULL;
   data->mime_type = g_strdup ("application/x-remote-connection");
   data->app_name = (gchar *) g_get_application_name ();
@@ -393,12 +399,12 @@
                 NULL,           /* default keyring */
                 NULL,           /* user            */
                 NULL,           /* domain          */
-                tab->priv->conn->host,   /* server          */
+                vinagre_connection_get_host (tab->priv->conn),   /* server          */
                 NULL,           /* object          */
                 "rfb",          /* protocol        */
                 "vnc-password", /* authtype        */
-                tab->priv->conn->port,           /* port            */
-                tab->priv->conn->password,       /* password        */
+                vinagre_connection_get_port (tab->priv->conn),           /* port            */
+                vinagre_connection_get_password (tab->priv->conn),       /* password        */
                 &tab->priv->keyring_item_id);
 
   if (result != GNOME_KEYRING_RESULT_OK)
@@ -421,11 +427,11 @@
   result = gnome_keyring_find_network_password_sync (
                 NULL,           /* user     */
 		NULL,           /* domain   */
-		tab->priv->conn->host,   /* server   */
+		vinagre_connection_get_host (tab->priv->conn),   /* server   */
 		NULL,           /* object   */
 		"rfb",          /* protocol */
 		"vnc-password", /* authtype */
-		tab->priv->conn->port,           /* port     */
+		vinagre_connection_get_port (tab->priv->conn),           /* port     */
 		&matches);
 
   if (result != GNOME_KEYRING_RESULT_OK || matches == NULL || matches->data == NULL)
@@ -450,7 +456,7 @@
   vinagre_connection_set_desktop_name (tab->priv->conn,
 				       vnc_display_get_name (VNC_DISPLAY (tab->priv->vnc)));
 
-  name = vinagre_connection_best_name (tab->priv->conn);
+  name = vinagre_connection_get_best_name (tab->priv->conn);
   label = g_object_get_data (G_OBJECT (tab), "label");
   g_return_if_fail (label != NULL);
   gtk_label_set_label (label, name);
@@ -464,7 +470,8 @@
 		      tab->priv->status_id,
 		      _("Press Ctrl+Alt to grab the cursor"));
 
-  _vinagre_window_add_machine_connected (tab->priv->window);
+  tab->priv->state = VINAGRE_TAB_STATE_CONNECTED;
+  vinagre_window_update_machine_menu_sensitivity (tab->priv->window);
 
   /* Emits the signal saying that we have connected to the machine */
   g_signal_emit (G_OBJECT (tab),
@@ -488,7 +495,7 @@
   gtk_window_set_transient_for (GTK_WINDOW(password_dialog), GTK_WINDOW(tab->priv->window));
 
   host_label = glade_xml_get_widget (xml, "host_label");
-  name = vinagre_connection_best_name (tab->priv->conn);
+  name = vinagre_connection_get_best_name (tab->priv->conn);
   gtk_label_set_text (GTK_LABEL (host_label), name);
   g_free (name);
 
@@ -531,7 +538,6 @@
 
 static void vnc_grab_cb (VncDisplay *vnc, VinagreTab *tab)
 {
-
   gtk_statusbar_pop (tab->priv->status,
 		     tab->priv->status_id);
 
@@ -572,15 +578,12 @@
 static void
 vinagre_tab_init (VinagreTab *tab)
 {
-  GtkWidget *align;
   GtkWidget *viewport;
 
   tab->priv = VINAGRE_TAB_GET_PRIVATE (tab);
   tab->priv->save_password = FALSE;
   tab->priv->keyring_item_id = 0;
-
-  /* Create the alignment */
-  align = gtk_alignment_new (0.5, 0.5, 0, 0);
+  tab->priv->state = VINAGRE_TAB_STATE_INITIALIZING;
 
   /* Create the scrolled window */
   tab->priv->scroll = gtk_scrolled_window_new (NULL, NULL);
@@ -594,10 +597,9 @@
 
   /* Create the vnc widget */
   tab->priv->vnc = vnc_display_new ();
-  gtk_container_add (GTK_CONTAINER (align), tab->priv->vnc);
 
   gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (tab->priv->scroll),
-					 align);
+					 tab->priv->vnc);
   viewport = gtk_bin_get_child (GTK_BIN (tab->priv->scroll));
   gtk_viewport_set_shadow_type(GTK_VIEWPORT (viewport), GTK_SHADOW_NONE);
 
@@ -679,8 +681,8 @@
 				  "<b>%s</b> %d\n"
 				  "<b>%s</b> %dx%d",
 				  _("Desktop Name:"), vnc_display_get_name (VNC_DISPLAY (tab->priv->vnc)),
-				  _("Host:"), tab->priv->conn->host,
-				  _("Port:"), tab->priv->conn->port,
+				  _("Host:"), vinagre_connection_get_host (tab->priv->conn),
+				  _("Port:"), vinagre_connection_get_port (tab->priv->conn),
 				  _("Dimensions:"), vnc_display_get_width (VNC_DISPLAY (tab->priv->vnc)), vnc_display_get_height (VNC_DISPLAY (tab->priv->vnc)));
 
   return tip;
@@ -746,7 +748,7 @@
   pix = vnc_display_get_pixbuf (VNC_DISPLAY (tab->priv->vnc));
 
   filename = NULL;
-  name = vinagre_connection_best_name (tab->priv->conn);
+  name = vinagre_connection_get_best_name (tab->priv->conn);
   suggested_filename = g_string_new (NULL);
   g_string_printf (suggested_filename, _("Screenshot of %s"), name);
   g_string_append (suggested_filename, ".png");
@@ -795,4 +797,29 @@
     }
 }
 
+gboolean
+vinagre_tab_set_scaling (VinagreTab *tab, gboolean active) {
+  g_return_if_fail (VINAGRE_IS_TAB (tab));
+
+  if (vnc_display_get_scaling (VNC_DISPLAY (tab->priv->vnc)) == active)
+    return TRUE;
+
+  return vnc_display_set_scaling (VNC_DISPLAY (tab->priv->vnc), active);
+}
+
+gboolean
+vinagre_tab_get_scaling (VinagreTab *tab) {
+  g_return_if_fail (VINAGRE_IS_TAB (tab));
+
+  return vnc_display_get_scaling (VNC_DISPLAY (tab->priv->vnc));
+}
+
+VinagreTabState
+vinagre_tab_get_state (VinagreTab *tab)
+{
+  g_return_if_fail (VINAGRE_IS_TAB (tab));
+
+  return tab->priv->state;
+}
+
 /* vim: ts=8 */

Modified: trunk/src/vinagre-tab.h
==============================================================================
--- trunk/src/vinagre-tab.h	(original)
+++ trunk/src/vinagre-tab.h	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-tab.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,14 @@
 #include "vinagre-notebook.h"
 #include "vinagre-window.h"
 
+typedef enum
+{
+  VINAGRE_TAB_STATE_INITIALIZING = 1,
+  VINAGRE_TAB_STATE_CONNECTED,
+  VINAGRE_TAB_STATE_INVALID
+} VinagreTabState;
+
+
 struct _VinagreTab 
 {
   GtkVBox vbox;
@@ -78,6 +86,13 @@
 void		  vinagre_tab_take_screenshot	(VinagreTab *tab);
 void		  vinagre_tab_paste_text	(VinagreTab *tab,
 						 const gchar *text);
+
+gboolean	  vinagre_tab_set_scaling	(VinagreTab *tab, gboolean active);
+gboolean	  vinagre_tab_get_scaling	(VinagreTab *tab);
+
+VinagreTabState   vinagre_tab_get_state		(VinagreTab *tab);
+
 G_END_DECLS
 
 #endif  /* __VINAGRE_TAB_H__  */
+/* vim: ts=8 */

Modified: trunk/src/vinagre-ui.h
==============================================================================
--- trunk/src/vinagre-ui.h	(original)
+++ trunk/src/vinagre-ui.h	Thu Apr 10 03:35:47 2008
@@ -2,7 +2,7 @@
  * vinagre-ui.h
  * This file is part of vinagre
  *
- * Copyright (C) 2007 - Jonh Wendell <wendell bani com br>
+ * Copyright (C) 2007,2008 - Jonh Wendell <wendell bani com br>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -84,6 +84,13 @@
     N_("View the current machine in full screen"), G_CALLBACK (vinagre_cmd_view_fullscreen) },
 };
 
+static const GtkToggleActionEntry vinagre_machine_connected_toggle_menu_entries[] =
+{
+  { "ViewScaling", NULL, N_("S_caling"), NULL,
+    N_("Fit the remote screen into the current window size"),
+    G_CALLBACK (vinagre_cmd_view_scaling), FALSE }
+};
+
 static const GtkToggleActionEntry vinagre_always_sensitive_toggle_menu_entries[] =
 {
   { "ViewToolbar", NULL, N_("_Toolbar"), NULL,
@@ -94,8 +101,8 @@
     N_("Show or hide the statusbar"),
     G_CALLBACK (vinagre_cmd_view_show_statusbar), FALSE },
 
-  { "ViewBookmarks", NULL, N_("_Bookmarks"), "F9",
-    N_("Show or hide the bookmarks panel"),
+  { "ViewSidePanel", NULL, N_("Side _Panel"), "F9",
+    N_("Show or hide the side panel"),
     G_CALLBACK (vinagre_cmd_view_show_fav_panel), FALSE }
 };
 

Modified: trunk/src/vinagre-utils.c
==============================================================================
--- trunk/src/vinagre-utils.c	(original)
+++ trunk/src/vinagre-utils.c	Thu Apr 10 03:35:47 2008
@@ -156,4 +156,29 @@
   vinagre_utils_show_error (msg->str, parent);
   g_string_free (msg, TRUE);
 }
+
+
+static void _default_log (const gchar *log_domain G_GNUC_UNUSED,
+			 GLogLevelFlags log_level G_GNUC_UNUSED,
+			 const gchar *message,
+			 gpointer user_data G_GNUC_UNUSED)
+{
+  printf ("gtk-vnc: %s", message);
+}
+
+void
+vinagre_utils_handle_debug (void)
+{
+  static gboolean initialized = FALSE;
+
+  if (initialized)
+    return;
+
+  g_log_set_handler ("gtk-vnc",
+		     G_LOG_LEVEL_DEBUG,
+		     _default_log,
+		     NULL);
+
+  initialized = TRUE;
+}
 /* vim: ts=8 */

Modified: trunk/src/vinagre-utils.h
==============================================================================
--- trunk/src/vinagre-utils.h	(original)
+++ trunk/src/vinagre-utils.h	Thu Apr 10 03:35:47 2008
@@ -41,5 +41,6 @@
 gchar		*vinagre_utils_escape_underscores	(const gchar *text,
 							 gssize      length);
 
+void		vinagre_utils_handle_debug		(void);
 #endif  /* __VINAGRE_UTILS_H__  */
 /* vim: ts=8 */

Modified: trunk/src/vinagre-window-private.h
==============================================================================
--- trunk/src/vinagre-window-private.h	(original)
+++ trunk/src/vinagre-window-private.h	Thu Apr 10 03:35:47 2008
@@ -46,6 +46,7 @@
   GtkActionGroup *bookmarks_list_action_group;
   GtkActionGroup *recent_action_group;
   GtkAction      *recent_action;
+  GtkAction      *scaling_action;
   guint           bookmarks_list_menu_ui_id;
   guint           recents_menu_ui_id;
 
@@ -67,7 +68,6 @@
 
   gulong	  signal_notebook;
   gulong	  signal_clipboard;
-  gint            machines_connected;
 };
 
 

Modified: trunk/src/vinagre-window.c
==============================================================================
--- trunk/src/vinagre-window.c	(original)
+++ trunk/src/vinagre-window.c	Thu Apr 10 03:35:47 2008
@@ -36,6 +36,7 @@
 #include "vinagre-utils.h"
 #include "vinagre-bookmarks.h"
 #include "vinagre-ui.h"
+#include "vinagre-mdns.h"
 
 #include "vinagre-window-private.h"
 
@@ -52,7 +53,7 @@
 
   if (window->priv->fav_conn_selected)
     {
-      vinagre_connection_free (window->priv->fav_conn_selected);
+      g_object_unref (window->priv->fav_conn_selected);
       window->priv->fav_conn_selected = NULL;
     }
 
@@ -62,9 +63,6 @@
       window->priv->manager = NULL;
     }
 
-
-  vinagre_bookmarks_finalize ();
-
   G_OBJECT_CLASS (vinagre_window_parent_class)->finalize (object);
 }
 
@@ -183,7 +181,8 @@
   switch (event->keyval)
     {
       case GDK_F11:
-	if (window->priv->active_tab)
+	if (window->priv->active_tab &&
+	    (vinagre_tab_get_state (VINAGRE_TAB (window->priv->active_tab)) == VINAGRE_TAB_STATE_CONNECTED))
 	  vinagre_window_toggle_fullscreen (window);
 	return FALSE;
     }
@@ -275,7 +274,7 @@
   if (conn)
     {
       vinagre_cmd_open_bookmark (window, conn);
-      vinagre_connection_free (conn);
+      g_object_unref (conn);
     }
   else
     {
@@ -384,10 +383,15 @@
 				vinagre_machine_connected_menu_entries,
 				G_N_ELEMENTS (vinagre_machine_connected_menu_entries),
 				window);
+  gtk_action_group_add_toggle_actions  (action_group,
+					vinagre_machine_connected_toggle_menu_entries,
+					G_N_ELEMENTS (vinagre_machine_connected_toggle_menu_entries),
+					window);
 
   gtk_ui_manager_insert_action_group (manager, action_group, 0);
   g_object_unref (action_group);
   window->priv->machine_connected_action_group = action_group;
+  window->priv->scaling_action = gtk_action_group_get_action (action_group, "ViewScaling");
 
   action = gtk_action_group_get_action (action_group, "ViewFullScreen");
   g_object_set (action, "is_important", TRUE, NULL);
@@ -465,8 +469,8 @@
 
 }
 
-static void
-set_machine_menu_sensitivity (VinagreWindow *window)
+void
+vinagre_window_update_machine_menu_sensitivity (VinagreWindow *window)
 {
   gboolean active;
 
@@ -475,7 +479,8 @@
   active = gtk_notebook_get_n_pages (GTK_NOTEBOOK (window->priv->notebook)) > 0;
   gtk_action_group_set_sensitive (window->priv->action_group, active);
 
-  active = window->priv->machines_connected > 0;
+  active = (window->priv->active_tab) &&
+	   (vinagre_tab_get_state (VINAGRE_TAB (window->priv->active_tab)) == VINAGRE_TAB_STATE_CONNECTED);
   gtk_action_group_set_sensitive (window->priv->machine_connected_action_group, active);
 }
 
@@ -514,7 +519,7 @@
 
   if (window->priv->fav_conn_selected)
     {
-      vinagre_connection_free (window->priv->fav_conn_selected);
+      g_object_unref (window->priv->fav_conn_selected);
       window->priv->fav_conn_selected = NULL;
     }
 
@@ -537,13 +542,10 @@
 vinagre_window_update_bookmarks_list_menu (VinagreWindow *window)
 {
   VinagreWindowPrivate *p = window->priv;
-  GList                *actions, *l, *favs;
-  gint                  n, i;
-  guint                 id;
-  VinagreConnection    *conn;
-  gchar                *action_name, *action_label;
-  GtkAction            *action;
-  gchar                *name, *tooltip;
+  GList  *actions, *l;
+  GSList *favs, *mdnss;
+  gint   n, m, i;
+  guint  id;
 
   g_return_if_fail (p->bookmarks_list_action_group != NULL);
 
@@ -559,38 +561,42 @@
       gtk_action_group_remove_action (p->bookmarks_list_action_group,
 				      GTK_ACTION (l->data));
     }
-    g_list_free (actions);
+  g_list_free (actions);
 
-  /* Get the bookmarks from file */
-  favs = vinagre_bookmarks_get_all ();
-  n = g_list_length (favs);
+  favs = vinagre_bookmarks_get_all (vinagre_bookmarks_get_default ());
+  mdnss = vinagre_mdns_get_all (vinagre_mdns_get_default ());
+  n = g_slist_length (favs);
+  m = g_slist_length (mdnss);
   i = 0;
 
-  id = (n > 0) ? gtk_ui_manager_new_merge_id (p->manager) : 0;
+  id = (n > 0||m > 0) ? gtk_ui_manager_new_merge_id (p->manager) : 0;
 
   while (favs)
     {
+      VinagreConnection *conn;
+      gchar             *action_name, *action_label;
+      GtkAction         *action;
+      gchar             *name, *tooltip;
+
       conn = (VinagreConnection *) favs->data;
-      name = vinagre_connection_best_name (conn);
+      g_assert (VINAGRE_IS_CONNECTION (conn));
 
-      action_name = g_strdup_printf ("Fav_%d", i);
+      name = vinagre_connection_get_best_name (conn);
+
+      action_name = g_strdup_printf ("Bookmark_%d", i);
       /* Translators: This is server:port, a statusbar tooltip when mouse is over a bookmark item on menu */
-      tooltip = g_strdup_printf (_("Open %s:%d"), conn->host, conn->port);
-      action_label = vinagre_utils_escape_underscores (
-		     name,
-		     -1);
+      tooltip = g_strdup_printf (_("Open %s:%d"),
+                                 vinagre_connection_get_host (conn),
+                                 vinagre_connection_get_port (conn));
+      action_label = vinagre_utils_escape_underscores (name, -1);
       action = gtk_action_new (action_name,
 			       action_label,
 			       tooltip,
 			       NULL);
       g_object_set (G_OBJECT (action), "icon-name", "application-x-vnc", NULL);
-      g_object_set_data_full (G_OBJECT (action),
-			      "conn",
-			      conn,
-			      (GDestroyNotify) vinagre_connection_free);
+      g_object_set_data (G_OBJECT (action), "conn", conn);
       gtk_action_group_add_action (p->bookmarks_list_action_group,
 				   GTK_ACTION (action));
-
       g_signal_connect (action,
 			"activate",
 			G_CALLBACK (vinagre_cmd_bookmarks_open),
@@ -613,7 +619,55 @@
       i++;
     }
 
-  g_list_free (favs);
+  /* avahi */
+  i = 0;
+  while (mdnss)
+    {
+      VinagreConnection *conn;
+      gchar             *action_name, *action_label;
+      GtkAction         *action;
+      gchar             *name, *tooltip;
+
+      conn = (VinagreConnection *) mdnss->data;
+      g_assert (VINAGRE_IS_CONNECTION (conn));
+
+      name = vinagre_connection_get_best_name (conn);
+
+      action_name = g_strdup_printf ("Avahi_%d", i);
+      /* Translators: This is server:port, a statusbar tooltip when mouse is over a bookmark item on menu */
+        tooltip = g_strdup_printf (_("Open %s:%d"),
+                                 vinagre_connection_get_host (conn),
+                                 vinagre_connection_get_port (conn));
+      action_label = vinagre_utils_escape_underscores (name, -1);
+      action = gtk_action_new (action_name,
+			       action_label,
+			       tooltip,
+			       NULL);
+      g_object_set (G_OBJECT (action), "icon-name", "application-x-vnc", NULL);
+      g_object_set_data (G_OBJECT (action), "conn", conn);
+      gtk_action_group_add_action (p->bookmarks_list_action_group,
+				   GTK_ACTION (action));
+      g_signal_connect (action,
+			"activate",
+			G_CALLBACK (vinagre_cmd_bookmarks_open),
+			window);
+
+      gtk_ui_manager_add_ui (p->manager,
+			     id,
+			     "/MenuBar/BookmarksMenu/AvahiList",
+			     action_name, action_name,
+			     GTK_UI_MANAGER_MENUITEM,
+			     FALSE);
+
+      g_object_unref (action);
+      g_free (action_name);
+      g_free (action_label);
+      g_free (name);
+      g_free (tooltip);
+
+      mdnss = mdnss->next;
+      i++;
+    }
 
   p->bookmarks_list_menu_ui_id = id;
 }
@@ -664,7 +718,7 @@
 
   /* fav panel visibility */
   action = gtk_action_group_get_action (window->priv->always_sensitive_action_group,
-					"ViewBookmarks");
+					"ViewSidePanel");
   visible = vinagre_prefs_manager_get_side_pane_visible ();
   if (gtk_toggle_action_get_active (GTK_TOGGLE_ACTION (action)) != visible)
     gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), visible);
@@ -758,7 +812,7 @@
       return;
     }
 
-  name = vinagre_connection_best_name (vinagre_tab_get_conn (VINAGRE_TAB (window->priv->active_tab)));
+  name = vinagre_connection_get_best_name (vinagre_tab_get_conn (VINAGRE_TAB (window->priv->active_tab)));
   title = g_strdup_printf ("%s - %s",
 			   name,
 			   g_get_application_name ());
@@ -768,6 +822,20 @@
 }
 
 static void
+update_toggle_machine_items (VinagreWindow *window) {
+  g_return_if_fail (VINAGRE_IS_WINDOW (window));
+
+  if (window->priv->active_tab == NULL)
+    {
+      gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (window->priv->scaling_action), FALSE);
+      return;
+    }
+
+  gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (window->priv->scaling_action),
+				vinagre_tab_get_scaling (VINAGRE_TAB (window->priv->active_tab)));
+}
+
+static void
 vinagre_window_page_removed (GtkNotebook   *notebook,
 			     GtkWidget     *child,
 			     guint         page_num,
@@ -781,7 +849,8 @@
     vinagre_window_toggle_fullscreen (window);
 
   vinagre_window_set_title (window);
-  _vinagre_window_del_machine_connected (window);
+  update_toggle_machine_items (window);
+  vinagre_window_update_machine_menu_sensitivity (window);
 }
 
 static void
@@ -795,6 +864,8 @@
   window->priv->active_tab = child;
 
   vinagre_window_set_title (window);
+  update_toggle_machine_items (window);
+  vinagre_window_update_machine_menu_sensitivity (window);
 }
 
 static void 
@@ -814,6 +885,8 @@
   window->priv->active_tab = tab;
 
   vinagre_window_set_title (window);
+  update_toggle_machine_items (window);
+  vinagre_window_update_machine_menu_sensitivity (window);
 }
 
 static void
@@ -883,9 +956,6 @@
   window->priv->fav_conn_selected = NULL;
   window->priv->fullscreen = FALSE;
   window->priv->signal_notebook = 0;
-  window->priv->machines_connected = 0;
-
-  vinagre_bookmarks_init ();
 
   main_box = gtk_vbox_new (FALSE, 0);
   gtk_container_add (GTK_CONTAINER (window), main_box);
@@ -916,9 +986,18 @@
   gtk_widget_grab_focus (window->priv->hpaned);
 
   init_widgets_visibility (window);
-  set_machine_menu_sensitivity (window);
+  vinagre_window_update_machine_menu_sensitivity (window);
 
   vinagre_window_update_bookmarks_list_menu (window);
+  g_signal_connect_swapped (vinagre_bookmarks_get_default (),
+                            "changed",
+                            G_CALLBACK (vinagre_window_update_bookmarks_list_menu),
+                            window);
+  g_signal_connect_swapped (vinagre_mdns_get_default (),
+                            "changed",
+                            G_CALLBACK (vinagre_window_update_bookmarks_list_menu),
+                            window);
+
   vinagre_window_init_clipboard (window);
 }
 
@@ -1049,7 +1128,7 @@
 }
 
 VinagreTab *
-vinagre_window_get_active_tab	(VinagreWindow *window)
+vinagre_window_get_active_tab (VinagreWindow *window)
 {
   g_return_val_if_fail (VINAGRE_IS_WINDOW (window), NULL);
 
@@ -1064,25 +1143,4 @@
   return window->priv->manager;
 }
 
-void
-_vinagre_window_add_machine_connected (VinagreWindow *window)
-{
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  window->priv->machines_connected++;
-  set_machine_menu_sensitivity (window);
-}
-
-void
-_vinagre_window_del_machine_connected (VinagreWindow *window)
-{
-  g_return_if_fail (VINAGRE_IS_WINDOW (window));
-
-  if (window->priv->machines_connected > 0)
-    {
-      window->priv->machines_connected--;
-      set_machine_menu_sensitivity (window);
-    }
-}
-
 /* vim: ts=8 */

Modified: trunk/src/vinagre-window.h
==============================================================================
--- trunk/src/vinagre-window.h	(original)
+++ trunk/src/vinagre-window.h	Thu Apr 10 03:35:47 2008
@@ -38,6 +38,7 @@
 typedef struct _VinagreWindowClass   VinagreWindowClass;
 
 #include "vinagre-tab.h"
+#include "vinagre-bookmarks.h"
 
 struct _VinagreWindow 
 {
@@ -88,9 +89,7 @@
 void		vinagre_window_toggle_fullscreen	(VinagreWindow *window);
 void		vinagre_window_set_title		(VinagreWindow *window);
 
-void		_vinagre_window_add_machine_connected	(VinagreWindow *window);
-void		_vinagre_window_del_machine_connected	(VinagreWindow *window);
-
+void		vinagre_window_update_machine_menu_sensitivity (VinagreWindow	*window);
 G_END_DECLS
 
 #endif  /* __VINAGRE_WINDOW_H__  */



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]