Index: embed/print-dialog.c
===================================================================
RCS file: /cvs/gnome/epiphany/embed/print-dialog.c,v
retrieving revision 1.10
diff -u -p -r1.10 print-dialog.c
--- embed/print-dialog.c	1 Sep 2003 23:20:08 -0000	1.10
+++ embed/print-dialog.c	14 Sep 2003 14:42:04 -0000
@@ -1,5 +1,7 @@
 /*
+ *  Copyright (C) 2000, 2001, 2002 Marco Pesenti Gritti
  *  Copyright (C) 2002 Jorn Baayen
+ *  Copyright (C) 2003 Christian Persch
  *
  *  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,71 +20,34 @@
  *  $Id: print-dialog.c,v 1.10 2003/09/01 23:20:08 chpe Exp $
  */
 
-#include "print-dialog.h"
-#include "ephy-prefs.h"
-#include <gtk/gtkdialog.h>
-#include <gtk/gtkstock.h>
-#include <libgnomevfs/gnome-vfs-utils.h>
-
-#define CONF_PRINT_BOTTOM_MARGIN "/apps/epiphany/dialogs/print_bottom_margin"
-#define CONF_PRINT_TOP_MARGIN "/apps/epiphany/dialogs/print_top_margin"
-#define CONF_PRINT_LEFT_MARGIN "/apps/epiphany/dialogs/print_left_margin"
-#define CONF_PRINT_RIGHT_MARGIN "/apps/epiphany/dialogs/print_right_margin"
-#define CONF_PRINT_PAGE_TITLE "/apps/epiphany/dialogs/print_page_title"
-#define CONF_PRINT_PAGE_URL "/apps/epiphany/dialogs/print_page_url"
-#define CONF_PRINT_DATE "/apps/epiphany/dialogs/print_date"
-#define CONF_PRINT_PAGE_NUMBERS "/apps/epiphany/dialogs/print_page_numbers"
-#define CONF_PRINT_PRINTER "/apps/epiphany/dialogs/print_printer"
-#define CONF_PRINT_FILE "/apps/epiphany/dialogs/print_file"
-#define CONF_PRINT_PRINTON "/apps/epiphany/dialogs/print_on"
-#define CONF_PRINT_PAPER "/apps/epiphany/dialogs/print_paper"
-#define CONF_PRINT_ALL_PAGES "/apps/epiphany/dialogs/print_all_pages"
-#define CONF_PRINT_COLOR "/apps/epiphany/dialogs/print_color"
-#define CONF_PRINT_ORIENTATION "/apps/epiphany/dialogs/print_orientation"
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
 
-static void print_dialog_class_init (PrintDialogClass *klass);
-static void print_dialog_init (PrintDialog *dialog);
-
-/* Glade callbacks */
-void
-print_cancel_button_cb (GtkWidget *widget,
-			EphyDialog *dialog);
-void
-print_ok_button_cb (GtkWidget *widget,
-		    EphyDialog *dialog);
-void
-print_preview_button_cb (GtkWidget *widget,
-	 	         EphyDialog *dialog);
+#include "print-dialog.h"
 
-static GObjectClass *parent_class = NULL;
+#include "ephy-file-helpers.h"
+#include "ephy-types.h"
+#include "ephy-debug.h"
+
+#include <bonobo/bonobo-i18n.h>
+#include <libgnomeprint/gnome-print-config.h>
+#include <libgnomeprint/gnome-print-job.h>
+#include <libgnomevfs/gnome-vfs-utils.h>
+#include <unistd.h>
+#include <string.h>
 
 #define EPHY_PRINT_DIALOG_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), EPHY_TYPE_PRINT_DIALOG, PrintDialogPrivate))
 
 struct PrintDialogPrivate
 {
-	GtkWidget *window;
+	EphyEmbed *embed;
 };
 
 enum
 {
-	WINDOW_PROP,
-	PRINTON_PROP,
-	PRINTER_PROP,
-	FILE_PROP,
-	PAPER_PROP,
-	TOP_PROP,
-	BOTTOM_PROP,
-	LEFT_PROP,
-	RIGHT_PROP,
-	PAGE_TITLE_PROP,
-	PAGE_URL_PROP,
-	PAGE_NUMBERS_PROP,
-	DATE_PROP,
-	ALL_PAGES_PROP,
-	TO_PROP,
-	FROM_PROP,
-	COLOR_PROP,
-	ORIENTATION_PROP
+	PROP_0,
+	PROP_EMBED
 };
 
 enum
@@ -91,39 +56,19 @@ enum
 	LAST_SIGNAL
 };
 
-static const
-EphyDialogProperty properties [] =
-{
-	{ WINDOW_PROP, "print_dialog", NULL, PT_NORMAL, NULL },
-	{ PRINTON_PROP, "printer_radiobutton", CONF_PRINT_PRINTON, PT_NORMAL, NULL },
-	{ PRINTER_PROP, "printer_entry", CONF_PRINT_PRINTER, PT_NORMAL, NULL },
-	{ FILE_PROP, "file_entry", CONF_PRINT_FILE, PT_NORMAL, NULL },
-	{ PAPER_PROP,"A4_radiobutton", CONF_PRINT_PAPER, PT_NORMAL, NULL },
-	{ TOP_PROP, "top_spinbutton", CONF_PRINT_TOP_MARGIN, PT_NORMAL, NULL },
-        { BOTTOM_PROP, "bottom_spinbutton", CONF_PRINT_BOTTOM_MARGIN, PT_NORMAL, NULL },
-	{ LEFT_PROP,"left_spinbutton", CONF_PRINT_LEFT_MARGIN, PT_NORMAL, NULL },
-	{ RIGHT_PROP, "right_spinbutton", CONF_PRINT_RIGHT_MARGIN, PT_NORMAL, NULL },
-	{ PAGE_TITLE_PROP, "print_page_title_checkbutton", CONF_PRINT_PAGE_TITLE, PT_NORMAL, NULL },
-	{ PAGE_URL_PROP, "print_page_url_checkbutton", CONF_PRINT_PAGE_URL, PT_NORMAL, NULL },
-	{ PAGE_NUMBERS_PROP, "print_page_numbers_checkbutton", CONF_PRINT_PAGE_NUMBERS, PT_NORMAL, NULL },
-	{ DATE_PROP, "print_date_checkbutton", CONF_PRINT_DATE, PT_NORMAL, NULL },
-	{ ALL_PAGES_PROP, "all_pages_radiobutton", CONF_PRINT_ALL_PAGES, PT_NORMAL, NULL },
-	{ TO_PROP, "to_spinbutton", NULL, PT_NORMAL, NULL },
-	{ FROM_PROP, "from_spinbutton", NULL, PT_NORMAL, NULL },
-	{ COLOR_PROP, "print_color_radiobutton", CONF_PRINT_COLOR, PT_NORMAL, NULL },
-	{ ORIENTATION_PROP, "orient_p_radiobutton", CONF_PRINT_ORIENTATION, PT_NORMAL, NULL },
+static guint signals[LAST_SIGNAL] = { 0 };
 
-	{ -1, NULL, NULL }
-};
+static GObjectClass *parent_class = NULL;
 
-static const
-char *paper_format_enum [] =
-{
-	"A4", "Letter", "Legal", "Executive"
-};
-static guint n_paper_format_enum = G_N_ELEMENTS (paper_format_enum);
+/* global config */
+static GnomePrintConfig *global_config = NULL;
+static char *config_file = NULL;
+
+static void print_dialog_class_init	(PrintDialogClass *klass);
+static void print_dialog_init		(PrintDialog *dialog);
+static void print_dialog_finalize	(GObject *object);
 
-static guint print_dialog_signals[LAST_SIGNAL] = { 0 };
+#define PRINT_CONFIG_FILENAME	"ephy-print-config.xml"
 
 GType
 print_dialog_get_type (void)
@@ -144,289 +89,403 @@ print_dialog_get_type (void)
                         0, /* n_preallocs */
                         (GInstanceInitFunc) print_dialog_init
                 };
-
-                print_dialog_type = g_type_register_static (EPHY_TYPE_EMBED_DIALOG,
-						            "PrintDialog",
-						            &our_info, 0);
+                print_dialog_type = g_type_register_static (GNOME_TYPE_PRINT_DIALOG,
+							    "PrintDialog",
+							    &our_info, 0);
         }
 
         return print_dialog_type;
-
 }
 
 static void
-print_dialog_class_init (PrintDialogClass *klass)
+print_dialog_set_property (GObject *object,
+				guint prop_id,
+				const GValue *value,
+				GParamSpec *pspec)
 {
-        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        PrintDialog *dialog = EPHY_PRINT_DIALOG (object);
 
-        parent_class = g_type_class_peek_parent (klass);
+        switch (prop_id)
+        {
+                case PROP_EMBED:
+                        print_dialog_set_embed (dialog, g_value_get_object (value));
+                        break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
 
-	print_dialog_signals[PREVIEW] =
-                g_signal_new ("preview",
-                              G_OBJECT_CLASS_TYPE (object_class),
-                              G_SIGNAL_RUN_FIRST,
-                              G_STRUCT_OFFSET (PrintDialogClass, preview),
-                              NULL, NULL,
-                              g_cclosure_marshal_VOID__VOID,
-                              G_TYPE_NONE,
-                              0);
+static void
+print_dialog_get_property (GObject *object,
+				guint prop_id,
+				GValue *value,
+				GParamSpec *pspec)
+{
+        PrintDialog *dialog = EPHY_PRINT_DIALOG (object);
 
-	g_type_class_add_private (object_class, sizeof(PrintDialogPrivate));
+        switch (prop_id)
+        {
+                case PROP_EMBED:
+                        g_value_set_object (value, dialog->priv->embed);
+                        break;
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+        }
 }
 
-static void
-print_dialog_init (PrintDialog *dialog)
+#define SUCK	(const guchar*)
+
+static gboolean
+printing_done_and_idle_cb (GnomePrintConfig *config)
 {
-	GdkPixbuf *icon;
-	dialog->priv = EPHY_PRINT_DIALOG_GET_PRIVATE (dialog);
+	GnomePrintJob *job;
+	char *file, *str, *backend, *tempfile;
 
-	dialog->only_collect_info = FALSE;
-	dialog->ret_info = NULL;
+	LOG ("printing_done_and_idle_cb")
 
-	ephy_dialog_construct (EPHY_DIALOG(dialog),
-				 properties,
-				 "print.glade", "print_dialog");
+	g_return_val_if_fail (GNOME_IS_PRINT_CONFIG (config), FALSE);
 
-	dialog->priv->window = ephy_dialog_get_control (EPHY_DIALOG(dialog), WINDOW_PROP);
+	/* FIXME: this was in xd2's gnomeprint patch for galeon,
+	 * what's it good for ?
+	 */
+	fflush(NULL);
 
-	ephy_dialog_add_enum (EPHY_DIALOG (dialog), PAPER_PROP,
-			      n_paper_format_enum, paper_format_enum);
-	
-	icon = gtk_widget_render_icon (dialog->priv->window, 
-						      GTK_STOCK_PRINT,
-						      GTK_ICON_SIZE_MENU,
-						      "print_dialog");
-	gtk_window_set_icon (GTK_WINDOW(dialog->priv->window), icon);
-	g_object_unref (icon);
+	/* get temp file name */
+	tempfile = (char *) g_object_get_data (G_OBJECT (config), "tempfile");
+	if (tempfile == NULL)
+	{
+		g_object_unref (config);
+		return FALSE;
+	}
+
+	/* create new print job */
+	job = gnome_print_job_new (config);
+	gnome_print_job_set_file (job, tempfile);
+
+	backend = (char *) gnome_print_config_get (config, SUCK "Settings.Transport.Backend");
+	str = (char *) gnome_print_config_get (config, SUCK "Settings.Transport.Backend.FileName");
+	file = gnome_vfs_expand_initial_tilde (str);
+
+	LOG ("Backend %s", backend)
+	LOG ("Printing from tempfile %s", tempfile)
+
+	if (file && backend && strncmp (backend, "file", 4) == 0)
+	{
+		LOG ("Printing to file %s", file)
+
+		gnome_print_job_print_to_file (job, file);
+	}
+
+	/* FIXME: warn on unsuccessful print (at least when printing to file) */
+	gnome_print_job_print (job);
+
+	g_free (backend);
+	g_free (file);
+	g_free (str);
+
+	/* cleanup */
+	unlink (tempfile);
+
+	g_object_unref (config);
+	g_object_unref (job);
+
+	/* don't run again */
+	return FALSE;
 }
 
-EphyDialog *
-print_dialog_new (EphyEmbed *embed,
-		  EmbedPrintInfo **ret_info)
+static gboolean
+printing_done_cb (GObject *data)
 {
-	PrintDialog *dialog;
+	g_object_ref (data);
+	g_idle_add ((GSourceFunc) printing_done_and_idle_cb, data);
 
-	dialog = EPHY_PRINT_DIALOG (g_object_new (EPHY_TYPE_PRINT_DIALOG,
-						  "embed", embed,
-						  NULL));
+	return TRUE;
+}
 
-	if (!embed) dialog->only_collect_info = TRUE;
-	dialog->ret_info = ret_info;
+static void
+print_dialog_print (PrintDialog *dialog, gboolean preview)
+{
+	GnomePrintConfig *config;
+	char *tempfile, *path;
+	const char *dir;
+	gresult result;
+
+	g_return_if_fail (dialog->priv->embed != NULL);
+
+	/* FIXME: once we have custom nb pages for them,
+	 * translate the margin/header/footer/colour/... settings to the config */
+
+	/* dup the config so that it doesn't change while we use it to print */
+	config = gnome_print_config_dup (global_config);
+
+	/* generate temp file name */
+	// FIXME is this the right env var??
+	dir = g_getenv ("TMP");
+	if (dir == NULL)
+	{
+		dir = "/tmp";
+	}
+	path = g_build_filename (dir, "ephy-print-XXXXXX", NULL);
+	tempfile = ephy_file_tmp_filename (path, "ps");
+	g_free (path);
+
+	/* set temp file name and callback info */
+	g_object_set_data_full (G_OBJECT (config), "tempfile", tempfile,
+				(GDestroyNotify) g_free);
+	g_object_set_data (G_OBJECT (config), "callback",
+			   (GSourceFunc) printing_done_cb);
+
+	/* do the deed */
+	result = ephy_embed_print (dialog->priv->embed, G_OBJECT (config), preview);
 
-	return EPHY_DIALOG(dialog);
+	/* clean up */
+	g_object_unref (config);
+
+	if (preview && result == G_OK)
+	{
+	        g_signal_emit (G_OBJECT (dialog), signals[PREVIEW], 0);
+	}
 }
 
-EphyDialog *
-print_dialog_new_with_parent (GtkWidget *window,
-			      EphyEmbed *embed,
-			      EmbedPrintInfo **ret_info)
+static void
+print_dialog_save_config (PrintDialog *dialog)
 {
-	PrintDialog *dialog;
+	// char *string;
 
-	dialog = EPHY_PRINT_DIALOG (g_object_new (EPHY_TYPE_PRINT_DIALOG,
-						  "embed", embed,
-						  "ParentWindow", window,
-						  NULL));
+	// string = gnome_print_config_to_string (global_config, 0);
+	// how to write config to file?
+	// g_free (string);
+}
 
-	if (!embed) dialog->only_collect_info = TRUE;
-	dialog->ret_info = ret_info;
+static void
+response_cb (GtkWidget *widget, int response_id, PrintDialog *dialog)
+{
+	LOG ("response_cb")
 
-	return EPHY_DIALOG(dialog);
+	switch (response_id)
+	{
+		case GNOME_PRINT_DIALOG_RESPONSE_PRINT:
+			print_dialog_print (dialog, FALSE);
+			print_dialog_save_config (dialog);
+			break;
+		case GNOME_PRINT_DIALOG_RESPONSE_PREVIEW:
+			print_dialog_print (dialog, TRUE);
+			print_dialog_save_config (dialog);
+			break;
+	}
+
+	gtk_widget_destroy (widget);
 }
 
-void
-print_free_info (EmbedPrintInfo *info)
+static void
+impl_show (GtkWidget *widget)
 {
-	g_free (info->printer);
-	g_free (info->file);
-	g_free (info->paper);
-	g_free (info->header_left_string);
-	g_free (info->header_center_string);
-	g_free (info->header_right_string);
-	g_free (info->footer_left_string);
-	g_free (info->footer_center_string);
-	g_free (info->footer_right_string);
-	g_free (info);
-}
-
-static EmbedPrintInfo *
-print_get_info (EphyDialog *dialog)
-{
-	EmbedPrintInfo *info;
-	GValue print_to_file = {0, };
-	GValue printer = {0, };
-	GValue file = {0, };
-	GValue top_margin = {0, };
-	GValue bottom_margin = {0, };
-	GValue left_margin = {0, };
-	GValue right_margin = {0, };
-	GValue from_page = {0, };
-	GValue to_page = {0, };
-	GValue paper = {0, };
-	GValue pages = {0, };
-	GValue print_color = {0, };
-	GValue orientation = {0, };
-	GValue page_title = {0, };
-	GValue page_url = {0, };
-	GValue date = {0, };
-	GValue page_numbers = {0, };
-
-	info = g_new0 (EmbedPrintInfo, 1);
-
-	ephy_dialog_get_value (dialog, PRINTON_PROP, &print_to_file);
-	info->print_to_file = g_value_get_int (&print_to_file);
-	g_value_unset (&print_to_file);
-
-	ephy_dialog_get_value (dialog, PRINTER_PROP, &printer);
-	info->printer = g_strdup (g_value_get_string (&printer));
-	g_value_unset (&printer);
-
-	ephy_dialog_get_value (dialog, FILE_PROP, &file);
-	info->file = gnome_vfs_expand_initial_tilde (g_value_get_string (&file));
-	g_value_unset (&file);
-
-	ephy_dialog_get_value (dialog, BOTTOM_PROP, &bottom_margin);
-	info->bottom_margin = g_value_get_float (&bottom_margin);
-	g_value_unset (&bottom_margin);
-
-	ephy_dialog_get_value (dialog, LEFT_PROP, &left_margin);
-	info->left_margin = g_value_get_float (&left_margin);
-	g_value_unset (&left_margin);
-
-	ephy_dialog_get_value (dialog, TOP_PROP, &top_margin);
-	info->top_margin = g_value_get_float (&top_margin);
-	g_value_unset (&top_margin);
-
-	ephy_dialog_get_value (dialog, RIGHT_PROP, &right_margin);
-	info->right_margin = g_value_get_float (&right_margin);
-	g_value_unset (&right_margin);
-
-	ephy_dialog_get_value (dialog, FROM_PROP, &from_page);
-	info->from_page = g_value_get_float (&from_page);
-	g_value_unset (&from_page);
-
-	ephy_dialog_get_value (dialog, TO_PROP, &to_page);
-	info->to_page = g_value_get_float (&to_page);
-	g_value_unset (&to_page);
-
-	ephy_dialog_get_value (dialog, PAPER_PROP, &paper);
-	info->paper = g_strdup (paper_format_enum[g_value_get_int (&paper)]);
-	g_value_unset (&paper);
-
-	ephy_dialog_get_value (dialog, ALL_PAGES_PROP, &pages);
-	info->pages = g_value_get_int (&pages);
-	g_value_unset (&pages);
-
-	ephy_dialog_get_value (dialog, COLOR_PROP, &print_color);
-	info->print_color = !g_value_get_int (&print_color);
-	g_value_unset (&print_color);
-
-	ephy_dialog_get_value (dialog, ORIENTATION_PROP, &orientation);
-	info->orientation = g_value_get_int (&orientation);
-	g_value_unset (&orientation);
-
-	info->frame_type = 0;
-
-	ephy_dialog_get_value (dialog, PAGE_TITLE_PROP, &page_title);
-	info->header_left_string = g_value_get_boolean (&page_title) ?
-				   g_strdup ("&T") : g_strdup ("");
-	g_value_unset (&page_title);
-
-	ephy_dialog_get_value (dialog, PAGE_URL_PROP, &page_url);
-	info->header_right_string = g_value_get_boolean (&page_url) ?
-				    g_strdup ("&U") : g_strdup ("");
-	g_value_unset (&page_url);
-
-	ephy_dialog_get_value (dialog, PAGE_NUMBERS_PROP, &page_numbers);
-	info->footer_left_string = g_value_get_boolean (&page_numbers) ?
-				   g_strdup ("&PT") : g_strdup ("");
-	g_value_unset (&page_numbers);
-
-	ephy_dialog_get_value (dialog, DATE_PROP, &date);
-	info->footer_right_string = g_value_get_boolean (&date) ?
-				    g_strdup ("&D") : g_strdup ("");
-	g_value_unset (&date);
-
-	info->header_center_string = g_strdup("");
-	info->footer_center_string = g_strdup("");
+	/* construct the beast */
+	gnome_print_dialog_construct (GNOME_PRINT_DIALOG (widget),
+				      (const guchar *) _("Print"),
+				      GNOME_PRINT_DIALOG_RANGE |
+				      GNOME_PRINT_DIALOG_COPIES);
+
+	gnome_print_dialog_construct_range_page (GNOME_PRINT_DIALOG (widget),
+						 GNOME_PRINT_RANGE_ALL |
+						 GNOME_PRINT_RANGE_RANGE |
+						 GNOME_PRINT_RANGE_SELECTION,
+						 1,
+						 1,
+						 NULL,
+						 _("Pages"));
+
+	g_signal_connect (G_OBJECT (widget), "response",
+			  G_CALLBACK (response_cb), widget);
 
-	return info;
+	/* FIXME: append custom notebook page for
+	   margins, headers, footers, colour/grayscale, etc. */
+
+	/* GnomePrintDialog SUCKS!! - let's show the margin selectors */
+	gtk_widget_show_all (GNOME_PRINT_DIALOG (widget)->notebook);
+
+	GTK_WIDGET_CLASS (parent_class)->show (widget);
 }
 
 static void
-print_dialog_print (EphyDialog *dialog)
+print_init_config (void)
 {
-	EmbedPrintInfo *info;
-	EphyEmbed *embed;
-
-	info = print_get_info (dialog);
+	char *config_string;
+	gsize len;
+	
+	/* FIXME: we need to unref global_config and g_free config_file
+	 * somewhere on exit...
+	 */
+
+	config_file = g_build_filename (ephy_dot_dir (),
+					PRINT_CONFIG_FILENAME,
+					NULL);
 
-	if(EPHY_PRINT_DIALOG(dialog)->only_collect_info && EPHY_PRINT_DIALOG(dialog)->ret_info)
+	if (g_file_get_contents (config_file, &config_string, &len, NULL))
 	{
-		*(EPHY_PRINT_DIALOG(dialog)->ret_info) = info;
+		LOG ("loading from string")
+
+		global_config = gnome_print_config_from_string (config_string, 0);
+
+		g_free (config_string);
 	}
-	else
+
+	if (global_config == NULL)
 	{
-		embed = ephy_embed_dialog_get_embed
-			(EPHY_EMBED_DIALOG(dialog));
-		g_return_if_fail (embed != NULL);
+		LOG ("setting default config")
 
-		info->preview = FALSE;
-		ephy_embed_print (embed, info);
-		print_free_info (info);
+		global_config = gnome_print_config_default ();
 	}
 
-	g_object_unref (G_OBJECT(dialog));
+	g_assert (global_config != NULL);
+
+	// FIXME disable setting which are unsupported by gnomeprint's
+	// ps backend [like print-to-PDF, combine pages etc.]
 }
 
 static void
-print_dialog_preview (EphyDialog *dialog)
+print_dialog_class_init (PrintDialogClass *klass)
 {
-	EmbedPrintInfo *info;
-	EphyEmbed *embed;
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+	GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+
+        parent_class = g_type_class_peek_parent (klass);
 
-	info = print_get_info (dialog);
+        object_class->finalize = print_dialog_finalize;
+	object_class->set_property = print_dialog_set_property;
+	object_class->get_property = print_dialog_get_property;
 
-	if(EPHY_PRINT_DIALOG(dialog)->only_collect_info && EPHY_PRINT_DIALOG(dialog)->ret_info)
+	widget_class->show = impl_show;
+
+	signals[PREVIEW] =
+                g_signal_new ("preview",
+                              G_OBJECT_CLASS_TYPE (object_class),
+                              G_SIGNAL_RUN_FIRST,
+                              G_STRUCT_OFFSET (PrintDialogClass, preview),
+                              NULL, NULL,
+                              g_cclosure_marshal_VOID__VOID,
+                              G_TYPE_NONE,
+                              0);
+
+	g_object_class_install_property (object_class,
+					 PROP_EMBED,
+                                         g_param_spec_object ("embed",
+                                                              "Embed",
+                                                              "The dialog's embed",
+                                                              G_TYPE_OBJECT,
+                                                              G_PARAM_READWRITE));
+
+	g_type_class_add_private (object_class, sizeof (PrintDialogPrivate));
+
+	print_init_config ();
+}
+
+static void
+sync_page_change (EphyEmbed *embed, PrintDialog *dialog)
+{
+	char *title, *embed_title;
+
+	ephy_embed_get_title (embed, &embed_title);
+	if (embed_title && embed_title[0] != '\0')
 	{
-		*(EPHY_PRINT_DIALOG(dialog)->ret_info) = info;
+		title = g_strdup_printf ("Print \"%s\"", embed_title);
 	}
 	else
 	{
-		embed = ephy_embed_dialog_get_embed
-			(EPHY_EMBED_DIALOG(dialog));
-		g_return_if_fail (embed != NULL);
-
-		info->preview = TRUE;
-		ephy_embed_print (embed, info);
-		print_free_info (info);
+		title = g_strdup ("Print");
 	}
-	g_signal_emit (G_OBJECT (dialog), print_dialog_signals[PREVIEW], 0);
 
-	g_object_unref (G_OBJECT(dialog));
+	gtk_window_set_title (GTK_WINDOW (dialog), title);
+
+	g_free (title);
+	g_free (embed_title);
 }
 
-void
-print_cancel_button_cb (GtkWidget *widget,
-			EphyDialog *dialog)
+static void
+unset_embed (PrintDialog *dialog)
 {
-	g_object_unref (G_OBJECT(dialog));
+	if (dialog->priv->embed != NULL)
+	{
+		g_signal_handlers_disconnect_by_func (dialog->priv->embed,
+						      G_CALLBACK (sync_page_change),
+						      dialog);
+
+		g_object_remove_weak_pointer (G_OBJECT (dialog->priv->embed),
+					      (gpointer *)&dialog->priv->embed);
+
+		dialog->priv->embed = NULL;
+	}
 }
 
 void
-print_ok_button_cb (GtkWidget *widget,
-		    EphyDialog *dialog)
+print_dialog_set_embed (PrintDialog *dialog, EphyEmbed *embed)
 {
-	print_dialog_print (dialog);
+	g_return_if_fail (EPHY_IS_EMBED (embed));
+
+	unset_embed (dialog);
+	dialog->priv->embed = embed;
+
+	sync_page_change (embed, dialog);
+	g_signal_connect (G_OBJECT (embed), "ge_title",
+			  G_CALLBACK (sync_page_change), dialog);
+
+	g_object_add_weak_pointer (G_OBJECT (embed),
+				   (gpointer *)&dialog->priv->embed);
 }
 
-void
-print_preview_button_cb (GtkWidget *widget,
-		         EphyDialog *dialog)
+static void
+print_dialog_init (PrintDialog *dialog)
 {
-	//FIXME: Don't show preview button at all.
-	if(!(EPHY_PRINT_DIALOG(dialog)->only_collect_info))
-		print_dialog_preview (dialog);
+	LOG ("PrintDialog initialising %p", dialog)
+
+	dialog->priv = EPHY_PRINT_DIALOG_GET_PRIVATE (dialog);
+
+	dialog->priv->embed = NULL;
+
+	LOG ("in INIT: global_config %p", global_config)
+
+	/* NOTE: we can't construct the dialogue here, because, you've
+	 * guessed it, libgnomeprintui sucks.
+	 */
 }
 
+static void
+print_dialog_finalize (GObject *object)
+{
+	PrintDialog *dialog = EPHY_PRINT_DIALOG (object);
+
+	unset_embed (dialog);
 
+	LOG ("PrintDialog finalised %p", object)
+
+        G_OBJECT_CLASS (parent_class)->finalize (object);
+}
+
+PrintDialog *
+print_dialog_new (EphyEmbed *embed)
+{
+	PrintDialog *dialog;
+
+	dialog = EPHY_PRINT_DIALOG (g_object_new (EPHY_TYPE_PRINT_DIALOG,
+						  "embed", embed,
+						  NULL));
+
+	g_object_set (G_OBJECT (dialog), "print_config", global_config, NULL);
+
+	return dialog;
+}
+
+PrintDialog *
+print_dialog_new_with_parent (GtkWidget *parent, EphyEmbed *embed)
+{
+	PrintDialog *dialog;
+	
+	dialog = print_dialog_new (embed);
+
+	gtk_window_set_transient_for (GTK_WINDOW (dialog),
+				      GTK_WINDOW (parent));
+
+	return dialog;
+}
