diff --git a/gladeui/Makefile.am b/gladeui/Makefile.am
index 5220078..b60d616 100644
--- a/gladeui/Makefile.am
+++ b/gladeui/Makefile.am
@@ -94,7 +94,8 @@ libgladeui_1_la_SOURCES = \
 	glade-displayable-values.c \
 	glade-editable.c \
 	glade-editor-table.c \
-	glade-cell-renderer-icon.c
+	glade-cell-renderer-icon.c \
+	glade-preview.c
 
 libgladeui_1_la_CPPFLAGS =  \
 	$(common_defines)   \
diff --git a/gladeui/glade-preview.c b/gladeui/glade-preview.c
new file mode 100644
index 0000000..eed4370
--- /dev/null
+++ b/gladeui/glade-preview.c
@@ -0,0 +1,261 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2010 Marco Diego Aurélio Mesquita
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
+ */
+
+#include <config.h>
+
+/**
+ * SECTION:glade-preview
+ * @Short_Description: The glade preview launch/kill interface.
+ *
+ * This object owns all data that is needed to keep a preview. It stores
+ * the GIOChannel used for comunnication between glade and glade-previewer,
+ * the event source id for a watch  (in the case a watch is used to monitor
+ * the communication channel), the previewed widget and the pid of the
+ * corresponding glade-previewer.
+ * 
+ */
+
+
+#include <string.h>
+#include <stdlib.h>
+#include <glib.h>
+#include <glib/gi18n-lib.h>
+#include <glib/gstdio.h>
+
+#include "glade.h"
+#include "glade-preview.h"
+#include "glade-app.h"
+
+
+/* Private data for glade-preview */
+struct _GladePreviewPrivate
+{
+	GIOChannel *channel; /* Channel user for communication between glade and glade-previewer */
+	guint watch; /* Event source id used to monitor the channel */
+	GtkWidget *previewed_widget; /* The widget that is been previewed */
+	GPid pid; /* Pid of the corresponding glade-previewer process */
+};
+
+G_DEFINE_TYPE (GladePreview, glade_preview, G_TYPE_OBJECT);
+ 
+#define GLADE_PREVIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GLADE_TYPE_PREVIEW, GladePreviewPrivate))
+ 
+static void
+glade_preview_dispose (GObject *gobject)
+{
+	GladePreview *self = GLADE_PREVIEW (gobject);
+
+	if (self->priv->channel) {
+		g_io_channel_unref (self->priv->channel);
+		self->priv->channel = NULL;
+	}
+
+	G_OBJECT_CLASS (glade_preview_parent_class)->dispose (gobject);
+}
+
+static void
+glade_preview_class_init (GladePreviewClass *klass)
+{
+	GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+	gobject_class->dispose = glade_preview_dispose;
+
+	g_type_class_add_private (klass, sizeof (GladePreviewPrivate));
+}
+
+static void
+glade_preview_init (GladePreview *self)
+{
+	GladePreviewPrivate *priv;
+
+	self->priv = priv = GLADE_PREVIEW_GET_PRIVATE (self);
+	priv->channel = NULL;
+}
+
+/**
+ * glade_preview_kill_preview:
+ * @preview: a #GladePreview that will be killed.
+ *
+ * Uses the communication channel and protocol to send the "<quit>" token to the
+ * glade-previewer telling it to commit suicide.
+ *
+ */
+void
+glade_preview_kill_preview (GladePreview *preview)
+{
+	const gchar *quit = "<quit>";
+	GIOChannel *channel;
+	GError *error = NULL;
+	gsize size;
+
+	channel = preview->priv->channel;
+	g_io_channel_write_chars (channel, quit, strlen (quit), &size, &error);
+
+	if (size != strlen (quit) && error != NULL)
+	{
+		g_printerr ("Error passing quit signal trough pipe: %s", error->message);
+		g_error_free (error);
+	}
+
+	g_io_channel_flush (channel, &error);
+	if (error != NULL)
+	{
+		g_printerr ("Error flushing channel: %s", error->message);
+		g_error_free (error);
+	}
+
+	g_io_channel_shutdown (channel, TRUE, &error);
+	if (error != NULL)
+	{
+		g_printerr ("Error shutting down channel: %s", error->message);
+		g_error_free (error);
+	}
+
+	g_io_channel_unref (channel);
+	preview->priv->channel = NULL;
+}
+
+/**
+ * glade_preview_remove_watch:
+ * @preview: a #GladePreview that will have a watch removed from its communication channel.
+ *
+ * Removes the watch monitoring the communication channel between glade and corresponding
+ * glade-previwer process.
+ *
+ */
+void glade_preview_remove_watch (GladePreview *preview)
+{
+	g_source_remove (preview->priv->watch);
+}
+
+/**
+ * glade_preview_launch_preview:
+ * @buffer: Contents of an xml definition of the interface which will be previewed
+ * @widget: Pointer to a local instance of the widget that will be previewed.
+ *
+ * Creates a new #GladePreview and launches glade-previewer to preview it.
+ *
+ * Returns: a new #GladePreview or NULL if launch fails.
+ * 
+ */
+GladePreview*
+glade_preview_launch_preview (gchar *buffer, GtkWidget *widget)
+{
+	GPid pid;
+	GError *error = NULL;
+	gchar *argv[4];
+	gint child_stdin;
+	GIOChannel *output;
+	GladePreview *preview = NULL;
+	GladeWidget *glade_widget;
+
+	#ifdef WINDOWS
+	argv[0] = g_build_filename (glade_app_get_bin_dir(), "glade-previewer.exe", NULL);
+	#else
+	argv[0] = g_build_filename (glade_app_get_bin_dir(), "glade-previewer", NULL);
+	#endif
+
+	argv[1] = "--listen";
+
+	if (widget != NULL)
+	{
+		glade_widget = glade_widget_get_from_gobject (G_OBJECT (widget));
+		argv[2] = g_strdup_printf ("--toplevel=%s", glade_widget->name);
+		argv[3] = NULL;
+	}
+
+	if (g_spawn_async_with_pipes (NULL,
+				      argv,
+				      NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
+				      &pid, &child_stdin, NULL, NULL, &error) == FALSE)
+	{
+		g_printerr (_("Error launching previewer: %s\n"), error->message);
+		glade_util_ui_message (glade_app_get_window(),
+				       GLADE_UI_ERROR, NULL,
+				       _("Failed to launch preview: %s.\n"),
+				       error->message);
+		g_error_free (error);
+		goto end;
+	}
+
+	#ifdef WINDOWS
+	output = g_io_channel_win32_new_fd (child_stdin);
+	#else
+	output = g_io_channel_unix_new (child_stdin);
+	#endif
+
+	gsize bytes_written;
+	g_io_channel_write_chars (output, buffer, strlen (buffer), &bytes_written, &error);
+
+	if (bytes_written != strlen (buffer) && error != NULL)
+	{
+		g_printerr ("Error passing UI trough pipe: %s", error->message);
+		g_error_free (error);
+	}
+
+	g_io_channel_flush (output, &error);
+	if (error != NULL)
+	{
+		g_printerr ("Error flushing UI trough pipe: %s", error->message);
+		g_error_free (error);
+	}
+
+	if (widget != NULL) g_free (argv[2]);
+
+	/* Setting up preview data */
+	preview = g_object_new (GLADE_TYPE_PREVIEW, NULL);
+	preview->priv->channel = output;
+	preview->priv->previewed_widget = widget;
+	preview->priv->pid = pid;
+
+	end:
+	g_free (argv[0]);
+	return preview;
+}
+
+/**
+ * glade_preview_add_watch:
+ * @preview: a #GladePreview that will have a watch added to its communication channel
+ * @function: callback function that will be used to monitor the communicatin channel
+ * @data: data that is sent to the callback function.
+ *
+ * Add a watch to monitor the communication channel between glade and corresponding
+ * glade-previwer process.
+ *
+ */
+void
+glade_preview_add_watch (GladePreview *preview, 
+			 GChildWatchFunc function, 
+			 gpointer data)
+{
+	preview->priv->watch = g_child_watch_add (preview->priv->pid, function, data);
+}
+
+GtkWidget* glade_preview_get_widget (GladePreview *preview)
+{
+	return preview->priv->previewed_widget;
+}
+
+GPid glade_preview_get_pid (GladePreview *preview)
+{
+	return preview->priv->pid;
+}
+
diff --git a/gladeui/glade-preview.h b/gladeui/glade-preview.h
new file mode 100644
index 0000000..b40cf2b
--- /dev/null
+++ b/gladeui/glade-preview.h
@@ -0,0 +1,75 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2010 Marco Diego Aurélio Mesquita
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Authors:
+ *   Marco Diego Aurélio Mesquita <marcodiegomesquita@gmail.com>
+ */
+
+#ifndef _GLADE_PREVIEW_H_
+#define _GLADE_PREVIEW_H_
+
+#include <glib-object.h>
+#include <glib.h>
+#include <glib/gstdio.h>
+
+G_BEGIN_DECLS
+
+#define GLADE_TYPE_PREVIEW             (glade_preview_get_type ())
+#define GLADE_PREVIEW(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GLADE_TYPE_PREVIEW, GladePreview))
+#define GLADE_PREVIEW_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GLADE_TYPE_PREVIEW, GladePreviewClass))
+#define GLADE_IS_PREVIEW(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GLADE_TYPE_PREVIEW))
+#define GLADE_IS_PREVIEW_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GLADE_TYPE_PREVIEW))
+#define GLADE_PREVIEW_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GLADE_TYPE_PREVIEW, GladePreviewClass))
+
+
+typedef struct _GladePreviewClass GladePreviewClass;
+typedef struct _GladePreview      GladePreview;
+
+struct _GladePreviewClass
+{
+	GObjectClass parent_class;
+};
+
+typedef struct _GladePreviewPrivate  GladePreviewPrivate;
+
+struct _GladePreview
+{
+	GObject parent_instance;
+
+	GladePreviewPrivate *priv;
+};
+
+GType		glade_preview_get_type		(void) G_GNUC_CONST;
+
+void 		glade_preview_kill_preview	(GladePreview *preview);
+
+void 		glade_preview_remove_watch	(GladePreview *preview);
+
+GladePreview*	glade_preview_launch_preview	(gchar *buffer, GtkWidget *widget);
+
+void 		glade_preview_add_watch		(GladePreview *preview, 
+						 GChildWatchFunc function, 
+						 gpointer data);
+
+GtkWidget* 	glade_preview_get_widget	(GladePreview *preview);
+
+GPid 		glade_preview_get_pid		(GladePreview *preview);
+
+G_END_DECLS
+
+#endif /* _GLADE_PREVIEW_H_ */
diff --git a/gladeui/glade-project.c b/gladeui/glade-project.c
index a778f4c..ab5de74 100644
--- a/gladeui/glade-project.c
+++ b/gladeui/glade-project.c
@@ -46,6 +46,8 @@
 #include "glade-marshallers.h"
 #include "glade-catalog.h"
 
+#include "glade-preview.h"
+
 #include "glade-project.h"
 #include "glade-command.h"
 #include "glade-name-context.h"
@@ -164,8 +166,8 @@ struct _GladeProjectPrivate
 	gint       progress_full;
 	gboolean   load_cancel;
 
-	/* Store preview processes, so we can kill them on close */
-	GHashTable *preview_channels;
+	/* Store previews, so we can kill them on close */
+	GHashTable *previews;
 };
 
 typedef struct {
@@ -178,12 +180,6 @@ typedef struct {
 	gchar *filename;
 } StockFilePair;
 
-typedef struct {
-	GIOChannel *channel;
-	guint watch;
-} ChannelWatchPair;
-
-
 static void         glade_project_set_target_version       (GladeProject *project,
 							    const gchar  *catalog,
 							    guint16       major,
@@ -598,17 +594,14 @@ static void
 glade_project_preview_exits (GPid pid, gint status, gpointer data)
 {
 	GladeProject *project = (GladeProject *)data;
-	ChannelWatchPair *channel_watch;
-	GIOChannel *channel;
+	GladePreview *preview;
 	gchar *pidstr = g_strdup_printf ("%d", pid);
 
-	channel_watch = g_hash_table_lookup (project->priv->preview_channels, pidstr);
-	channel = channel_watch->channel;
-	g_io_channel_unref (channel);
-	g_hash_table_remove (project->priv->preview_channels, pidstr);
+	preview = g_hash_table_lookup (project->priv->previews, pidstr);
+	g_hash_table_remove (project->priv->previews, pidstr);
 
 	g_free (pidstr);
-	g_free (channel_watch);
+	g_object_unref (preview);
 }
 
 static void
@@ -616,46 +609,20 @@ glade_project_kill_previews (gpointer key,
 			     gpointer value,
 			     gpointer user_data)
 {
-	const gchar *quit = "<quit>";
-	GIOChannel *channel;
-	ChannelWatchPair *channel_watch = (ChannelWatchPair *) value;
-	GError *error = NULL;
-	gsize size;
+	GladePreview *preview = GLADE_PREVIEW (value);
 
-	channel = channel_watch->channel;
 	/* Removing watch, since the child will commit suicide */
-	g_source_remove (channel_watch->watch);
-	g_io_channel_write_chars (channel, quit, strlen (quit), &size, &error);
-
-	if (size != strlen (quit) && error != NULL)
-	{
-		g_printerr ("Error passing quit signal trough pipe: %s", error->message);
-		g_error_free (error);
-	}
-
-	g_io_channel_flush (channel, &error);
-	if (error != NULL)
-	{
-		g_printerr ("Error flushing channel: %s", error->message);
-		g_error_free (error);
-	}
-
-	g_io_channel_shutdown (channel, TRUE, &error);
-	if (error != NULL)
-	{
-		g_printerr ("Error shutting down channel: %s", error->message);
-		g_error_free (error);
-	}
-
-	g_io_channel_unref (channel);
-	g_free (channel_watch);
+	glade_preview_remove_watch (preview);
+	glade_preview_kill_preview (preview);
+	g_object_unref (preview);
 }
 
 static void
 glade_project_close_impl (GladeProject *project)
 {
-	g_hash_table_foreach (project->priv->preview_channels, glade_project_kill_previews, project);
-	g_hash_table_unref (project->priv->preview_channels);
+	g_hash_table_foreach (project->priv->previews, glade_project_kill_previews, project);
+	g_hash_table_unref (project->priv->previews);
+	project->priv->previews = NULL;
 }
 
 static void
@@ -700,7 +667,7 @@ glade_project_init (GladeProject *project)
 	priv->first_modification = NULL;
 	priv->first_modification_is_na = FALSE;
 
-	priv->preview_channels = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+	priv->previews = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
 	priv->previewable = FALSE;
 	priv->toplevel_names = glade_name_context_new ();
 	priv->naming_policy = GLADE_POLICY_PROJECT_WIDE;
@@ -1991,87 +1958,31 @@ glade_project_save (GladeProject *project, const gchar *path, GError **error)
 	return ret > 0;
 }
 
-static GPid
-glade_project_launch_preview (GladeProject *project, gchar *buffer, GtkWidget *widget)
+static gboolean
+glade_project_check_previewed_widget (gpointer key, gpointer value, gpointer user_data)
 {
-	GPid pid;
-	GError *error = NULL;
-	gchar *argv[4];
-	gint child_stdin;
-	GIOChannel *output;
-	guint watch;
-	ChannelWatchPair *channel_watch;
-	GladeWidget *glade_widget;
-	
-
-	#ifdef WINDOWS
-	argv[0] = g_build_filename (glade_app_get_bin_dir(), "glade-previewer.exe", NULL);
-	#else
-	argv[0] = g_build_filename (glade_app_get_bin_dir(), "glade-previewer", NULL);
-	#endif
-
-
-	argv[1] = "--listen";
-
-	if (widget != NULL)
-	{
-		glade_widget = glade_widget_get_from_gobject (G_OBJECT (widget));
-		argv[2] = g_strdup_printf ("--toplevel=%s", glade_widget->name);
-		argv[3] = NULL;
-	}
-
-	if (g_spawn_async_with_pipes (NULL,
-				      argv,
-				      NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL,
-				      &pid, &child_stdin, NULL, NULL, &error) == FALSE)
-	{
-		g_printerr (_("Error launching previewer: %s\n"), error->message);
-		glade_util_ui_message (glade_app_get_window(),
-				       GLADE_UI_ERROR, NULL,
-				       _("Failed to launch preview: %s.\n"),
-				       error->message);
-		g_error_free (error);
-		pid = 0;
-		goto end;
-	}
-
-	/* Store watch so we can remove it later */
-	watch = g_child_watch_add (pid, glade_project_preview_exits, project);
-
-	#ifdef WINDOWS
-	output = g_io_channel_win32_new_fd (child_stdin);
-	#else
-	output = g_io_channel_unix_new (child_stdin);
-	#endif
-
-	gsize bytes_written;
-	g_io_channel_write_chars (output, buffer, strlen (buffer), &bytes_written, &error);
-
-	if (bytes_written != strlen (buffer) && error != NULL)
-	{
-		g_printerr ("Error passing UI trough pipe: %s", error->message);
-		g_error_free (error);
-	}
-
-	g_io_channel_flush (output, &error);
-	if (error != NULL)
-	{
-		g_printerr ("Error flushing UI trough pipe: %s", error->message);
-		g_error_free (error);
-	}
-
-	if (widget != NULL) g_free (argv[2]);
+	if (!key || !value || !user_data) return FALSE;
+	GladePreview *preview = GLADE_PREVIEW (value);
+	GtkWidget *widget = (GtkWidget *)user_data;
+	return glade_preview_get_widget (preview) == widget;
+}
 
-	/* Adding channel to list of channels */
-	channel_watch = g_new (ChannelWatchPair, 1);
-	channel_watch->channel = output;
-	channel_watch->watch = watch;
-	g_hash_table_insert (project->priv->preview_channels, g_strdup_printf("%d", pid),
-							      channel_watch);
+static gboolean
+glade_project_has_preview (GladeProject *project, GtkWidget *widget)
+{
+	if (!project->priv->previews) return FALSE;
+	return g_hash_table_find(
+			project->priv->previews,
+			glade_project_check_previewed_widget,
+			widget) != NULL;
+}
 
-	end:
-	g_free (argv[0]);
-	return pid;
+static void
+glade_project_add_preview (GladePreview *preview, GladeProject *project)
+{
+	g_hash_table_insert (project->priv->previews,
+			     g_strdup_printf("%d", glade_preview_get_pid (preview)),
+			     preview);
 }
 
 /**
@@ -2090,6 +2001,7 @@ glade_project_preview (GladeProject *project, GladeWidget *gwidget)
 	GladeXmlContext *context;
 	gchar *text;
 	GtkWidget *widget;
+	GladePreview *preview;
 
 	g_return_if_fail (GLADE_IS_PROJECT (project));
 
@@ -2101,7 +2013,13 @@ glade_project_preview (GladeProject *project, GladeWidget *gwidget)
 	if (!GTK_IS_WIDGET (gwidget->object)) return;
 	widget = GTK_WIDGET (gwidget->object);
 
-	glade_project_launch_preview (project, text, widget);
+	if(!glade_project_has_preview (project, widget)) {
+		preview = glade_preview_launch_preview (text, widget);
+		glade_preview_add_watch (preview, glade_project_preview_exits, project);
+		/* Add preview to list of previews */
+		glade_project_add_preview (preview, project);
+	}
+
 
 	g_free (text);
 }
@@ -3220,6 +3138,7 @@ glade_project_remove_object (GladeProject *project, GObject *object)
 {
 	GladeWidget   *gwidget;
 	GList         *list, *children;
+	GladePreview *preview = NULL;
 	
 	g_return_if_fail (GLADE_IS_PROJECT (project));
 	g_return_if_fail (G_IS_OBJECT      (object));
@@ -3257,6 +3176,16 @@ glade_project_remove_object (GladeProject *project, GObject *object)
 	project->priv->objects = g_list_remove (project->priv->objects, object);
 	g_object_unref (gwidget);
 
+	/* Check if there is a preview of such object */
+	if (project->priv->previews)
+	preview = g_hash_table_find (project->priv->previews,
+					   glade_project_check_previewed_widget,
+					   GTK_WIDGET(object));
+
+	if (preview)
+		glade_preview_kill_preview (preview);
+
+
 	glade_project_update_previewable (project);
 }
 
