gedit r6057 - branches/printing/gedit



Author: pborelli
Date: Sun Jan  6 18:19:16 2008
New Revision: 6057
URL: http://svn.gnome.org/viewvc/gedit?rev=6057&view=rev

Log:
first cut a print preview widget


Added:
   branches/printing/gedit/gedit-print-preview.c
   branches/printing/gedit/gedit-print-preview.h
Modified:
   branches/printing/gedit/Makefile.am
   branches/printing/gedit/gedit-commands-file-print.c
   branches/printing/gedit/gedit-tab.c

Modified: branches/printing/gedit/Makefile.am
==============================================================================
--- branches/printing/gedit/Makefile.am	(original)
+++ branches/printing/gedit/Makefile.am	Sun Jan  6 18:19:16 2008
@@ -69,15 +69,13 @@
 	gedit-local-document-saver.h	\
 	gedit-gnomevfs-document-saver.h	\
 	gedit-history-entry.h		\
-	gedit-print.h			\
-	gedit-print-job-preview.h	\
+	gedit-print-preview.h	\
 	gedit-io-error-message-area.h	\
 	gedit-spinner.h			\
 	gedit-prefs-manager-private.h	\
 	sexy-icon-entry.h		\
 	gedittextregion.h		\
-	gedit-session.h			\
-	gtksourceprintjob.h
+	gedit-session.h
 
 if ENABLE_PYTHON
 NOINST_H_FILES += \
@@ -153,8 +151,7 @@
 	gedit-prefs-manager-app.c	\
 	gedit-prefs-manager.c		\
 	gedit-prefs-manager-private.h	\
-	gedit-print.c			\
-	gedit-print-job-preview.c	\
+	gedit-print-preview.c		\
 	gedit-progress-message-area.c	\
 	gedit-session.c			\
 	gedit-spinner.c			\
@@ -166,7 +163,6 @@
 	gedit-window.c			\
 	sexy-icon-entry.c		\
 	gedittextregion.c		\
-	gtksourceprintjob.c		\
 	$(NOINST_H_FILES)		\
 	$(INST_H_FILES)
 

Modified: branches/printing/gedit/gedit-commands-file-print.c
==============================================================================
--- branches/printing/gedit/gedit-commands-file-print.c	(original)
+++ branches/printing/gedit/gedit-commands-file-print.c	Sun Jan  6 18:19:16 2008
@@ -34,177 +34,321 @@
 #include <config.h>
 #endif
 
+#include <math.h>
+
+#include <pango/pangocairo.h>
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
+#include <gtk/gtkprintoperation.h>
+#include <gtksourceview/gtksourceprintcompositor.h>
 
 #include "gedit-commands.h"
+#include "gedit-print-preview.h"
 #include "gedit-window.h"
 #include "gedit-debug.h"
-#include "gedit-print.h"
-#include "dialogs/gedit-page-setup-dialog.h"
 
+#define LINE_NUMBERS_FONT_NAME   "Monospace 6"
+#define HEADER_FONT_NAME   "Serif Italic 12"
+#define FOOTER_FONT_NAME   "SansSerif Bold 8"
+
+static GtkPageSetup *page_setup = NULL;
+static GtkPrintSettings *settings = NULL;
+static GList *active_prints = NULL;
 
-void
-_gedit_cmd_file_page_setup (GtkAction   *action,
-			   GeditWindow *window)
+static void
+do_page_setup (GtkWindow *window)
 {
-	gedit_debug (DEBUG_COMMANDS);
+	GtkPageSetup *new_page_setup;
 
-	gedit_show_page_setup_dialog (GTK_WINDOW (window));
+	new_page_setup = gtk_print_run_page_setup_dialog (window,
+							  page_setup,
+							  settings);
+
+	if (page_setup)
+		g_object_unref (page_setup);
+  
+	page_setup = new_page_setup;
 }
 
-void
-_gedit_cmd_file_print_preview (GtkAction   *action,
-			      GeditWindow *window)
+static void
+status_changed_cb (GtkPrintOperation *op,
+		   gpointer user_data)
 {
-	GeditDocument *doc;
-	GeditTab      *tab;
-	GeditPrintJob *pjob;
-	GtkTextIter    start;
-	GtkTextIter    end;
+  if (gtk_print_operation_is_finished (op))
+    {
+      active_prints = g_list_remove (active_prints, op);
+      g_object_unref (op);
+    }
 
-	gedit_debug (DEBUG_COMMANDS);
+//  update_statusbar ();
+}
 
-	tab = gedit_window_get_active_tab (window);
-	if (tab == NULL)
-		return;
+//static GtkWidget *
+//create_custom_widget (GtkPrintOperation *operation,
+//		      gpointer          *data)
+//{
+//  GtkWidget *vbox, *hbox, *font, *label;
+
+//  gtk_print_operation_set_custom_tab_label (operation, "Other");
+//  vbox = gtk_vbox_new (FALSE, 0);
+//  gtk_container_set_border_width (GTK_CONTAINER (vbox), 12);
+
+//  hbox = gtk_hbox_new (FALSE, 8);
+//  gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+//  gtk_widget_show (hbox);
+
+//  label = gtk_label_new ("Font:");
+//  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
+//  gtk_widget_show (label);
+//  
+//  font = gtk_font_button_new_with_font  (data->font);
+//  gtk_box_pack_start (GTK_BOX (hbox), font, FALSE, FALSE, 0);
+//  gtk_widget_show (font);
+//  data->font_button = font;
+
+//  return vbox;
+//}
+
+//static void
+//custom_widget_apply (GtkPrintOperation *operation,
+//		     GtkWidget *widget,
+//		     PrintData *data)
+//{
+//  const char *selected_font;
+//  selected_font = gtk_font_button_get_font_name  (GTK_FONT_BUTTON (data->font_button));
+//  g_free (data->font);
+//  data->font = g_strdup (selected_font);
+//}
+
+static gboolean 
+run_preview (GtkPrintOperation        *op,
+	     GtkPrintOperationPreview *gtk_preview,
+	     GtkPrintContext          *context,
+	     GtkWindow                *parent,
+	     GeditTab                 *tab)
+{
+	GtkWidget *window;
+	GtkWidget *preview;
 
-	doc = gedit_tab_get_document (tab);
+	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_default_size (GTK_WINDOW (window), 400, 600);
 
-	pjob = gedit_print_job_new (doc);
+	preview = gedit_print_preview_new (op, gtk_preview, context);
+	gtk_container_add (GTK_CONTAINER (window), preview);
 
-	gtk_text_buffer_get_bounds (GTK_TEXT_BUFFER (doc) , &start, &end);
+	gtk_widget_show_all (window);
 
-	_gedit_tab_print_preview (tab, pjob, &start, &end);
-	g_object_unref (pjob);
+	return TRUE;
 }
 
 static void
-print_dialog_response_cb (GtkWidget *dialog,
-			  gint response,
-			  GeditPrintJob *pjob)
+print_done (GtkPrintOperation *op,
+	    GtkPrintOperationResult res,
+	    gpointer *data)
 {
-	GtkTextIter          start;
-	GtkTextIter          end;
-	gint                 line_start;
-	gint                 line_end;
-	GnomePrintRangeType  range_type;
-	GtkTextBuffer       *buffer;
-	GeditTab            *tab;
+  GError *error = NULL;
 
-	gedit_debug (DEBUG_COMMANDS);
-
-	range_type = gnome_print_dialog_get_range (GNOME_PRINT_DIALOG (dialog));
+  if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
+    {
 
-	buffer = GTK_TEXT_BUFFER (
-			gtk_source_print_job_get_buffer (GTK_SOURCE_PRINT_JOB (pjob)));
-
-	gtk_text_buffer_get_bounds (buffer, &start, &end);
+      GtkWidget *error_dialog;
+      
+      gtk_print_operation_get_error (op, &error);
+
+      error_dialog = gtk_message_dialog_new (NULL, //GTK_WINDOW (main_window),
+					     GTK_DIALOG_DESTROY_WITH_PARENT,
+					     GTK_MESSAGE_ERROR,
+					     GTK_BUTTONS_CLOSE,
+					     "Error printing file:\n%s",
+					     error ? error->message : "no details");
+      g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
+      gtk_widget_show (error_dialog);
+    }
+  else if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
+    {
+      if (settings != NULL)
+	g_object_unref (settings);
+      settings = g_object_ref (gtk_print_operation_get_print_settings (op));
+    }
+
+//  g_object_unref (print_data->buffer);
+//  g_free (print_data->font);
+//  g_free (print_data);
+  
+  if (!gtk_print_operation_is_finished (op))
+    {
+      g_object_ref (op);
+      active_prints = g_list_append (active_prints, op);
+//      update_statusbar ();
+      
+      /* This ref is unref:ed when we get the final state change */
+      g_signal_connect (op, "status_changed",
+			G_CALLBACK (status_changed_cb), NULL);
+    }
+}
 
-	tab = gedit_tab_get_from_document (GEDIT_DOCUMENT (buffer));
+static void
+begin_print (GtkPrintOperation        *operation, 
+	     GtkPrintContext          *context,
+	     GtkSourcePrintCompositor *compositor)
+{
+	g_debug ("begin_print");
+}
 
-	switch (range_type)
+static gboolean
+paginate (GtkPrintOperation        *operation, 
+	  GtkPrintContext          *context,
+	  GtkSourcePrintCompositor *compositor)
+{
+	g_print ("Pagination progress: %.2f %%\n", gtk_source_print_compositor_get_pagination_progress (compositor) * 100.0);
+	
+	if (gtk_source_print_compositor_paginate (compositor, context))
 	{
-		case GNOME_PRINT_RANGE_ALL:
-			break;
+		gint n_pages;
 
-		case GNOME_PRINT_RANGE_SELECTION:
-			gtk_text_buffer_get_selection_bounds (buffer,
-							      &start,
-							      &end);
-			break;
-
-		case GNOME_PRINT_RANGE_RANGE:
-			gnome_print_dialog_get_range_page (GNOME_PRINT_DIALOG (dialog),
-							   &line_start,
-							   &line_end);
-
-			/* The print dialog should ensure to set the
-			 * sensitivity of the spin buttons so that
-			 * the start and end lines are in ascending
-			 * order, but it doesn't.
-			 * We reorder them if needed */
-			if (line_start > line_end)
-			{
-				gint tmp;
-
-				gedit_debug_message (DEBUG_PRINT,
-						     "line start: %d, line end: %d. Swapping.",
-						     line_start,
-						     line_end);
-
-				tmp = line_start;
-				line_start = line_end;
-				line_end = tmp;
-			}
-
-			gtk_text_iter_set_line (&start, line_start - 1);
-			gtk_text_iter_set_line (&end, line_end - 1);
+		g_assert (gtk_source_print_compositor_get_pagination_progress (compositor) == 1.0);
+		g_print ("Pagination progress: %.2f %%\n", gtk_source_print_compositor_get_pagination_progress (compositor) * 100.0);
+		        
+		n_pages = gtk_source_print_compositor_get_n_pages (compositor);
+		gtk_print_operation_set_n_pages (operation, n_pages);
 
-			gtk_text_iter_forward_to_line_end (&end);
 
-			break;
-
-		default:
-			g_return_if_reached ();
+		
+		return TRUE;
 	}
+     
+	return FALSE;
+}
 
-	switch (response)
-	{
-		case GNOME_PRINT_DIALOG_RESPONSE_PRINT:
-			gedit_debug_message (DEBUG_PRINT,
-					     "Print button pressed.");
-
-			_gedit_tab_print (tab, pjob, &start, &end);
-
-			break;
-
-		case GNOME_PRINT_DIALOG_RESPONSE_PREVIEW:
-			gedit_debug_message (DEBUG_PRINT,
-					     "Preview button pressed.");
-
-			_gedit_tab_print_preview (tab, pjob, &start, &end);
+static void
+draw_page (GtkPrintOperation        *operation,
+	   GtkPrintContext          *context,
+	   gint                      page_nr,
+	   GtkSourcePrintCompositor *compositor)
+{
+	g_debug ("draw_page %d", page_nr);
 
-			break;
-        }
+	gtk_source_print_compositor_draw_page (compositor, context, page_nr);
+}
 
-        g_object_unref (pjob);
-	gtk_widget_destroy (dialog);
+static void
+end_print (GtkPrintOperation        *operation, 
+	   GtkPrintContext          *context,
+	   GtkSourcePrintCompositor *compositor)
+{
+	g_object_unref (compositor);
 }
 
 void
-_gedit_cmd_file_print (GtkAction   *action,
-		      GeditWindow *window)
+do_print_or_preview (GeditWindow             *window,
+		     GtkPrintOperationAction  print_action)
 {
+	GeditTab *tab;
+	GeditView *view;
 	GeditDocument *doc;
-	GeditPrintJob *pjob;
-	GtkWidget *print_dialog;
-	GtkWindowGroup *wg;
+	GtkSourcePrintCompositor *compositor;
+	GtkPrintOperation *operation;
+	gchar *name;
 
-	gedit_debug (DEBUG_COMMANDS);
+	tab = gedit_window_get_active_tab (window);
+	if (tab == NULL)
+		return;
+
+	view = gedit_tab_get_view (tab);
+	if (view == NULL)
+		return;
 
-	doc = gedit_window_get_active_document (window);
+	doc = gedit_tab_get_document (tab);
 	if (doc == NULL)
 		return;
 
-	pjob = gedit_print_job_new (doc);
+	compositor = gtk_source_print_compositor_new (GTK_SOURCE_BUFFER (doc));
+
+	gtk_source_print_compositor_set_tab_width (compositor,
+						   gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (view)));
+	gtk_source_print_compositor_set_wrap_mode (compositor,
+						   gtk_text_view_get_wrap_mode (GTK_TEXT_VIEW (view)));
+
+	gtk_source_print_compositor_set_print_line_numbers (compositor, 5);
+
+	/* To test line numbers font != text font */
+	gtk_source_print_compositor_set_line_numbers_font_name (compositor,
+								LINE_NUMBERS_FONT_NAME);
+
+	gtk_source_print_compositor_set_header_format (compositor,
+						       TRUE,
+						       "Printed on %A",
+						       "test-widget",
+						       "%F");
+
+	name = gedit_document_get_short_name_for_display (doc);
+	gtk_source_print_compositor_set_footer_format (compositor,
+						       TRUE,
+						       "%T",
+						       name,
+						       "Page %N/%Q");
+	g_free (name);
+
+	gtk_source_print_compositor_set_print_header (compositor, TRUE);
+	gtk_source_print_compositor_set_print_footer (compositor, TRUE);
+
+	gtk_source_print_compositor_set_header_font_name (compositor,
+							  HEADER_FONT_NAME);
+
+	gtk_source_print_compositor_set_footer_font_name (compositor,
+							  FOOTER_FONT_NAME);
+	
+	operation = gtk_print_operation_new ();
+	
+  	g_signal_connect (operation, "begin-print", 
+			  G_CALLBACK (begin_print), compositor);
+  	g_signal_connect (operation, "paginate", 
+			  G_CALLBACK (paginate), compositor);		          
+	g_signal_connect (operation, "draw-page", 
+			  G_CALLBACK (draw_page), compositor);
+	g_signal_connect (operation, "preview",
+			  G_CALLBACK (run_preview), tab);
+//	g_signal_connect (operation, "create_custom_widget",
+//			  G_CALLBACK (create_custom_widget), print_data);
+//	g_signal_connect (operation, "custom_widget_apply",
+//			  G_CALLBACK (custom_widget_apply), print_data);
+	g_signal_connect (operation, "end-print", 
+			  G_CALLBACK (end_print), compositor);
+	g_signal_connect (operation, "done",
+			  G_CALLBACK (print_done), compositor);
+
+	gtk_print_operation_run (operation, 
+				 print_action,
+				 GTK_WINDOW (window),
+				 NULL);
+
+	g_object_unref (operation);
+}
 
-	print_dialog = gedit_print_dialog_new (pjob);
+void
+_gedit_cmd_file_page_setup (GtkAction   *action,
+			    GeditWindow *window)
+{
+	gedit_debug (DEBUG_COMMANDS);
 
-	wg = gedit_window_get_group (window);
+	do_page_setup (GTK_WINDOW (window));
+}
 
-	gtk_window_group_add_window (wg,
-				     GTK_WINDOW (print_dialog));
+void
+_gedit_cmd_file_print_preview (GtkAction   *action,
+			       GeditWindow *window)
+{
+	gedit_debug (DEBUG_COMMANDS);
 
-	gtk_window_set_transient_for (GTK_WINDOW (print_dialog),
-				      GTK_WINDOW (window));
-	gtk_window_set_modal (GTK_WINDOW (print_dialog), TRUE);
+	do_print_or_preview (window, GTK_PRINT_OPERATION_ACTION_PREVIEW);
+}
 
-	g_signal_connect (print_dialog,
-			  "response",
-			  G_CALLBACK (print_dialog_response_cb),
-			  pjob);
+void
+_gedit_cmd_file_print (GtkAction   *action,
+		       GeditWindow *window)
+{
+	gedit_debug (DEBUG_COMMANDS);
 
-	gtk_widget_show (print_dialog);
+	do_print_or_preview (window, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG);
 }
 

Added: branches/printing/gedit/gedit-print-preview.c
==============================================================================
--- (empty file)
+++ branches/printing/gedit/gedit-print-preview.c	Sun Jan  6 18:19:16 2008
@@ -0,0 +1,970 @@
+/*
+ * gedit-print-preview.c
+ *
+ * Copyright (C) 2008 Paolo Borelli
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the gedit Team, 1998-2006. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: gedit-commands-search.c 5931 2007-09-25 20:05:40Z pborelli $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <math.h>
+#include <stdlib.h>
+#include <glib/gi18n.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include <cairo-pdf.h>
+
+#include "gedit-print-preview.h"
+
+#define PRINTER_DPI (72.)
+
+struct _GeditPrintPreviewPrivate
+{
+	GtkPrintOperation *operation;
+	GtkPrintContext *context;
+	GtkPrintOperationPreview *gtk_preview;
+
+	GtkWidget *layout;
+	GtkWidget *scrolled_window;
+
+	GtkToolItem *next;
+	GtkToolItem *prev;
+	GtkWidget   *page_entry;
+	GtkWidget   *last;
+	GtkToolItem *multi;
+	GtkToolItem *zoom_in;
+	GtkToolItem *zoom_out;
+
+	/* real size of the page in inches */
+	double paper_w;
+	double paper_h;
+	double dpi;
+
+	double scale;
+
+	/* size of the tile of a page (including padding
+	 * and drop shadow) in pixels */
+	gint tile_w;
+	gint tile_h;
+
+	/* multipage support */
+	gint rows;
+	gint cols;
+
+	guint n_pages;
+	guint cur_page;
+};
+
+enum {
+	CLOSE,
+	LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+G_DEFINE_TYPE (GeditPrintPreview, gedit_print_preview, GTK_TYPE_VBOX)
+
+static void	set_zoom_factor		(GeditPrintPreview *preview,
+					 double             zoom);
+
+static void 
+gedit_print_preview_get_property (GObject    *object,
+				  guint       prop_id,
+				  GValue     *value,
+				  GParamSpec *pspec)
+{
+	GeditPrintPreview *preview = GEDIT_PRINT_PREVIEW (object);
+	
+	switch (prop_id)
+	{
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void 
+gedit_print_preview_set_property (GObject      *object,
+				  guint         prop_id,
+				  const GValue *value,
+				  GParamSpec   *pspec)
+{
+	GeditPrintPreview *preview = GEDIT_PRINT_PREVIEW (object);
+	
+	switch (prop_id)
+	{
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+			break;
+	}
+}
+
+static void
+gedit_print_preview_finalize (GObject *object)
+{
+	GeditPrintPreview *preview = GEDIT_PRINT_PREVIEW (object);
+
+	G_OBJECT_CLASS (gedit_print_preview_parent_class)->finalize (object);
+}
+
+static void						 
+gedit_print_preview_class_init (GeditPrintPreviewClass *klass)
+{
+	GObjectClass *object_class;
+	GtkBindingSet *binding_set;
+
+	object_class = G_OBJECT_CLASS (klass);
+
+	object_class->get_property = gedit_print_preview_get_property;
+	object_class->set_property = gedit_print_preview_set_property;
+	object_class->finalize = gedit_print_preview_finalize;
+
+	signals[CLOSE] =  g_signal_new ("close",
+					G_OBJECT_CLASS_TYPE (klass),
+					G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+					G_STRUCT_OFFSET (GeditPrintPreviewClass, close),
+		  			NULL, NULL,
+		  			g_cclosure_marshal_VOID__VOID,
+					G_TYPE_NONE, 0);
+
+	binding_set = gtk_binding_set_by_class (klass);
+	gtk_binding_entry_add_signal (binding_set, GDK_Escape, 0, "close", 0);
+
+	g_type_class_add_private (object_class, sizeof(GeditPrintPreviewPrivate));	
+}
+
+static void
+goto_page (GeditPrintPreview *preview, gint page)
+{
+	gchar c[32];
+
+	g_snprintf (c, 32, "%d", page + 1);
+	gtk_entry_set_text (GTK_ENTRY (preview->priv->page_entry), c);
+
+	gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->prev),
+				  (page > 0) && (preview->priv->n_pages > 1));
+	gtk_widget_set_sensitive (GTK_WIDGET (preview->priv->next),
+				  (page != (preview->priv->n_pages - 1)) &&
+				  (preview->priv->n_pages > 1));
+
+	if (page != preview->priv->cur_page)
+	{
+		preview->priv->cur_page = page;
+		if (preview->priv->n_pages > 0)
+			gtk_widget_queue_draw (preview->priv->layout);
+	}
+}
+
+static void
+prev_button_clicked (GtkWidget         *button,
+		     GeditPrintPreview *preview)
+{
+	GdkEvent *event;
+
+	event = gtk_get_current_event ();
+
+	if (event->button.state & GDK_SHIFT_MASK)
+		goto_page (preview, 0);
+	else
+		goto_page (preview,
+			   MAX (preview->priv->cur_page - preview->priv->rows * preview->priv->cols,
+				0));
+
+	gdk_event_free (event);
+}
+
+static void
+next_button_clicked (GtkWidget         *button,
+		     GeditPrintPreview *preview)
+{
+	GdkEvent *event;
+
+	event = gtk_get_current_event ();
+
+	if (event->button.state & GDK_SHIFT_MASK)
+		goto_page (preview, preview->priv->n_pages - 1);
+	else
+		goto_page (preview,
+			   MIN (preview->priv->cur_page + preview->priv->rows * preview->priv->cols,
+			     	preview->priv->n_pages - 1));
+
+	gdk_event_free (event);
+}
+
+static void
+page_entry_activated (GtkEntry          *entry,
+		      GeditPrintPreview *preview)
+{
+	const gchar *text;
+	gint page;
+
+	text = gtk_entry_get_text (entry);
+
+	page = CLAMP (atoi (text), 1, preview->priv->n_pages) - 1;
+	goto_page (preview, page);
+
+	gtk_widget_grab_focus (GTK_WIDGET (preview->priv->layout));
+}
+
+static void
+page_entry_insert_text (GtkEditable *editable,
+			const gchar *text,
+			gint         length,
+			gint        *position)
+{
+	gunichar c;
+	const gchar *p;
+ 	const gchar *end;
+
+	p = text;
+	end = text + length;
+
+	while (p != end)
+	{
+		const gchar *next;
+		next = g_utf8_next_char (p);
+
+		c = g_utf8_get_char (p);
+
+		if (!g_unichar_isdigit (c))
+		{
+			g_signal_stop_emission_by_name (editable, "insert-text");
+			break;
+		}
+
+		p = next;
+	}
+}
+
+static gboolean 
+page_entry_focus_out (GtkWidget         *widget,
+		      GdkEventFocus     *event,
+		      GeditPrintPreview *preview)
+{
+	const gchar *text;
+	gint page;
+
+	text = gtk_entry_get_text (GTK_ENTRY (widget));
+	page = atoi (text) - 1;
+
+	/* Reset the page number only if really needed */
+	if (page != preview->priv->cur_page)
+	{
+		gchar *str;
+
+		str = g_strdup_printf ("%d", preview->priv->cur_page + 1);
+		gtk_entry_set_text (GTK_ENTRY (widget), str);
+		g_free (str);
+	}
+
+	return FALSE;
+}
+
+static void
+update_layout_size (GeditPrintPreview *preview)
+{
+	GeditPrintPreviewPrivate *priv;
+
+	priv = preview->priv;
+
+	g_print ("layout set size to %d, %d\n",
+		 priv->tile_w * priv->cols,
+		 priv->tile_h * priv->rows);
+
+	/* force size of the drawing area to make the scrolled window work */
+	gtk_layout_set_size (GTK_LAYOUT (priv->layout),
+			     priv->tile_w * priv->cols,
+			     priv->tile_h * priv->rows);
+}
+
+static void
+set_rows_and_cols (GeditPrintPreview *preview,
+		   gint               rows,
+		   gint               cols)
+{
+	/* TODO: set the zoom appropriately */
+
+	preview->priv->rows = rows;
+	preview->priv->cols = cols;
+	update_layout_size (preview);
+
+	gtk_widget_queue_draw (GTK_WIDGET (preview));
+}
+
+static void
+on_1x1_clicked (GtkMenuItem *i, GeditPrintPreview *preview)
+{
+	set_rows_and_cols (preview, 1, 1);
+}
+
+static void
+on_1x2_clicked (GtkMenuItem *i, GeditPrintPreview *preview)
+{
+	set_rows_and_cols (preview, 1, 2);
+}
+
+static void
+on_2x1_clicked (GtkMenuItem *i, GeditPrintPreview *preview)
+{
+	set_rows_and_cols (preview, 2, 1);
+}
+
+static void
+on_2x2_clicked (GtkMenuItem *i, GeditPrintPreview *preview)
+{
+	set_rows_and_cols (preview, 2, 2);
+}
+
+static void
+multi_button_clicked (GtkWidget         *button,
+		      GeditPrintPreview *preview)
+{
+	GtkWidget *m, *i;
+
+	m = gtk_menu_new ();
+	gtk_widget_show (m);
+	g_signal_connect (m,
+			 "selection_done",
+			  G_CALLBACK (gtk_widget_destroy),
+			  m);
+
+        i = gtk_menu_item_new_with_label ("1x1");
+        gtk_widget_show (i);
+	gtk_menu_attach (GTK_MENU (m), i, 0, 1, 0, 1);
+        g_signal_connect (i, "activate", G_CALLBACK (on_1x1_clicked), preview);
+
+        i = gtk_menu_item_new_with_label ("2x1");
+        gtk_widget_show (i);
+	gtk_menu_attach (GTK_MENU (m), i, 0, 1, 1, 2);
+        g_signal_connect (i, "activate", G_CALLBACK (on_2x1_clicked), preview);
+
+        i = gtk_menu_item_new_with_label ("1x2");
+        gtk_widget_show (i);
+	gtk_menu_attach (GTK_MENU (m), i, 1, 2, 0, 1);
+        g_signal_connect (i, "activate", G_CALLBACK (on_1x2_clicked), preview);
+
+        i = gtk_menu_item_new_with_label ("2x2");
+        gtk_widget_show (i);
+	gtk_menu_attach (GTK_MENU (m), i, 1, 2, 1, 2);
+        g_signal_connect (i, "activate", G_CALLBACK (on_2x2_clicked), preview);
+       
+	gtk_menu_popup (GTK_MENU (m),
+			NULL, NULL, NULL, preview, 0,
+			GDK_CURRENT_TIME);
+}
+
+static void
+zoom_in_button_clicked (GtkWidget         *button,
+			GeditPrintPreview *preview)
+{
+	// FIXME: look at the old widget to see proper zoom stuff
+	set_zoom_factor (preview, preview->priv->scale * 2);
+
+	gtk_widget_queue_draw (preview->priv->layout);
+}
+
+static void
+zoom_out_button_clicked (GtkWidget         *button,
+			 GeditPrintPreview *preview)
+{
+	// FIXME: look at the old widget to see proper zoom stuff
+	set_zoom_factor (preview, preview->priv->scale / 2);
+
+	gtk_widget_queue_draw (preview->priv->layout);
+}
+
+static void
+close_button_clicked (GtkWidget         *button,
+		      GeditPrintPreview *preview)
+{
+	gtk_widget_destroy (GTK_WIDGET (preview));
+}
+
+static void
+create_bar (GeditPrintPreview *preview)
+{
+	GeditPrintPreviewPrivate *priv;
+	GtkWidget *toolbar;
+	GtkToolItem *i;
+	AtkObject *atko;
+	GtkWidget *status;
+
+	priv = preview->priv;
+
+	toolbar = gtk_toolbar_new ();
+	gtk_toolbar_set_style (GTK_TOOLBAR (toolbar),
+			       GTK_TOOLBAR_BOTH_HORIZ);
+	gtk_widget_show (toolbar);
+	gtk_box_pack_start (GTK_BOX (preview),
+			    toolbar,
+			    FALSE, FALSE, 0);
+
+	priv->prev = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
+	gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->prev),
+				   "P_revious Page");
+	gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->prev), TRUE);
+	gtk_tool_item_set_tooltip (priv->prev,
+				   GTK_TOOLBAR (toolbar)->tooltips,
+				   _("Show the previous page"), "");
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->prev, -1);
+	g_signal_connect (priv->prev,
+			  "clicked",
+			  G_CALLBACK (prev_button_clicked),
+			  preview);
+	gtk_widget_show (GTK_WIDGET (priv->prev));
+
+	priv->next = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
+	gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->next),
+				   "_Next Page");
+	gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->next), TRUE);
+	gtk_tool_item_set_tooltip (priv->next,
+				   GTK_TOOLBAR (toolbar)->tooltips,
+				   _("Show the next page"), "");
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->next, -1);
+	g_signal_connect (priv->next,
+			  "clicked",
+			  G_CALLBACK (next_button_clicked),
+			  preview);
+	gtk_widget_show (GTK_WIDGET (priv->next));
+
+	i = gtk_separator_tool_item_new ();
+	gtk_widget_show (GTK_WIDGET (i));
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+
+	status = gtk_hbox_new (FALSE, 4);
+	priv->page_entry = gtk_entry_new ();
+	gtk_entry_set_width_chars (GTK_ENTRY (priv->page_entry), 3);
+	gtk_entry_set_max_length (GTK_ENTRY (priv->page_entry), 6);
+	gtk_widget_set_tooltip_text (priv->page_entry,
+	                             _("Current page (Alt+P)"));
+
+	g_signal_connect (priv->page_entry,
+			  "activate", 
+			  G_CALLBACK (page_entry_activated),
+			  preview);
+	g_signal_connect (priv->page_entry,
+			  "insert-text", 
+			  G_CALLBACK (page_entry_insert_text),
+			  NULL);
+	g_signal_connect (priv->page_entry,
+			  "focus-out-event", 
+			  G_CALLBACK (page_entry_focus_out),
+			  preview);
+
+	gtk_box_pack_start (GTK_BOX (status),
+			    priv->page_entry,
+			    FALSE, FALSE, 0);
+	/* gtk_label_set_mnemonic_widget ((GtkLabel *) l, mp->priv->page_entry); */
+
+	/* We are displaying 'XXX of XXX'. */
+	gtk_box_pack_start (GTK_BOX (status),
+			    gtk_label_new (_("of")),
+			    FALSE, FALSE, 0);
+
+	priv->last = gtk_label_new ("");
+	gtk_box_pack_start (GTK_BOX (status),
+			    priv->last,
+			    FALSE, FALSE, 0);
+	atko = gtk_widget_get_accessible (priv->last);
+	atk_object_set_name (atko, _("Page total"));
+	atk_object_set_description (atko, _("The total number of pages in the document"));
+
+	gtk_widget_show_all (status);
+
+	i = gtk_tool_item_new ();
+	gtk_container_add (GTK_CONTAINER (i), status);
+	gtk_widget_show (GTK_WIDGET (i));
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+
+	i = gtk_separator_tool_item_new ();
+	gtk_widget_show (GTK_WIDGET (i));
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+	
+	priv->multi = gtk_tool_button_new_from_stock (GTK_STOCK_DND_MULTIPLE);
+	gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->multi),
+				   "_Show Multiple Pages");
+	gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (priv->multi), TRUE);
+	gtk_tool_item_set_tooltip (priv->multi,
+				   GTK_TOOLBAR (toolbar)->tooltips,
+				   _("Show multiple pages"), "");
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->multi, -1);
+	g_signal_connect (priv->multi,
+			  "clicked",
+			  G_CALLBACK (multi_button_clicked),
+			  preview);
+	gtk_widget_show (GTK_WIDGET (priv->multi));
+
+	i = gtk_separator_tool_item_new ();
+	gtk_widget_show (GTK_WIDGET (i));
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+
+//	mp->priv->bz1 = GTK_WIDGET (i);
+//	gtk_tool_item_set_tooltip (i, GTK_TOOLBAR (toolbar)->tooltips,
+//				   _("Zoom 1:1"), "");
+//	g_signal_connect_swapped (i, "clicked",
+//		G_CALLBACK (preview_zoom_100_cmd), mp);
+//	gtk_widget_show (GTK_WIDGET (i));
+//	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+//	i = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_FIT);
+//	mp->priv->bzf = GTK_WIDGET (i);
+//	gtk_tool_item_set_tooltip (i, GTK_TOOLBAR (toolbar)->tooltips,
+//				   _("Zoom to fit the whole page"), "");
+//	g_signal_connect_swapped (i, "clicked",
+//		G_CALLBACK (preview_zoom_fit_cmd), mp);
+//	gtk_widget_show (GTK_WIDGET (i));
+//	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+//	
+
+	priv->zoom_in = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_IN);
+	gtk_tool_item_set_tooltip (priv->zoom_in,
+				   GTK_TOOLBAR (toolbar)->tooltips,
+				   _("Zoom the page in"), "");
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_in, -1);
+	g_signal_connect (priv->zoom_in,
+			  "clicked",
+			  G_CALLBACK (zoom_in_button_clicked),
+			  preview);
+	gtk_widget_show (GTK_WIDGET (priv->zoom_in));
+
+	priv->zoom_out = gtk_tool_button_new_from_stock (GTK_STOCK_ZOOM_OUT);
+	gtk_tool_item_set_tooltip (priv->zoom_out,
+				   GTK_TOOLBAR (toolbar)->tooltips,
+				   _("Zoom the page out"), "");
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->zoom_out, -1);
+	g_signal_connect (priv->zoom_out,
+			  "clicked",
+			  G_CALLBACK (zoom_out_button_clicked),
+			  preview);
+	gtk_widget_show (GTK_WIDGET (priv->zoom_out));
+
+	i = gtk_separator_tool_item_new ();
+	gtk_widget_show (GTK_WIDGET (i));
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+
+	i = gtk_tool_button_new (NULL, _("_Close Preview"));
+	gtk_tool_button_set_use_underline (GTK_TOOL_BUTTON (i), TRUE);
+	gtk_tool_item_set_is_important (i, TRUE);
+	gtk_tool_item_set_tooltip (i, GTK_TOOLBAR (toolbar)->tooltips, 
+				   _("Close print preview"), "");
+	g_signal_connect (i, "clicked",
+			  G_CALLBACK (close_button_clicked), preview);
+	gtk_widget_show (GTK_WIDGET (i));
+	gtk_toolbar_insert (GTK_TOOLBAR (toolbar), i, -1);
+}
+
+static void
+create_preview_layout (GeditPrintPreview *preview)
+{
+	GeditPrintPreviewPrivate *priv;
+	AtkObject *atko;
+
+	priv = preview->priv;
+
+	priv->layout = gtk_layout_new (NULL, NULL);
+//	gtk_widget_set_double_buffered (priv->layout, FALSE);
+
+	atko = gtk_widget_get_accessible (GTK_WIDGET (priv->layout));
+	atk_object_set_name (atko, _("Page Preview"));
+	atk_object_set_description (atko, _("The preview of a page in the document to be printed"));
+
+	gtk_widget_set_events (priv->layout,
+	                       gtk_widget_get_events (priv->layout) |
+	                       GDK_BUTTON_PRESS_MASK |
+	                       GDK_KEY_PRESS_MASK);
+
+	GTK_WIDGET_SET_FLAGS (priv->layout, GTK_CAN_FOCUS);
+
+	priv->scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_window),
+					GTK_POLICY_AUTOMATIC,
+					GTK_POLICY_AUTOMATIC);
+
+	gtk_container_add (GTK_CONTAINER (priv->scrolled_window), priv->layout);
+	gtk_box_pack_end (GTK_BOX (preview),
+			  priv->scrolled_window,
+			  TRUE, TRUE, 0);
+
+	gtk_widget_show_all (GTK_WIDGET (priv->scrolled_window));
+	gtk_widget_grab_focus (GTK_WIDGET (priv->layout));
+}
+
+static void
+gedit_print_preview_init (GeditPrintPreview *preview)
+{
+	GeditPrintPreviewPrivate *priv;
+	
+	priv = G_TYPE_INSTANCE_GET_PRIVATE (preview, 
+					    GEDIT_TYPE_PRINT_PREVIEW,
+					    GeditPrintPreviewPrivate);
+
+	preview->priv = priv;
+
+	priv->operation = NULL;
+	priv->context = NULL;
+	priv->gtk_preview = NULL;
+
+	create_bar (preview);
+	create_preview_layout (preview);
+
+	// FIXME
+	priv->cur_page = 0;
+	priv->paper_w = 0;
+	priv->paper_h = 0;
+	priv->dpi = PRINTER_DPI;
+	priv->scale = 1.0;
+	priv->rows = 1;
+	priv->cols = 1;
+}
+
+/* get the paper size in points: these must be used only
+ * after the widget has been mapped and the dpi is known */
+
+static double
+get_paper_width (GeditPrintPreview *preview)
+{
+	return preview->priv->paper_w * preview->priv->dpi;
+}
+
+static double
+get_paper_height (GeditPrintPreview *preview)
+{
+	return preview->priv->paper_h * preview->priv->dpi;
+}
+
+#define PAGE_PAD 12
+#define PAGE_SHADOW_OFFSET 5 
+
+static double
+get_tile_width (gint page_w)
+{
+	return page_w + 2 * PAGE_PAD;
+}
+
+static double
+get_tile_height (gint page_h)
+{
+	return page_h + 2 * PAGE_PAD;
+}
+
+static double
+get_page_width (gint tile_w)
+{
+	return MAX (1, tile_w - 2 * PAGE_PAD);
+}
+
+static double
+get_page_height (gint tile_h)
+{
+	return MAX (1, tile_h - 2 * PAGE_PAD);
+}
+
+static void
+set_zoom_factor (GeditPrintPreview *preview,
+	         double             zoom)
+{
+	GeditPrintPreviewPrivate *priv;	
+
+	priv = preview->priv;
+
+	priv->scale = zoom;
+
+	/* round up to avoid artifacts when clearing the background */
+	priv->tile_w = get_tile_width (floor (zoom * get_paper_width (preview) + 0.5));
+	priv->tile_h = get_tile_height (floor (zoom * get_paper_height (preview) + 0.5));
+
+	update_layout_size (preview);
+}
+
+/* used to fit-to-width */
+static void
+set_tile_width (GeditPrintPreview *preview,
+	        gint               width)
+{
+	GeditPrintPreviewPrivate *priv;	
+
+	priv = preview->priv;
+
+	priv->tile_w = width;
+	priv->tile_h = floor (0.5 + width * (priv->paper_h / priv->paper_w));
+
+	priv->scale = get_page_width (width) / priv->paper_w;
+}
+
+/* used to fit-to-height */
+static void
+set_tile_height (GeditPrintPreview *preview,
+	         gint               height)
+{
+	GeditPrintPreviewPrivate *priv;	
+
+	priv = preview->priv;
+
+	priv->tile_w = floor (0.5 + height * (priv->paper_w / priv->paper_h));
+	priv->tile_h = height;
+
+	priv->scale = get_page_height (height) / priv->paper_h;
+}
+
+static void
+draw_page (cairo_t           *cr,
+	   double             x,
+	   double             y,
+	   gint               page_number,
+	   GeditPrintPreview *preview)
+{
+	GeditPrintPreviewPrivate *priv;	
+
+	priv = preview->priv;
+
+	cairo_save (cr);
+
+	/* move to the page top left corner */
+	cairo_translate (cr, x + PAGE_PAD, y + PAGE_PAD);
+
+	/* scale to the desired size */
+	cairo_scale (cr, priv->scale, priv->scale);
+
+	/* drop shadow */
+	cairo_set_source_rgb (cr, 0, 0, 0);
+	cairo_rectangle (cr,
+			 PAGE_SHADOW_OFFSET, PAGE_SHADOW_OFFSET,
+			 get_paper_width (preview), get_paper_height (preview));
+	cairo_fill (cr);
+
+	/* page frame */
+	cairo_set_source_rgb (cr, 1, 1, 1);
+	cairo_rectangle (cr,
+			 0, 0,
+			 get_paper_width (preview), get_paper_height (preview));
+	cairo_fill_preserve (cr);
+	cairo_set_source_rgb (cr, 0, 0, 0);
+	cairo_set_line_width (cr, 1);
+	cairo_stroke (cr);
+
+	/* render the page content */
+	gtk_print_context_set_cairo_context (preview->priv->context,
+					     cr,
+					     preview->priv->dpi,
+					     preview->priv->dpi);
+
+	gtk_print_operation_preview_render_page (preview->priv->gtk_preview,
+						 page_number);
+
+	cairo_restore (cr);
+}
+
+static gboolean
+preview_expose (GtkWidget         *widget,
+		GdkEventExpose    *event,
+		GeditPrintPreview *preview)
+{
+	GeditPrintPreviewPrivate *priv;	
+	cairo_t *cr;
+	gint i, j;
+
+	priv = preview->priv;
+
+	if (event->window != GTK_LAYOUT (priv->layout)->bin_window)
+		return FALSE;
+
+	cr = gdk_cairo_create (GTK_LAYOUT (priv->layout)->bin_window);
+
+	gdk_cairo_rectangle (cr, &event->area);
+	cairo_clip (cr);
+
+	for (i = 0; i < priv->cols; ++i)
+	{
+		for (j = 0; j < priv->rows; ++j)
+		{
+			gint pg;
+
+			pg = priv->cur_page + j + i * priv->rows;
+
+			if (!gtk_print_operation_preview_is_selected (priv->gtk_preview,
+								      pg))
+			{
+				continue;
+			}
+
+			draw_page (cr,
+				   j * priv->tile_w,
+				   i * priv->tile_h,
+				   pg,
+				   preview);
+		}
+	}
+	cairo_destroy (cr);
+
+	return TRUE;
+}
+
+static double
+get_screen_dpi (GeditPrintPreview *preview)
+{
+	GdkScreen *screen;
+
+	screen = gtk_widget_get_screen (GTK_WIDGET (preview));	
+
+	return gdk_screen_get_resolution (screen);
+}
+
+static void
+preview_ready (GtkPrintOperationPreview *gtk_preview,
+	       GtkPrintContext          *context,
+	       GeditPrintPreview        *preview)
+{
+	gint n_pages;
+
+	g_object_get (preview->priv->operation, "n-pages", &n_pages, NULL);
+	preview->priv->n_pages = n_pages;
+	goto_page (preview, 0);
+
+	/* figure out the dpi */
+	preview->priv->dpi = get_screen_dpi (preview);
+
+	set_zoom_factor (preview, 1.0);
+
+	/* let the default gtklayout handler clear the background */
+	g_signal_connect_after (preview->priv->layout,
+				"expose-event",
+				G_CALLBACK (preview_expose),
+				preview);
+
+	gtk_widget_queue_draw (preview->priv->layout);
+}
+
+static void
+update_paper_size (GeditPrintPreview *preview,
+		   GtkPageSetup      *page_setup)
+{
+	GtkPaperSize *paper_size;
+
+	paper_size = gtk_page_setup_get_paper_size (page_setup);
+
+	preview->priv->paper_w = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
+	preview->priv->paper_h = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
+}
+
+static void
+preview_got_page_size (GtkPrintOperationPreview *gtk_preview, 
+		       GtkPrintContext          *context,
+		       GtkPageSetup             *page_setup,
+		       GeditPrintPreview        *preview)
+{
+	update_paper_size (preview, page_setup);
+}
+
+/* HACK: we need a dummy surface to paginate... can we use something simpler? */
+
+static cairo_status_t
+dummy_write_func (G_GNUC_UNUSED gpointer      closure,
+                  G_GNUC_UNUSED const guchar *data,
+                  G_GNUC_UNUSED guint         length)
+{
+    return CAIRO_STATUS_SUCCESS;
+}
+
+#define PRINTER_DPI (72.)
+
+static cairo_surface_t *
+create_preview_surface_platform (GtkPaperSize *paper_size,
+                                 double       *dpi_x,
+                                 double       *dpi_y)
+{
+    double width, height;
+    cairo_surface_t *sf;
+
+    width = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
+    height = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
+
+    *dpi_x = *dpi_y = PRINTER_DPI;
+
+    sf = cairo_pdf_surface_create_for_stream (dummy_write_func, NULL,
+                                              width, height);
+    return sf;
+}
+
+static cairo_surface_t *
+create_preview_surface (GeditPrintPreview *preview,
+                        double          *dpi_x,
+                        double          *dpi_y)
+{
+    GtkPageSetup *page_setup;
+    GtkPaperSize *paper_size;
+
+    page_setup = gtk_print_context_get_page_setup (preview->priv->context);
+    /* gtk_page_setup_get_paper_size swaps width and height for landscape */
+    paper_size = gtk_page_setup_get_paper_size (page_setup);
+
+    return create_preview_surface_platform (paper_size, dpi_x, dpi_y);
+}
+
+GtkWidget *
+gedit_print_preview_new (GtkPrintOperation        *op,
+			 GtkPrintOperationPreview *gtk_preview,
+			 GtkPrintContext          *context)
+{
+	GeditPrintPreview *preview;
+	GtkPageSetup *page_setup;
+	cairo_surface_t *surface;
+	cairo_t *cr;
+	double dpi_x, dpi_y;
+
+	g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), NULL);
+	g_return_val_if_fail (GTK_IS_PRINT_OPERATION_PREVIEW (gtk_preview), NULL);
+
+	preview = g_object_new (GEDIT_TYPE_PRINT_PREVIEW, NULL);
+
+	preview->priv->operation = g_object_ref (op);
+	preview->priv->gtk_preview = g_object_ref (gtk_preview);
+	preview->priv->context = g_object_ref (context);
+
+	/* FIXME: is this legal?? */
+	gtk_print_operation_set_unit (op, GTK_UNIT_POINTS);
+
+	g_signal_connect (gtk_preview, "ready",
+			  G_CALLBACK (preview_ready), preview);
+	g_signal_connect (gtk_preview, "got-page-size",
+			  G_CALLBACK (preview_got_page_size), preview);
+
+	page_setup = gtk_print_context_get_page_setup (preview->priv->context);
+	update_paper_size (preview, page_setup);
+
+	/* FIXME: we need a cr to paginate... but we can't get the drawing
+	 * area surface because it's not there yet... for now I create 
+	 * a dummy pdf surface */
+
+	surface = create_preview_surface (preview, &dpi_x, &dpi_y);
+	cr = cairo_create (surface);
+	gtk_print_context_set_cairo_context (context, cr, dpi_x, dpi_y);
+	cairo_destroy (cr);
+	cairo_surface_destroy (surface);
+
+	return GTK_WIDGET (preview);
+}
+

Added: branches/printing/gedit/gedit-print-preview.h
==============================================================================
--- (empty file)
+++ branches/printing/gedit/gedit-print-preview.h	Sun Jan  6 18:19:16 2008
@@ -0,0 +1,72 @@
+/*
+ * gedit-print-preview.h
+ *
+ * Copyright (C) 2008 Paolo Borelli
+ *
+ * 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.
+ */
+
+/*
+ * Modified by the gedit Team, 1998-2006. See the AUTHORS file for a
+ * list of people on the gedit Team.
+ * See the ChangeLog files for a list of changes.
+ *
+ * $Id: gedit-commands-search.c 5931 2007-09-25 20:05:40Z pborelli $
+ */
+
+
+#ifndef __GEDIT_PRINT_PREVIEW_H__
+#define __GEDIT_PRINT_PREVIEW_H__
+
+#include <gtk/gtkvbox.h>
+#include <gtk/gtkprintoperation.h>
+
+G_BEGIN_DECLS
+
+#define GEDIT_TYPE_PRINT_PREVIEW            (gedit_print_preview_get_type ())
+#define GEDIT_PRINT_PREVIEW(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), GEDIT_TYPE_PRINT_PREVIEW, GeditPrintPreview))
+#define GEDIT_PRINT_PREVIEW_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GEDIT_TYPE_PRINT_PREVIEW, GeditPrintPreviewClass))
+#define GEDIT_IS_PRINT_PREVIEW(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), GEDIT_TYPE_PRINT_PREVIEW))
+#define GEDIT_IS_PRINT_PREVIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GEDIT_TYPE_PRINT_PREVIEW))
+#define GEDIT_PRINT_PREVIEW_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GEDIT_TYPE_PRINT_PREVIEW, GeditPrintPreviewClass))
+
+typedef struct _GeditPrintPreview        GeditPrintPreview;
+typedef struct _GeditPrintPreviewPrivate GeditPrintPreviewPrivate;
+typedef struct _GeditPrintPreviewClass   GeditPrintPreviewClass;
+
+struct _GeditPrintPreview
+{
+	GtkVBox parent;
+	GeditPrintPreviewPrivate *priv;
+};
+
+struct _GeditPrintPreviewClass
+{
+	GtkVBoxClass parent_class;
+
+	void (* close)		(GeditPrintPreview          *preview);
+};
+
+
+GType		 gedit_print_preview_get_type	(void) G_GNUC_CONST;
+
+GtkWidget	*gedit_print_preview_new	(GtkPrintOperation		*op,
+						 GtkPrintOperationPreview	*gtk_preview,
+						 GtkPrintContext		*context);
+
+G_END_DECLS
+
+#endif /* __GEDIT_PRINT_PREVIEW_H__ */

Modified: branches/printing/gedit/gedit-tab.c
==============================================================================
--- branches/printing/gedit/gedit-tab.c	(original)
+++ branches/printing/gedit/gedit-tab.c	Sun Jan  6 18:19:16 2008
@@ -42,8 +42,8 @@
 #include "gedit-utils.h"
 #include "gedit-message-area.h"
 #include "gedit-io-error-message-area.h"
-#include "gedit-print.h"
-#include "gedit-print-job-preview.h"
+//#include "gedit-print.h"
+//#include "gedit-print-job-preview.h"
 #include "gedit-progress-message-area.h"
 #include "gedit-debug.h"
 #include "gedit-prefs-manager-app.h"
@@ -64,7 +64,7 @@
 	GtkWidget	       *message_area;
 	GtkWidget	       *print_preview;
 
-	GeditPrintJob          *print_job;
+//	GeditPrintJob          *print_job;
 
 	/* tmp data for saving */
 	gchar		       *tmp_save_uri;
@@ -229,7 +229,8 @@
 gedit_tab_finalize (GObject *object)
 {
 	GeditTab *tab = GEDIT_TAB (object);
-	
+
+#if 0
 	if (tab->priv->print_job != NULL)
 	{
 		gedit_debug_message (DEBUG_TAB, "Cancelling printing");
@@ -237,6 +238,7 @@
 		gtk_source_print_job_cancel (GTK_SOURCE_PRINT_JOB (tab->priv->print_job));
 		g_object_unref (tab->priv->print_job);
 	}
+#endif
 	
 	if (tab->priv->timer != NULL)
 		g_timer_destroy (tab->priv->timer);
@@ -2197,6 +2199,8 @@
 
 #define MIN_PAGES 15
 
+#if 0
+
 static void
 print_page_cb (GtkSourcePrintJob *pjob, GeditTab *tab)
 {
@@ -2333,6 +2337,7 @@
 	  
 	set_message_area (tab, area);
 }
+#endif
 
 void 
 _gedit_tab_print (GeditTab      *tab,
@@ -2340,6 +2345,7 @@
 		  GtkTextIter   *start, 
 		  GtkTextIter   *end)
 {
+#if 0
 	GeditPrintJob *pjob;
 	GeditDocument *doc;
 
@@ -2380,6 +2386,7 @@
 		g_warning ("Async print preview failed");
 		g_object_unref (pjob);
 	}
+#endif
 }
 
 void
@@ -2388,6 +2395,7 @@
 			  GtkTextIter   *start, 
 			  GtkTextIter   *end)
 {
+#if 0
 	GeditPrintJob *pjob;
 	GeditDocument *doc;
 
@@ -2426,6 +2434,7 @@
 		g_warning ("Async print preview failed");
 		g_object_unref (pjob);
 	}
+#endif
 }
 
 void 



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