better late than never

We finally released a new developement version of gedit that reimplements printing using GTK+ print support. It also includes a custom print preview widget so that we can keep our current UI (print preview embedded in a tab). This means that we do not depend on libgnomeprint and libgnomeprintui anymore… it was about time!

Print Preview screenshot Print Preferences screenshot

Please test it, test it, test it and report any regression or problem!

GtkSourceView 2.1

Today we released GtkSourceView 2.1, the developement release for 2.2 that will be part of the next GNOME. In this cycle we didn’t have much time to work on it, however over the Christmas break we reimplemented two important features that went missing in the big 2.0 release:

  • Marks in the left margin (useful for bookmarks, breakpoints, showing errors etc)
  • Printing

This means that we have reached feature parity with the old GtkSourceView 1.

The API however is different from what was there in gtksourceview 1: in particular printing now integrates with GtkPrint instead of using the old and deprecated gnome-print libraries. GtkPrint is a pretty strange beast (due to the fact that a cross platform printing api is quite challenging), but in the end I think we found a pretty elegant API.

We expose a GtkSourcePrintCompositor class that knows how to draw the text view (including syntax highlighting, line numbers, header and footer): when running a GtkPrintOperation to print, you just need to instanciate a compositor for the current text buffer and delegate to it all the pagination and drawing. Pagination, which for long documents can take quite a bit of time, is async which allows to present a progress bar without blocking the UI.

Here is a simple example showing how to use the new printing API:

static gboolean
paginate (GtkPrintOperation        *operation,
	  GtkPrintContext          *context,
	  GtkSourcePrintCompositor *compositor)
{
	if (gtk_source_print_compositor_paginate (compositor, context))
	{
		gint n_pages;

		n_pages = gtk_source_print_compositor_get_n_pages (compositor);
		gtk_print_operation_set_n_pages (operation, n_pages);

		return TRUE;
	}

	return FALSE;
}

draw_page (GtkPrintOperation        *operation,
	   GtkPrintContext          *context,
	   gint                      page_nr,
	   GtkSourcePrintCompositor *compositor)
{
	gtk_source_print_compositor_draw_page (compositor, context, page_nr);
}

static void
end_print (GtkPrintOperation        *operation,
	   GtkPrintContext          *context,
	   GtkSourcePrintCompositor *compositor)
{
	g_object_unref (compositor);
}

static void
print_source_view (GtkSourceView *view)
{
	GtkSourcePrintCompositor *compositor;
	GtkPrintOperation *operation;	

	compositor = gtk_source_print_compositor_new_from_view (view);
	operation = gtk_print_operation_new ();

  	g_signal_connect (operation, "paginate",  G_CALLBACK (paginate), compositor);
	g_signal_connect (operation, "draw-page", G_CALLBACK (draw_page), compositor);
	g_signal_connect (operation, "end-print", G_CALLBACK (end_print), compositor);

	gtk_print_operation_run (operation,
				 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
				 NULL, NULL);

	g_object_unref (operation);
}