vinagre r272 - in branches/unstable: . data src



Author: jwendell
Date: Mon Mar 24 12:58:34 2008
New Revision: 272
URL: http://svn.gnome.org/viewvc/vinagre?rev=272&view=rev

Log:
2008-03-24  Jonh Wendell <jwendell gnome org>
	- Make VinagreBookmarks a GObject.
	- Modify the side panel interface.


Added:
   branches/unstable/src/gossip-cell-renderer-expander.c
   branches/unstable/src/gossip-cell-renderer-expander.h
Modified:
   branches/unstable/ChangeLog
   branches/unstable/data/vinagre-ui.xml
   branches/unstable/src/Makefile.am
   branches/unstable/src/vinagre-bookmarks.c
   branches/unstable/src/vinagre-connection.c
   branches/unstable/src/vinagre-fav.c
   branches/unstable/src/vinagre-fav.h
   branches/unstable/src/vinagre-ui.h
   branches/unstable/src/vinagre-window.c

Modified: branches/unstable/data/vinagre-ui.xml
==============================================================================
--- branches/unstable/data/vinagre-ui.xml	(original)
+++ branches/unstable/data/vinagre-ui.xml	Mon Mar 24 12:58:34 2008
@@ -38,7 +38,7 @@
     <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"/>

Modified: branches/unstable/src/Makefile.am
==============================================================================
--- branches/unstable/src/Makefile.am	(original)
+++ branches/unstable/src/Makefile.am	Mon Mar 24 12:58:34 2008
@@ -28,6 +28,7 @@
 	vinagre-window.c vinagre-window.h		\
 	vinagre-ui.h vinagre-window-private.h		\
 	vinagre-enums.h vinagre-enums.c			\
+	gossip-cell-renderer-expander.c gossip-cell-renderer-expander.h \
 	$(NULL)
 
 vinagre_LDADD = \

Added: branches/unstable/src/gossip-cell-renderer-expander.c
==============================================================================
--- (empty file)
+++ branches/unstable/src/gossip-cell-renderer-expander.c	Mon Mar 24 12:58:34 2008
@@ -0,0 +1,513 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006  Kristian Rietveld <kris babi-pangang org>
+ *
+ * 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 the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* To do:
+ *  - should probably cancel animation if model changes
+ *  - need to handle case where node-in-animation is removed
+ *  - it only handles a single animation at a time; but I guess users
+ *    aren't fast enough to trigger two or more animations at once anyway :P
+ *    (could guard for this by just cancelling the "old" animation, and
+ *     start the new one).
+ */
+
+#include "config.h"
+
+#include <gtk/gtktreeview.h>
+
+#include "gossip-cell-renderer-expander.h"
+
+#define GET_PRIV(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpanderPriv))
+
+static void     gossip_cell_renderer_expander_init         (GossipCellRendererExpander      *expander);
+static void     gossip_cell_renderer_expander_class_init   (GossipCellRendererExpanderClass *klass);
+static void     gossip_cell_renderer_expander_get_property (GObject                         *object,
+							    guint                            param_id,
+							    GValue                          *value,
+							    GParamSpec                      *pspec);
+static void     gossip_cell_renderer_expander_set_property (GObject                         *object,
+							    guint                            param_id,
+							    const GValue                    *value,
+							    GParamSpec                      *pspec);
+static void     gossip_cell_renderer_expander_finalize     (GObject                         *object);
+static void     gossip_cell_renderer_expander_get_size     (GtkCellRenderer                 *cell,
+							    GtkWidget                       *widget,
+							    GdkRectangle                    *cell_area,
+							    gint                            *x_offset,
+							    gint                            *y_offset,
+							    gint                            *width,
+							    gint                            *height);
+static void     gossip_cell_renderer_expander_render       (GtkCellRenderer                 *cell,
+							    GdkWindow                       *window,
+							    GtkWidget                       *widget,
+							    GdkRectangle                    *background_area,
+							    GdkRectangle                    *cell_area,
+							    GdkRectangle                    *expose_area,
+							    GtkCellRendererState             flags);
+static gboolean gossip_cell_renderer_expander_activate     (GtkCellRenderer                 *cell,
+							    GdkEvent                        *event,
+							    GtkWidget                       *widget,
+							    const gchar                     *path,
+							    GdkRectangle                    *background_area,
+							    GdkRectangle                    *cell_area,
+							    GtkCellRendererState             flags);
+
+/* Properties */
+enum {
+	PROP_0,
+	PROP_EXPANDER_STYLE,
+	PROP_EXPANDER_SIZE,
+	PROP_ACTIVATABLE
+};
+
+typedef struct _GossipCellRendererExpanderPriv GossipCellRendererExpanderPriv;
+
+struct _GossipCellRendererExpanderPriv {
+	GtkExpanderStyle     expander_style;
+	gint                 expander_size;
+
+	GtkTreeView         *animation_view;
+	GtkTreeRowReference *animation_node;
+	GtkExpanderStyle     animation_style;
+	guint                animation_timeout;
+	GdkRectangle         animation_area;
+
+	guint                activatable : 1;
+	guint                animation_expanding : 1;
+};
+
+G_DEFINE_TYPE (GossipCellRendererExpander, gossip_cell_renderer_expander, GTK_TYPE_CELL_RENDERER)
+
+static void
+gossip_cell_renderer_expander_init (GossipCellRendererExpander *expander)
+{
+	GossipCellRendererExpanderPriv *priv;
+
+	priv = GET_PRIV (expander);
+
+	priv->expander_style = GTK_EXPANDER_COLLAPSED;
+	priv->expander_size = 12;
+	priv->activatable = TRUE;
+	priv->animation_node = NULL;
+
+	GTK_CELL_RENDERER (expander)->xpad = 2;
+	GTK_CELL_RENDERER (expander)->ypad = 2;
+	GTK_CELL_RENDERER (expander)->mode = GTK_CELL_RENDERER_MODE_ACTIVATABLE;
+}
+
+static void
+gossip_cell_renderer_expander_class_init (GossipCellRendererExpanderClass *klass)
+{
+	GObjectClass         *object_class;
+	GtkCellRendererClass *cell_class;
+
+	object_class  = G_OBJECT_CLASS (klass);
+	cell_class = GTK_CELL_RENDERER_CLASS (klass);
+
+	object_class->finalize = gossip_cell_renderer_expander_finalize;
+
+	object_class->get_property = gossip_cell_renderer_expander_get_property;
+	object_class->set_property = gossip_cell_renderer_expander_set_property;
+
+	cell_class->get_size = gossip_cell_renderer_expander_get_size;
+	cell_class->render = gossip_cell_renderer_expander_render;
+	cell_class->activate = gossip_cell_renderer_expander_activate;
+
+	g_object_class_install_property (object_class,
+					 PROP_EXPANDER_STYLE,
+					 g_param_spec_enum ("expander-style",
+							    "Expander Style",
+							    "Style to use when painting the expander",
+							    GTK_TYPE_EXPANDER_STYLE,
+							    GTK_EXPANDER_COLLAPSED,
+							    G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_EXPANDER_SIZE,
+					 g_param_spec_int ("expander-size",
+							   "Expander Size",
+							   "The size of the expander",
+							   0,
+							   G_MAXINT,
+							   12,
+							   G_PARAM_READWRITE));
+
+	g_object_class_install_property (object_class,
+					 PROP_ACTIVATABLE,
+					 g_param_spec_boolean ("activatable",
+							       "Activatable",
+							       "The expander can be activated",
+							       TRUE,
+							       G_PARAM_READWRITE));
+
+	g_type_class_add_private (object_class, sizeof (GossipCellRendererExpanderPriv));
+}
+
+static void
+gossip_cell_renderer_expander_get_property (GObject    *object,
+					    guint       param_id,
+					    GValue     *value,
+					    GParamSpec *pspec)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+
+	expander = GOSSIP_CELL_RENDERER_EXPANDER (object);
+	priv = GET_PRIV (expander);
+
+	switch (param_id) {
+	case PROP_EXPANDER_STYLE:
+		g_value_set_enum (value, priv->expander_style);
+		break;
+
+	case PROP_EXPANDER_SIZE:
+		g_value_set_int (value, priv->expander_size);
+		break;
+
+	case PROP_ACTIVATABLE:
+		g_value_set_boolean (value, priv->activatable);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gossip_cell_renderer_expander_set_property (GObject      *object,
+					    guint         param_id,
+					    const GValue *value,
+					    GParamSpec   *pspec)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+
+	expander = GOSSIP_CELL_RENDERER_EXPANDER (object);
+	priv = GET_PRIV (expander);
+
+	switch (param_id) {
+	case PROP_EXPANDER_STYLE:
+		priv->expander_style = g_value_get_enum (value);
+		break;
+
+	case PROP_EXPANDER_SIZE:
+		priv->expander_size = g_value_get_int (value);
+		break;
+
+	case PROP_ACTIVATABLE:
+		priv->activatable = g_value_get_boolean (value);
+		break;
+
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
+		break;
+	}
+}
+
+static void
+gossip_cell_renderer_expander_finalize (GObject *object)
+{
+	GossipCellRendererExpanderPriv *priv;
+
+	priv = GET_PRIV (object);
+
+	if (priv->animation_timeout) {
+		g_source_remove (priv->animation_timeout);
+		priv->animation_timeout = 0;
+	}
+
+	if (priv->animation_node) {
+		gtk_tree_row_reference_free (priv->animation_node);
+	}
+
+	(* G_OBJECT_CLASS (gossip_cell_renderer_expander_parent_class)->finalize) (object);
+}
+
+GtkCellRenderer *
+gossip_cell_renderer_expander_new (void)
+{
+	return g_object_new (GOSSIP_TYPE_CELL_RENDERER_EXPANDER, NULL);
+}
+
+static void
+gossip_cell_renderer_expander_get_size (GtkCellRenderer *cell,
+					GtkWidget       *widget,
+					GdkRectangle    *cell_area,
+					gint            *x_offset,
+					gint            *y_offset,
+					gint            *width,
+					gint            *height)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+
+	expander = (GossipCellRendererExpander*) cell;
+	priv = GET_PRIV (expander);
+
+	if (cell_area) {
+		if (x_offset) {
+			*x_offset = cell->xalign * (cell_area->width - (priv->expander_size + (2 * cell->xpad)));
+			*x_offset = MAX (*x_offset, 0);
+		}
+
+		if (y_offset) {
+			*y_offset = cell->yalign * (cell_area->height - (priv->expander_size + (2 * cell->ypad)));
+			*y_offset = MAX (*y_offset, 0);
+		}
+	} else {
+		if (x_offset)
+			*x_offset = 0;
+
+		if (y_offset)
+			*y_offset = 0;
+	}
+
+	if (width)
+		*width = cell->xpad * 2 + priv->expander_size;
+
+	if (height)
+		*height = cell->ypad * 2 + priv->expander_size;
+}
+
+static void
+gossip_cell_renderer_expander_render (GtkCellRenderer      *cell,
+				      GdkWindow            *window,
+				      GtkWidget            *widget,
+				      GdkRectangle         *background_area,
+				      GdkRectangle         *cell_area,
+				      GdkRectangle         *expose_area,
+				      GtkCellRendererState  flags)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+	GtkExpanderStyle                expander_style;
+	gint                            x_offset, y_offset;
+
+	expander = (GossipCellRendererExpander*) cell;
+	priv = GET_PRIV (expander);
+
+	if (priv->animation_node) {
+		GtkTreePath *path;
+		GdkRectangle rect;
+
+		/* Not sure if I like this ... */
+		path = gtk_tree_row_reference_get_path (priv->animation_node);
+		gtk_tree_view_get_background_area (priv->animation_view, path,
+						   NULL, &rect);
+		gtk_tree_path_free (path);
+
+		if (background_area->y == rect.y)
+			expander_style = priv->animation_style;
+		else
+			expander_style = priv->expander_style;
+	} else
+		expander_style = priv->expander_style;
+
+	gossip_cell_renderer_expander_get_size (cell, widget, cell_area,
+						&x_offset, &y_offset,
+						NULL, NULL);
+
+	gtk_paint_expander (widget->style,
+			    window,
+			    GTK_STATE_NORMAL,
+			    expose_area,
+			    widget,
+			    "treeview",
+			    cell_area->x + x_offset + cell->xpad + priv->expander_size / 2,
+			    cell_area->y + y_offset + cell->ypad + priv->expander_size / 2,
+			    expander_style);
+}
+
+static void
+invalidate_node (GtkTreeView *tree_view,
+		 GtkTreePath *path)
+{
+       GdkWindow    *bin_window;
+       GdkRectangle  rect;
+
+       bin_window = gtk_tree_view_get_bin_window (tree_view);
+
+       gtk_tree_view_get_background_area (tree_view, path, NULL, &rect);
+
+       rect.x = 0;
+       rect.width = GTK_WIDGET (tree_view)->allocation.width;
+
+       gdk_window_invalidate_rect (bin_window, &rect, TRUE);
+}
+
+static gboolean
+do_animation (GossipCellRendererExpander *expander)
+{
+	GossipCellRendererExpanderPriv *priv;
+	GtkTreePath                    *path;
+	gboolean                        done = FALSE;
+
+	priv = GET_PRIV (expander);
+
+	if (priv->animation_expanding) {
+		if (priv->animation_style == GTK_EXPANDER_SEMI_COLLAPSED)
+			priv->animation_style = GTK_EXPANDER_SEMI_EXPANDED;
+		else if (priv->animation_style == GTK_EXPANDER_SEMI_EXPANDED) {
+			priv->animation_style = GTK_EXPANDER_EXPANDED;
+			done = TRUE;
+		}
+	} else {
+		if (priv->animation_style == GTK_EXPANDER_SEMI_EXPANDED)
+			priv->animation_style = GTK_EXPANDER_SEMI_COLLAPSED;
+		else if (priv->animation_style == GTK_EXPANDER_SEMI_COLLAPSED) {
+			priv->animation_style = GTK_EXPANDER_COLLAPSED;
+			done = TRUE;
+		}
+	}
+
+	path = gtk_tree_row_reference_get_path (priv->animation_node);
+	invalidate_node (priv->animation_view, path);
+	gtk_tree_path_free (path);
+
+	if (done) {
+		gtk_tree_row_reference_free (priv->animation_node);
+		priv->animation_node = NULL;
+		priv->animation_timeout = 0;
+	}
+
+	return !done;
+}
+
+static gboolean
+animation_timeout (gpointer data)
+{
+	gboolean retval;
+
+	GDK_THREADS_ENTER ();
+
+	retval = do_animation (data);
+
+	GDK_THREADS_LEAVE ();
+
+	return retval;
+}
+
+static void
+gossip_cell_renderer_expander_start_animation (GossipCellRendererExpander *expander,
+					       GtkTreeView                *tree_view,
+					       GtkTreePath                *path,
+					       gboolean                    expanding,
+					       GdkRectangle               *background_area)
+{
+	GossipCellRendererExpanderPriv *priv;
+
+	priv = GET_PRIV (expander);
+
+	if (expanding) {
+		priv->animation_style = GTK_EXPANDER_SEMI_COLLAPSED;
+	} else {
+		priv->animation_style = GTK_EXPANDER_SEMI_EXPANDED;
+	}
+
+	invalidate_node (tree_view, path);
+
+	priv->animation_expanding = expanding;
+	priv->animation_view = tree_view;
+	priv->animation_node = gtk_tree_row_reference_new (gtk_tree_view_get_model (tree_view), path);
+	priv->animation_timeout = g_timeout_add (50, animation_timeout, expander);
+}
+
+static gboolean
+gossip_cell_renderer_expander_activate (GtkCellRenderer      *cell,
+					GdkEvent             *event,
+					GtkWidget            *widget,
+					const gchar          *path_string,
+					GdkRectangle         *background_area,
+					GdkRectangle         *cell_area,
+					GtkCellRendererState  flags)
+{
+	GossipCellRendererExpander     *expander;
+	GossipCellRendererExpanderPriv *priv;
+	GtkTreePath                    *path;
+	GtkSettings                    *settings;
+	gboolean                        animate;
+	gboolean                        expanding;
+	gboolean                        in_cell;
+	int                             mouse_x;
+	int                             mouse_y;
+
+	expander = GOSSIP_CELL_RENDERER_EXPANDER (cell);
+	priv = GET_PRIV (cell);
+
+	if (!GTK_IS_TREE_VIEW (widget) || !priv->activatable)
+		return FALSE;
+
+	path = gtk_tree_path_new_from_string (path_string);
+
+	gtk_widget_get_pointer (widget, &mouse_x, &mouse_y);
+	gtk_tree_view_widget_to_tree_coords (GTK_TREE_VIEW (widget),
+					     mouse_x,
+					     mouse_y,
+					     &mouse_x,
+					     &mouse_y);
+
+	/* check if click is within the cell */
+	if (mouse_x - cell_area->x >= 0
+	    && mouse_x - cell_area->x <= cell_area->width) {
+		in_cell = TRUE;
+	} else {
+		in_cell = FALSE;
+	}
+
+	if (! in_cell) {
+		return FALSE;
+	}
+
+#if 0
+	if (gtk_tree_path_get_depth (path) > 1) {
+		gtk_tree_path_free (path);
+		return TRUE;
+	}
+#endif
+
+	settings = gtk_widget_get_settings (GTK_WIDGET (widget));
+	if (g_object_class_find_property (G_OBJECT_GET_CLASS (settings), "gtk-enable-animations")) {
+		g_object_get (settings,
+			      "gtk-enable-animations", &animate,
+			      NULL);
+	} else {
+		animate = FALSE;
+	}
+
+	if (gtk_tree_view_row_expanded (GTK_TREE_VIEW (widget), path)) {
+		gtk_tree_view_collapse_row (GTK_TREE_VIEW (widget), path);
+		expanding = FALSE;
+	} else {
+		gtk_tree_view_expand_row (GTK_TREE_VIEW (widget), path, FALSE);
+		expanding = TRUE;
+	}
+
+	if (animate) {
+		gossip_cell_renderer_expander_start_animation (expander,
+							       GTK_TREE_VIEW (widget),
+							       path,
+							       expanding,
+							       background_area);
+	}
+
+	gtk_tree_path_free (path);
+
+	return TRUE;
+}

Added: branches/unstable/src/gossip-cell-renderer-expander.h
==============================================================================
--- (empty file)
+++ branches/unstable/src/gossip-cell-renderer-expander.h	Mon Mar 24 12:58:34 2008
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2006  Kristian Rietveld <kris babi-pangang org>
+ *
+ * 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 the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GOSSIP_CELL_RENDERER_EXPANDER_H__
+#define __GOSSIP_CELL_RENDERER_EXPANDER_H__
+
+#include <gtk/gtkcellrenderer.h>
+
+G_BEGIN_DECLS
+
+#define GOSSIP_TYPE_CELL_RENDERER_EXPANDER		(gossip_cell_renderer_expander_get_type ())
+#define GOSSIP_CELL_RENDERER_EXPANDER(obj)		(G_TYPE_CHECK_INSTANCE_CAST ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpander))
+#define GOSSIP_CELL_RENDERER_EXPANDER_CLASS(klass)	(G_TYPE_CHECK_CLASS_CAST ((klass), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpanderClass))
+#define GOSSIP_IS_CELL_RENDERER_EXPANDER(obj)		(G_TYPE_CHECK_INSTANCE_TYPE ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER))
+#define GOSSIP_IS_CELL_RENDERER_EXPANDER_CLASS(klass)	(G_TYPE_CHECK_CLASS_TYPE ((klass), GOSSIP_TYPE_CELL_RENDERER_EXPANDER))
+#define GOSSIP_CELL_RENDERER_EXPANDER_GET_CLASS(obj)	(G_TYPE_INSTANCE_GET_CLASS ((obj), GOSSIP_TYPE_CELL_RENDERER_EXPANDER, GossipCellRendererExpanderClass))
+
+typedef struct _GossipCellRendererExpander GossipCellRendererExpander;
+typedef struct _GossipCellRendererExpanderClass GossipCellRendererExpanderClass;
+
+struct _GossipCellRendererExpander {
+  GtkCellRenderer parent;
+};
+
+struct _GossipCellRendererExpanderClass {
+  GtkCellRendererClass parent_class;
+
+  /* Padding for future expansion */
+  void (*_gtk_reserved1) (void);
+  void (*_gtk_reserved2) (void);
+  void (*_gtk_reserved3) (void);
+  void (*_gtk_reserved4) (void);
+};
+
+GType            gossip_cell_renderer_expander_get_type (void) G_GNUC_CONST;
+GtkCellRenderer *gossip_cell_renderer_expander_new      (void);
+
+G_END_DECLS
+
+#endif /* __GOSSIP_CELL_RENDERER_EXPANDER_H__ */

Modified: branches/unstable/src/vinagre-bookmarks.c
==============================================================================
--- branches/unstable/src/vinagre-bookmarks.c	(original)
+++ branches/unstable/src/vinagre-bookmarks.c	Mon Mar 24 12:58:34 2008
@@ -23,13 +23,16 @@
 
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
+#include <gio/gio.h>
 #include <glade/glade.h>
 #include <string.h>
 
 struct _VinagreBookmarksPrivate
 {
-  GKeyFile *file;
-  GSList *conns;
+  GKeyFile     *file;
+  gchar        *filename;
+  GSList       *conns;
+  GFileMonitor *monitor;
 };
 
 enum
@@ -46,21 +49,43 @@
 static guint signals[LAST_SIGNAL] = { 0 };
 
 /* Prototypes */
-static void vinagre_bookmarks_init_file    (VinagreBookmarks *book);
+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_init (VinagreBookmarks *book)
 {
+  GFile *gfile;
+
   book->priv = G_TYPE_INSTANCE_GET_PRIVATE (book, VINAGRE_TYPE_BOOKMARKS, VinagreBookmarksPrivate);
 
   book->priv->conns = NULL;
-
-  vinagre_bookmarks_init_file (book);
+  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
@@ -72,6 +97,12 @@
   book->priv->file = NULL;
   vinagre_bookmarks_clear_conns (book);
 
+  g_free (book->priv->filename);
+  book->priv->filename = NULL;
+
+  g_file_monitor_cancel (book->priv->monitor);
+  g_object_unref (book->priv->monitor);
+
   G_OBJECT_CLASS (vinagre_bookmarks_parent_class)->finalize (object);
 }
 
@@ -370,33 +401,21 @@
   return book->priv->conns;
 }
 
-static gchar *
-filename (void)
-{
-  return g_build_filename (g_get_home_dir (),
-			   ".gnome2",
-			   VINAGRE_BOOKMARKS_FILE,
-			   NULL);
-}
-
 static void
-vinagre_bookmarks_init_file (VinagreBookmarks *book)
+vinagre_bookmarks_update_file (VinagreBookmarks *book)
 {
-  gchar    *file;
   gboolean loaded = TRUE;
   GError   *error = NULL;
 
+  if (book->priv->file)
+    g_key_file_free (book->priv->file);
   book->priv->file = g_key_file_new ();
 
-  file = filename ();
-
-  if (g_file_test (file, G_FILE_TEST_EXISTS))
+  if (g_file_test (book->priv->filename, G_FILE_TEST_EXISTS))
     loaded = g_key_file_load_from_file (book->priv->file,
-					file,
+					book->priv->filename,
 					G_KEY_FILE_NONE,
 					&error);
-  g_free (file);
-
   if (!loaded)
     {
       if (error)
@@ -410,7 +429,6 @@
 static void
 vinagre_bookmarks_save_file (VinagreBookmarks *book)
 {
-  gchar    *file;
   gchar    *data;
   gsize    length;
   GError   *error;
@@ -431,10 +449,9 @@
 
     }
 
-  file  = filename ();
   error = NULL;
 
-  if (!g_file_set_contents (file,
+  if (!g_file_set_contents (book->priv->filename,
 			    data,
 			    length,
 			    &error))
@@ -443,16 +460,12 @@
 	{
 	  g_warning (_("Error while saving bookmarks: %s"), error->message);
 	  g_error_free (error);
-          g_free (file);
           g_free (data);
           return;
 	}
     }
 
-  g_free (file);
   g_free (data);
-
-  g_signal_emit (book, signals[BOOKMARK_CHANGED], 0);
 }
 
 static void
@@ -494,4 +507,23 @@
 
   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;
+
+  vinagre_bookmarks_update_file (book);
+  vinagre_bookmarks_update_conns (book);
+
+  g_signal_emit (book, signals[BOOKMARK_CHANGED], 0);
+}
+
 /* vim: ts=8 */

Modified: branches/unstable/src/vinagre-connection.c
==============================================================================
--- branches/unstable/src/vinagre-connection.c	(original)
+++ branches/unstable/src/vinagre-connection.c	Mon Mar 24 12:58:34 2008
@@ -53,8 +53,6 @@
 #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 VinagreBookmarks *main_bookmark = NULL;
-
 static void
 vinagre_connection_init (VinagreConnection *conn)
 {
@@ -66,8 +64,6 @@
   conn->priv->password = NULL;
   conn->priv->name = NULL;
   conn->priv->desktop_name = NULL;
-
-  //main_bookmark = vinagre_bookmarks_get_default ();
 }
 
 static void
@@ -469,7 +465,9 @@
   host = server[0];
   port = server[1] ? atoi (server[1]) : 5900;
 
-  conn = vinagre_bookmarks_exists (main_bookmark, host, port);
+  conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (),
+                                   host,
+                                   port);
   if (!conn)
     {
       conn = vinagre_connection_new ();
@@ -532,7 +530,9 @@
       port = g_key_file_get_integer (file, "connection", "port", NULL);
       if (host)
 	{
-	  conn = vinagre_bookmarks_exists (main_bookmark, host, port);
+	  conn = vinagre_bookmarks_exists (vinagre_bookmarks_get_default (),
+                                           host,
+                                           port);
 	  if (!conn)
 	    {
 	      conn = vinagre_connection_new ();

Modified: branches/unstable/src/vinagre-fav.c
==============================================================================
--- branches/unstable/src/vinagre-fav.c	(original)
+++ branches/unstable/src/vinagre-fav.c	Mon Mar 24 12:58:34 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
@@ -27,7 +27,8 @@
 #include "vinagre-utils.h"
 #include "vinagre-bookmarks.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,7 +36,7 @@
   VinagreWindow *window;
   GtkWidget     *tree;
   GtkTreeModel  *model;
-  VinagreConnection *conn_selected;
+  GtkTreeViewColumn *main_column;
 };
 
 G_DEFINE_TYPE(VinagreFav, vinagre_fav, GTK_TYPE_VBOX)
@@ -53,6 +54,8 @@
   IMAGE_COL = 0,
   NAME_COL,
   CONN_COL,
+  IS_FOLDER_COL,
+  IS_GROUP_COL,
   NUM_COLS
 };
 
@@ -163,13 +166,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],
@@ -192,8 +207,6 @@
 			  -1);
     }
 
-  fav->priv->conn_selected = conn;
-
   /* Emits the signal saying that user has selected a bookmark */
   g_signal_emit (G_OBJECT (fav), 
 		 signals[FAV_SELECTED],
@@ -302,36 +315,46 @@
 			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;
+
+  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,
+		            -1);
+        if (folder || group)
+          {
+            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;
 }
 
 
@@ -353,18 +376,210 @@
                      VinagreFav *fav)
 {
   gchar *tip;
+  GtkTreePath *path = NULL;
+  gint bx, by;
+  GtkTreeIter iter;
+  gboolean folder, group;
+  VinagreConnection *conn = NULL;
 
-  if (!VINAGRE_IS_CONNECTION (fav->priv->conn_selected))
+  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;
 
-  tip = g_markup_printf_escaped (
-				  "<b>%s</b> %s\n"
-				  "<b>%s</b> %d",
-				  _("Host:"), vinagre_connection_get_host (fav->priv->conn_selected),
-				  _("Port:"), vinagre_connection_get_port (fav->priv->conn_selected));
+  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;
+
+  tip = g_markup_printf_escaped ("<b>%s</b> %s\n"
+				 "<b>%s</b> %d",
+				 _("Host:"), vinagre_connection_get_host (conn),
+				 _("Port:"), vinagre_connection_get_port (conn));
 
   gtk_tooltip_set_markup (tooltip, tip);
   g_free (tip);
+
+  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
@@ -386,31 +601,72 @@
   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,
-							 VINAGRE_TYPE_CONNECTION));
+							 VINAGRE_TYPE_CONNECTION,
+                                                         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",
@@ -441,41 +697,12 @@
   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)
 {
   GtkWidget *label_box, *label, *close_button;
 
   fav->priv = VINAGRE_FAV_GET_PRIVATE (fav);
-  fav->priv->conn_selected = NULL;
-
-  /* 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);
@@ -499,18 +726,26 @@
 gboolean
 vinagre_fav_update_list (VinagreFav *fav)
 {
-  GtkTreeIter        iter;
-  GtkListStore      *store;
+  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_LIST_STORE (fav->priv->model);
-  gtk_list_store_clear (store);
+  store = GTK_TREE_STORE (fav->priv->model);
+  gtk_tree_store_clear (store);
 
   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,
+                      -1);
+
   for (l = list; l; l = next)
     {
       gchar *name = NULL;
@@ -524,11 +759,13 @@
       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,
                           -1);
       if (name)
         g_free (name);
@@ -536,6 +773,10 @@
 	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);
+
   return FALSE;
 }
 /* vim: ts=8 */

Modified: branches/unstable/src/vinagre-fav.h
==============================================================================
--- branches/unstable/src/vinagre-fav.h	(original)
+++ branches/unstable/src/vinagre-fav.h	Mon Mar 24 12:58:34 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);
 
-gboolean	vinagre_fav_update_list		(VinagreFav *fav);
+gboolean    vinagre_fav_update_list (VinagreFav *fav);
 
 G_END_DECLS
 

Modified: branches/unstable/src/vinagre-ui.h
==============================================================================
--- branches/unstable/src/vinagre-ui.h	(original)
+++ branches/unstable/src/vinagre-ui.h	Mon Mar 24 12:58:34 2008
@@ -101,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: branches/unstable/src/vinagre-window.c
==============================================================================
--- branches/unstable/src/vinagre-window.c	(original)
+++ branches/unstable/src/vinagre-window.c	Mon Mar 24 12:58:34 2008
@@ -664,7 +664,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);



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