Page selection in GnomePrintDialog

Lutz Müller <[email protected]> Sun, 21 Aug 2005 20:30:00 +0200
Newsgroups gmane.comp.gnome.print
Message-ID <1124649000.14891.16.camel@localhost>
--=-y0L+PALab+5EaOKjk+Du
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

Hello!

I've written a small widget called GnomePrintPageSelection. Screenshot,
source code and patch (to hook it up) attached.

This widget offers advanced page selection to all applications using
libgnomeprintui and not calling one of the
gnome_print_dialog_construct_range_* functions.

The old-style page selection will appear if the application calls one of
the gnome_print_dialog_construct_range_* functions.

Any comments?

Regards
--=20
Lutz M=FCller <[email protected]>

--=-y0L+PALab+5EaOKjk+Du
Content-Disposition: attachment; filename=libgnomeprintui.diff
Content-Type: text/x-patch; name=libgnomeprintui.diff; charset=ANSI_X3.4-1968
Content-Transfer-Encoding: 7bit

Index: libgnomeprintui/Makefile.am
===================================================================
RCS file: /cvs/gnome/libgnomeprintui/libgnomeprintui/Makefile.am,v
retrieving revision 1.90
diff -u -3 -p -r1.90 Makefile.am
--- libgnomeprintui/Makefile.am	21 Aug 2005 17:48:19 -0000	1.90
+++ libgnomeprintui/Makefile.am	21 Aug 2005 18:22:23 -0000
@@ -53,7 +53,8 @@ libgnomeprintui_2_2_la_SOURCES = \
 	gnome-print-config-dialog.c  gnome-print-config-dialog-private.h \
         gnome-print-widget.c         gnome-print-widget.h           \
 	gnome-font-dialog.c		\
-	gnome-print-paper-preview.c  gnome-print-paper-preview.h	\
+	gnome-print-page-selector.c  gnome-print-page-selector.h \
+	gnome-print-paper-preview.c  gnome-print-paper-preview.h \
 	gnome-print-unit-selector.c	\
 	gnome-print-paper-selector.c	\
 	gnome-print-ui-private.c     gnome-print-ui-private.h		\
Index: libgnomeprintui/gnome-print-dialog.c
===================================================================
RCS file: /cvs/gnome/libgnomeprintui/libgnomeprintui/gnome-print-dialog.c,v
retrieving revision 1.66
diff -u -3 -p -r1.66 gnome-print-dialog.c
--- libgnomeprintui/gnome-print-dialog.c	21 Aug 2005 17:48:19 -0000	1.66
+++ libgnomeprintui/gnome-print-dialog.c	21 Aug 2005 18:22:23 -0000
@@ -38,16 +38,18 @@
 
 #include <libgnomeprint/gnome-print-config.h>
 
-#include "gnome-print-i18n.h"
-#include "gnome-printer-selector.h"
-#include "gnome-print-paper-selector.h"
-#include "gnome-print-copies.h"
-#include "gnome-print-dialog.h"
+#include <libgnomeprintui/gnome-print-i18n.h>
+#include <libgnomeprintui/gnome-printer-selector.h>
+#include <libgnomeprintui/gnome-print-page-selector.h>
+#include <libgnomeprintui/gnome-print-paper-selector.h>
+#include <libgnomeprintui/gnome-print-copies.h>
+#include <libgnomeprintui/gnome-print-dialog.h>
 
 #define PAD 6
 
 enum {
 	PROP_0,
+	PROP_CURRENT,
 	PROP_PRINT_CONFIG,
 	PROP_PRINTER_SELECTOR,
 	PROP_NOTEBOOK
@@ -69,6 +71,7 @@ struct _GnomePrintDialog {
 
 	GtkWidget *job;
 	GtkWidget *printer;
+	GtkWidget *page_selector;
 };
 
 struct _GnomePrintDialogClass {
@@ -123,6 +126,9 @@ gnome_print_dialog_set_property (GObject
 		if (gpd->config)
 			g_object_ref (G_OBJECT (gpd->config));
 		break;
+	case PROP_CURRENT:
+		g_object_set_property (G_OBJECT (gpd->page_selector), "current", value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 	}
@@ -141,6 +147,9 @@ gnome_print_dialog_get_property (GObject
 	case PROP_NOTEBOOK:
 		g_value_set_object (value, gpd->notebook);
 		break;
+	case PROP_CURRENT:
+		g_object_get_property (G_OBJECT (gpd->page_selector), "current", value);
+		break;
 	default:
 		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
 	}
@@ -232,6 +241,7 @@ gpd_create_job_page (GnomePrintDialog *g
 
 	gtk_box_pack_start (GTK_BOX (hb), vb, FALSE, FALSE, 0);
 
+	/* Print range, old API */
 	f = gtk_frame_new ("");
 	gtk_frame_set_shadow_type (GTK_FRAME (f), GTK_SHADOW_NONE);
 	l = gtk_label_new ("");
@@ -245,6 +255,14 @@ gpd_create_job_page (GnomePrintDialog *g
 	gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0);
 	g_object_set_data (G_OBJECT (hb), "range", f);
 
+	/* Print range */
+	f = g_object_new (GNOME_TYPE_PRINT_PAGE_SELECTOR, NULL);
+	gtk_widget_show (f);
+	gtk_box_pack_start (GTK_BOX (vb), f, FALSE, FALSE, 0);
+	if (gpd)
+		gpd->page_selector = f;
+
+	/* Copies */
 	c = gnome_print_copies_selector_new ();
 	if (gpd) {
 		g_signal_connect (G_OBJECT (c), "copies_set", 
@@ -497,6 +515,8 @@ gnome_print_dialog_construct_range_custo
 	g_return_if_fail (custom != NULL);
 	g_return_if_fail (GTK_IS_WIDGET (custom));
 
+	gtk_widget_hide (gpd->page_selector);
+
 	f = g_object_get_data (G_OBJECT (gpd->job), "range");
 	g_return_if_fail (f != NULL);
 	r = g_object_get_data (G_OBJECT (f), "range");
@@ -540,6 +560,8 @@ gnome_print_dialog_construct_range_any (
 	g_return_if_fail (!(!range_widget && (flags & GNOME_PRINT_RANGE_RANGE)));
 	g_return_if_fail (!((flags & GNOME_PRINT_RANGE_SELECTION) && (flags & GNOME_PRINT_RANGE_SELECTION_UNSENSITIVE)));
 
+	gtk_widget_hide (gpd->page_selector);
+
 	f = g_object_get_data (G_OBJECT (gpd->job), "range");
 	g_return_if_fail (f != NULL);
 	r = g_object_get_data (G_OBJECT (f), "range");
@@ -586,9 +608,9 @@ void
 gnome_print_dialog_construct_range_page (GnomePrintDialog *gpd, gint flags, gint start, gint end,
 					 const guchar *currentlabel, const guchar *rangelabel)
 {
-	GtkWidget *hbox;
+	GtkWidget *hbox = NULL;
 
-	hbox = NULL;
+	gtk_widget_hide (gpd->page_selector);
 
 	if (flags & GNOME_PRINT_RANGE_RANGE) {
 		GtkWidget *l, *sb;

--=-y0L+PALab+5EaOKjk+Du
Content-Disposition: attachment; filename=gnome-print-page-selector.c
Content-Type: text/x-csrc; name=gnome-print-page-selector.c;
	charset=ANSI_X3.4-1968
Content-Transfer-Encoding: 7bit

#include <config.h>

#include <libgnomeprintui/gnome-print-dialog.h>
#include <libgnomeprintui/gnome-print-page-selector.h>
#include <libgnomeprintui/gnome-print-i18n.h>

#include <libgnomeprint/gnome-print-config.h>
#include <libgnomeprint/gnome-print-filter.h>

#include <gtk/gtkframe.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtktable.h>
#include <gtk/gtkradiobutton.h>
#include <gtk/gtkspinbutton.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkcheckbutton.h>

#include <gdk/gdkkeysyms.h>

#include <string.h>

struct _GnomePrintPageSelector {
	GtkFrame parent;

	GnomePrintConfig *config;
	guint current;

	GtkWidget *r_all, *r_from_to, *r_selection, *r_current;
	GtkWidget *c_even, *c_odd;
	GtkAdjustment *a_from, *a_to;
	GtkWidget *e_selection;

	gboolean loading;
};

struct _GnomePrintPageSelectorClass {
	GtkFrameClass parent_class;
};

static GtkFrameClass *parent_class = NULL;

enum {
	PROP_0,
	PROP_CONFIG,
	PROP_CURRENT
};

static void
gnome_print_page_selector_load_config (GnomePrintPageSelector *ps)
{
	gchar *description;
	GnomePrintFilter *f;
	guint first, last, skip;
	gboolean collect;

	g_return_if_fail (GNOME_IS_PRINT_PAGE_SELECTOR (ps));

	if (!ps->config || ps->loading)
		return;

	description = (gchar *) gnome_print_config_get (ps->config,
			 (const guchar *) "Settings.Output.Job.Filter");
	if (!description)
		return;

	f = gnome_print_filter_new_from_description (description, NULL);
	g_free (description);
	if (!f)
		return;

	if (strcmp ("GnomePrintFilterSelect", G_OBJECT_TYPE_NAME (G_OBJECT (f)))) {
		g_object_unref (G_OBJECT (f));
		return;
	}

	g_object_get (G_OBJECT (f), "first", &first, "last", &last, "skip", &skip,
			"collect", &collect, NULL);
	if (collect || (skip > 1)) {
		g_object_unref (G_OBJECT (f));
		return;
	}

	ps->loading = TRUE;
	if ((first == 0) && (last == G_MAXUINT)) {
			if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_all)))
				g_object_set (G_OBJECT (ps->r_all), "active", TRUE, NULL);
	} else if ((ps->current > 0) &&
			(first == ps->current - 1) &&
			(last == ps->current - 1)) {
		if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_current)))
			g_object_set (G_OBJECT (ps->r_current), "active", TRUE, NULL);
	} else {
		if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_from_to)))
			g_object_set (G_OBJECT (ps->r_from_to), "active", TRUE, NULL);
		if ((guint) ps->a_from->value != first)
			g_object_set (G_OBJECT (ps->a_from), "value", (gdouble) first, NULL);
		if ((guint) ps->a_to->value != last)
			g_object_set (G_OBJECT (ps->a_to), "value", (gdouble) last, NULL);
	}
	if (skip) {
		g_object_set (G_OBJECT (ps->c_even), "active", (gboolean) (first & 1), NULL);
		g_object_set (G_OBJECT (ps->c_odd), "active", (gboolean) !(first & 1), NULL);
	}
	ps->loading = FALSE;
}

typedef enum {
	STATE_BEGIN,
	STATE_NUMBER_FROM,
	STATE_NUMBER_FROM_TO,
	STATE_NUMBER_BEGIN_TO,
	STATE_BEGIN_TO,
	STATE_FROM_TO
} ParseState;

static GArray *
gnome_print_page_selector_get_array (GnomePrintPageSelector *ps)
{
	const gchar *s;
	guint i, n_from = 0, n_to = 0;
	ParseState state = STATE_BEGIN;
	gboolean err = FALSE;
	GArray *a;

	g_return_val_if_fail (GNOME_IS_PRINT_PAGE_SELECTOR (ps), NULL);

	a = g_array_new (FALSE, TRUE, sizeof (gboolean));
	s = gtk_editable_get_chars (GTK_EDITABLE (ps->e_selection), 0, -1);
	for (i = 0; !err && (i < strlen (s)); i++) {
		if ((s[i] == '0') || (s[i] == '1') || (s[i] == '2') ||
		    (s[i] == '3') || (s[i] == '4') || (s[i] == '5') ||
		    (s[i] == '6') || (s[i] == '7') || (s[i] == '8') ||
		    (s[i] == '9')) {
			switch (state) {
			case STATE_BEGIN:
				state = STATE_NUMBER_FROM;
				n_from = atoi (&s[i]);
				if (!n_from) err = TRUE;
				break;
			case STATE_NUMBER_FROM:
				n_from = n_from * 10 + atoi (&s[i]);
				if (n_from > G_MAXUINT16) err = TRUE;
				break;
			case STATE_NUMBER_BEGIN_TO:
			case STATE_NUMBER_FROM_TO:
				n_to = n_to * 10 + atoi (&s[i]);
				if (n_to > G_MAXUINT16) err = TRUE;
				break;
			case STATE_FROM_TO:
				state = STATE_NUMBER_FROM_TO;
				n_to = atoi (&s[i]);
				if (!n_to) err = TRUE;
				break;
			case STATE_BEGIN_TO:
				state = STATE_NUMBER_BEGIN_TO;
				n_to = atoi (&s[i]);
				if (!n_to) err = TRUE;
				break;
			}
		} else if (s[i] == '-') {
			switch (state) {
			case STATE_BEGIN:
				state = STATE_BEGIN_TO;
				break;
			case STATE_NUMBER_FROM_TO:
			case STATE_NUMBER_BEGIN_TO:
			case STATE_BEGIN_TO:
			case STATE_FROM_TO:
				err = TRUE;
				break;
			case STATE_NUMBER_FROM:
				state = STATE_FROM_TO;
				break;
			}
		} else if ((s[i] == ',')) {
			switch (state) {
			case STATE_BEGIN:
				break;
			case STATE_FROM_TO:
				if (a->len < 1000)
					g_array_set_size (a, 1000);
				for (i = n_from - 1; i < 1000; i++)
					g_array_index (a, gboolean, i) = TRUE;
				break;
			case STATE_BEGIN_TO:
				err = TRUE;
				break;
			case STATE_NUMBER_FROM:
				state = STATE_BEGIN;
				if (a->len < n_from)
					g_array_set_size (a, n_from);
				g_array_index (a, gboolean, n_from - 1) = TRUE;
				break;
			case STATE_NUMBER_FROM_TO:
				state = STATE_BEGIN;
				if (a->len < MAX (n_from, n_to))
					g_array_set_size (a, MAX (n_from, n_to) + 1);
				for (i = MIN (n_from, n_to) - 1; i < MAX (n_from, n_to); i++)
					g_array_index (a, gboolean, i) = TRUE;
				break;
			case STATE_NUMBER_BEGIN_TO:
				state = STATE_BEGIN;
				if (a->len < n_to)
					g_array_set_size (a, n_to);
				for (i = 0; i < n_to - 1; i++)
					g_array_index (a, gboolean, i) = TRUE;
				break;
			}
		} else
			err = TRUE;
	}

	if (!err) switch (state) {
	case STATE_BEGIN:
		break;
	case STATE_BEGIN_TO:
		err = TRUE;
		break;
	case STATE_FROM_TO:
		if (a->len < 1000)
			g_array_set_size (a, 1000);
		for (i = n_from - 1; i < 1000; i++)
			g_array_index (a, gboolean, i) = TRUE;
		break;
	case STATE_NUMBER_FROM:
		if (a->len < n_from)
			g_array_set_size (a, n_from);
		g_array_index (a, gboolean, n_from - 1) = TRUE;
		break;
	case STATE_NUMBER_FROM_TO:
		if (a->len < MAX (n_from, n_to))
			g_array_set_size (a, MAX (n_from, n_to) + 1);
		for (i = MIN (n_from, n_to) - 1; i < MAX (n_from, n_to); i++)
			g_array_index (a, gboolean, i) = TRUE;
		break;
	case STATE_NUMBER_BEGIN_TO:
		if (a->len < n_to)
			g_array_set_size (a, n_to);
		for (i = 0; i < n_to - 1; i++)
			g_array_index (a, gboolean, i) = TRUE;
		break;
	}

	if (err) {
		i = gtk_editable_get_position (GTK_EDITABLE (ps->e_selection));
		gtk_editable_delete_text (GTK_EDITABLE (ps->e_selection), i, i + 1);
	}

	return a;
}

static void
gnome_print_page_selector_save_config (GnomePrintPageSelector *ps)
{
	gchar *description;
	GnomePrintFilter *filter = NULL, *f_old;

	g_return_if_fail (GNOME_IS_PRINT_PAGE_SELECTOR (ps));

	if (ps->loading || !ps->config)
		return;

	/* All */
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_all))) {
		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_even)))
			filter = gnome_print_filter_new_from_module_name ("select",
					"first", 1, "skip", 1, NULL);
		else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_odd)))
			filter = gnome_print_filter_new_from_module_name ("select",
					"first", 0, "skip", 1, NULL);
		else
			return;
	}

	/* Current */
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_current))) {
		filter = gnome_print_filter_new_from_module_name ("select",
				"first", ps->current - 1, "last", ps->current - 1, NULL);
	}

	/* Selection */
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_selection))) {
		GArray *a;
		GValueArray *va = NULL;

		a = gnome_print_page_selector_get_array (ps);
		if (a) {
			GValue v = {0,};
			guint i;

			g_value_init (&v, G_TYPE_BOOLEAN);
			va = g_value_array_new (a->len);
			for (i = 0; i < a->len; i++) {
				g_value_set_boolean (&v, g_array_index (a, gboolean, i));
				g_value_array_append (va, &v);
			}
			g_array_free (a, TRUE);
			g_value_unset (&v);
		}
		filter = gnome_print_filter_new_from_module_name ("select",
				"pages", va, NULL);
	}

	/* From ... to ... */
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_from_to))) {
		guint first = ps->a_from->value, last = ps->a_to->value, skip = 0;

		if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_even))) {
			skip = 1;
			if (first & 1) first++;
		} else if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_odd))) {
			skip = 1;
			if (first & 1) first++;
		}
		filter = gnome_print_filter_new_from_module_name ("select",
				"first", first, "last", last, "skip", skip, NULL);
	}

	if (!filter)
		return;
	description = (gchar *) gnome_print_config_get (ps->config,
			(const guchar *) "Settings.Output.Job.Filter");
	if (description) {
		f_old = gnome_print_filter_new_from_description (description, NULL);
		g_free (description);
		if (f_old) {

			/*
			 * For now, assume that if the first filter is a 
			 * GnomePrintFilterSelect, it has been added by us.
			 */
			if (!strcmp (G_OBJECT_TYPE_NAME (G_OBJECT (f_old)), "GnomePrintFilterSelect")) {
				guint i;

				for (i = 0; i < gnome_print_filter_count_successors (f_old); i++)
					gnome_print_filter_append_predecessor (
							gnome_print_filter_get_successor (f_old, i), filter);
				while (gnome_print_filter_count_successors (f_old))
					gnome_print_filter_remove_predecessor (
							gnome_print_filter_get_successor (f_old, 0), f_old);
			} else
				gnome_print_filter_append_predecessor (f_old, filter);
			g_object_unref (G_OBJECT (f_old));
		}
	}
	description = gnome_print_filter_description (filter);
	g_object_unref (G_OBJECT (filter));
	if (description) {
		gnome_print_config_set (ps->config,
			(const guchar *) "Settings.Output.Job.Filter", 
			(const guchar *) description);
		g_free (description);
	}
}

static void
gnome_print_page_selector_get_property (GObject *object, guint n, GValue *v,
		GParamSpec *pspec)
{
	GnomePrintPageSelector *ps = GNOME_PRINT_PAGE_SELECTOR (object);

	switch (n) {
	case PROP_CONFIG:
		g_value_set_object (v, ps->config);
		break;
	case PROP_CURRENT:
		g_value_set_uint (v, ps->current);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, n, pspec);
	}
}

static void
gnome_print_page_selector_set_property (GObject *object, guint n,
		const GValue *v, GParamSpec *pspec)
{
	GnomePrintPageSelector *ps = GNOME_PRINT_PAGE_SELECTOR (object);

	switch (n) {
	case PROP_CONFIG:
		if (ps->config)
			g_object_unref (G_OBJECT (ps->config));
		ps->config = g_value_get_object (v);
		g_object_ref (G_OBJECT (ps->config));
		gnome_print_page_selector_load_config (ps);
		break;
	case PROP_CURRENT:
		ps->current = g_value_get_uint (v);
		gtk_widget_set_sensitive (ps->r_current, ps->current);
		break;
	default:
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, n, pspec);
	}
}

static void
gnome_print_page_selector_finalize (GObject *object)
{
	GnomePrintPageSelector *ps = GNOME_PRINT_PAGE_SELECTOR (object);

	if (ps->config) {
		g_object_unref (G_OBJECT (ps->config));
		ps->config = NULL;
	}
}

static void
gnome_print_page_selector_class_init (GnomePrintPageSelectorClass *klass)
{
	GObjectClass *object_class = (GObjectClass *) klass;

	parent_class = g_type_class_peek_parent (klass);

	object_class->get_property = gnome_print_page_selector_get_property;
	object_class->set_property = gnome_print_page_selector_set_property;
	object_class->finalize     = gnome_print_page_selector_finalize;

	g_object_class_install_property (object_class, PROP_CONFIG,
			g_param_spec_object ("config", _("Configuration"), _("Configuration"),
				GNOME_TYPE_PRINT_CONFIG, G_PARAM_READWRITE));
	g_object_class_install_property (object_class, PROP_CURRENT,
			g_param_spec_uint ("current", _("Current page"), _("Current page"),
				0, G_MAXUINT, 0, G_PARAM_READWRITE));
}

static void
on_even_toggled (GtkToggleButton *b, GnomePrintPageSelector *ps)
{
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_even)) && 
			gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_odd)))
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps->c_odd), FALSE);
	gnome_print_page_selector_save_config (ps);
}

static void
on_odd_toggled (GtkToggleButton *b, GnomePrintPageSelector *ps)
{
	if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_even)) &&
			gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->c_odd)))
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps->c_even), FALSE);
	gnome_print_page_selector_save_config (ps);
}

static void
on_all_toggled (GtkToggleButton *b, GnomePrintPageSelector *ps)
{
	gtk_widget_set_sensitive (ps->c_even, TRUE);
	gtk_widget_set_sensitive (ps->c_odd, TRUE);
	gnome_print_page_selector_save_config (ps);
}

static void
on_current_toggled (GtkToggleButton *b, GnomePrintPageSelector *ps)
{
	gtk_widget_set_sensitive (ps->c_even, FALSE);
	gtk_widget_set_sensitive (ps->c_odd, FALSE);
	gnome_print_page_selector_save_config (ps);
}

static void
on_from_to_toggled (GtkToggleButton *b, GnomePrintPageSelector *ps)
{
	gtk_widget_set_sensitive (ps->c_even, TRUE);
	gtk_widget_set_sensitive (ps->c_odd, TRUE);
	gnome_print_page_selector_save_config (ps);
}

static void
on_selection_toggled (GtkToggleButton *b, GnomePrintPageSelector *ps)
{
	gtk_widget_set_sensitive (ps->c_even, FALSE);
	gtk_widget_set_sensitive (ps->c_odd, FALSE);
	gnome_print_page_selector_save_config (ps);
}

static void
on_to_value_changed (GtkAdjustment *a, GnomePrintPageSelector *ps)
{
	if (!GTK_TOGGLE_BUTTON (ps->r_from_to)->active)
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps->r_from_to), TRUE);
	gnome_print_page_selector_save_config (ps);
}

static void
on_from_value_changed (GtkAdjustment *a, GnomePrintPageSelector *ps)
{
	if (!GTK_TOGGLE_BUTTON (ps->r_from_to)->active)
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps->r_from_to), TRUE);
	g_object_set (G_OBJECT (ps->a_to), "lower", ps->a_from->value, NULL);
	g_object_set (G_OBJECT (ps->a_to), "value", MAX (ps->a_to->value, ps->a_from->value), NULL);
	gnome_print_page_selector_save_config (ps);
}

static void
on_selection_changed (GtkEditable *editable, GnomePrintPageSelector *ps)
{
	if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ps->r_selection)))
		gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ps->r_selection), TRUE);
	gnome_print_page_selector_save_config (ps);
}

static void
gnome_print_page_selector_init (GnomePrintPageSelector *ps)
{
	GtkWidget *t, *hb, *w;
	gchar *s;

	s = g_strdup_printf ("<b>%s</b>", _("Print Range"));
	g_object_set (G_OBJECT (ps), "label", s,
			"shadow-type", GTK_SHADOW_NONE, NULL);
	g_object_set (G_OBJECT (GTK_FRAME (ps)->label_widget),
			"use-markup", TRUE, "use-underline", TRUE, NULL);

	t = g_object_new (GTK_TYPE_TABLE, "column-spacing", 5,
			"row-spacing", 5, "border-width", 5, NULL);
	gtk_widget_show (t);
	gtk_container_add (GTK_CONTAINER (ps), t);

	/* All pages */
	ps->r_all = gtk_radio_button_new_with_mnemonic (NULL, _("_All"));
	gtk_widget_show (ps->r_all);
	gtk_table_attach (GTK_TABLE (t), ps->r_all, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);

	/* Current page */
	ps->r_current = gtk_radio_button_new_with_mnemonic_from_widget (
			GTK_RADIO_BUTTON (ps->r_all), _("_Current"));
	gtk_widget_show (ps->r_current);
	gtk_table_attach (GTK_TABLE (t), ps->r_current, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
	gtk_widget_set_sensitive (ps->r_current, FALSE);

	/* From - To */
	hb = g_object_new (GTK_TYPE_HBOX, NULL);
	gtk_widget_show (hb);
	gtk_table_attach (GTK_TABLE (t), hb, 0, 1, 2, 3, GTK_FILL, 0, 0, 0);
	ps->r_from_to = g_object_new (GTK_TYPE_RADIO_BUTTON, "group", ps->r_all, NULL);
	gtk_widget_show (ps->r_from_to);
	gtk_box_pack_start (GTK_BOX (hb), ps->r_from_to, FALSE, FALSE, 0);
	w = g_object_new (GTK_TYPE_LABEL, "label", _("_From page "),
			"use-markup", TRUE, "use-underline", TRUE,
			"mnemonic-widget", ps->r_from_to, NULL);
	gtk_widget_show (w);
	gtk_box_pack_start (GTK_BOX (hb), w, FALSE, FALSE, 0);
	ps->a_from = g_object_new (GTK_TYPE_ADJUSTMENT, "lower", 1., "upper", G_MAXDOUBLE,
			"value", 1., "step-increment", 1., "page-increment", 10., NULL);
	w = g_object_new (GTK_TYPE_SPIN_BUTTON, "adjustment", ps->a_from, NULL);
	gtk_widget_show (w);
	gtk_box_pack_start (GTK_BOX (hb), w, FALSE, FALSE, 0);
	w = g_object_new (GTK_TYPE_LABEL, "label", _(" to "), NULL);
	gtk_widget_show (w);
	gtk_box_pack_start (GTK_BOX (hb), w, FALSE, FALSE, 0);
	ps->a_to = g_object_new (GTK_TYPE_ADJUSTMENT, "lower", 1., "upper", G_MAXDOUBLE,
			"value", 1., "step-increment", 1., "page-increment", 10., NULL);
	w = g_object_new (GTK_TYPE_SPIN_BUTTON, "adjustment", ps->a_to, NULL);
	gtk_widget_show (w);
	gtk_box_pack_start (GTK_BOX (hb), w, FALSE, FALSE, 0);

	/* Custom page selection */
	hb = g_object_new (GTK_TYPE_HBOX, NULL);
	gtk_widget_show (hb);
	gtk_table_attach (GTK_TABLE (t), hb, 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
	ps->r_selection= g_object_new (GTK_TYPE_RADIO_BUTTON, "group", ps->r_all, NULL);
	gtk_widget_show (ps->r_selection);
	gtk_box_pack_start (GTK_BOX (hb), ps->r_selection, FALSE, FALSE, 0);
	w = g_object_new (GTK_TYPE_LABEL, "label", _("_Selection: "),
			"use-markup", TRUE, "use-underline", TRUE,
			"mnemonic-widget", ps->r_selection, NULL);
	gtk_widget_show (w);
	gtk_box_pack_start (GTK_BOX (hb), w, FALSE, FALSE, 0);
	ps->e_selection = g_object_new (GTK_TYPE_ENTRY, NULL);
	gtk_widget_show (ps->e_selection);
	gtk_box_pack_start (GTK_BOX (hb), ps->e_selection, FALSE, FALSE, 0);

	/* Print only... */
	w = g_object_new (GTK_TYPE_LABEL, "label", _("Print only..."), "xalign", 0., NULL),
	gtk_widget_show (w);
	gtk_table_attach (GTK_TABLE (t), w, 1, 2, 0, 1, GTK_FILL, 0, 0, 0);

	/* Even */
	ps->c_even = gtk_check_button_new_with_mnemonic (" _even pages");
	gtk_widget_show (ps->c_even);
	gtk_table_attach (GTK_TABLE (t), ps->c_even, 1, 2, 1, 2, GTK_FILL, 0, 0, 0);

	/* Odd */
	ps->c_odd = gtk_check_button_new_with_mnemonic (" _odd pages");
	gtk_widget_show (ps->c_odd);
	gtk_table_attach (GTK_TABLE (t), ps->c_odd, 1, 2, 2, 3, GTK_FILL, 0, 0, 0);

	/* Connect some signals */
	g_signal_connect (G_OBJECT (ps->r_all), "toggled", G_CALLBACK (on_all_toggled), ps);
	g_signal_connect (G_OBJECT (ps->r_current), "toggled", G_CALLBACK (on_current_toggled), ps);
	g_signal_connect (G_OBJECT (ps->r_from_to), "toggled", G_CALLBACK (on_from_to_toggled), ps);
	g_signal_connect (G_OBJECT (ps->r_selection), "toggled", G_CALLBACK (on_selection_toggled), ps);
	g_signal_connect (G_OBJECT (ps->c_even), "toggled", G_CALLBACK (on_even_toggled), ps);
	g_signal_connect (G_OBJECT (ps->c_odd), "toggled", G_CALLBACK (on_odd_toggled), ps);
	g_signal_connect (G_OBJECT (ps->a_to), "value_changed", G_CALLBACK (on_to_value_changed), ps);
	g_signal_connect (G_OBJECT (ps->a_from), "value_changed", G_CALLBACK (on_from_value_changed), ps);
	g_signal_connect (G_OBJECT (ps->e_selection), "changed", G_CALLBACK (on_selection_changed), ps);

	gnome_print_set_atk_relation (GTK_FRAME (ps)->label_widget, ps->r_all);
	gnome_print_set_atk_relation (GTK_FRAME (ps)->label_widget, ps->r_current);
	gnome_print_set_atk_relation (GTK_FRAME (ps)->label_widget, ps->r_from_to);
	gnome_print_set_atk_relation (GTK_FRAME (ps)->label_widget, ps->r_selection);
	gnome_print_set_atk_relation (GTK_FRAME (ps)->label_widget, ps->c_even);
	gnome_print_set_atk_relation (GTK_FRAME (ps)->label_widget, ps->c_odd);
}

GType
gnome_print_page_selector_get_type (void)
{
	static GType type = 0;

	if (!type) {
		static const GTypeInfo info = {
			sizeof (GnomePrintPageSelectorClass), NULL, NULL,
			(GClassInitFunc) gnome_print_page_selector_class_init,
			NULL, NULL, sizeof (GnomePrintPageSelector), 0,
			(GInstanceInitFunc) gnome_print_page_selector_init
		};
		type = g_type_register_static (GTK_TYPE_FRAME,
				"GnomePrintPageSelector", &info, 0);
	}
	return type;
}

--=-y0L+PALab+5EaOKjk+Du
Content-Disposition: attachment; filename=gnome-print-page-selector.h
Content-Type: text/x-chdr; name=gnome-print-page-selector.h;
	charset=ANSI_X3.4-1968
Content-Transfer-Encoding: 7bit

#ifndef __GNOME_PRINT_PAGE_SELECTOR_H__
#define __GNOME_PRINT_PAGE_SELECTOR_H__

#include <glib-object.h>

G_BEGIN_DECLS

#define GNOME_TYPE_PRINT_PAGE_SELECTOR (gnome_print_page_selector_get_type ())
#define GNOME_PRINT_PAGE_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GNOME_TYPE_PRINT_PAGE_SELECTOR, GnomePrintPageSelector))
#define GNOME_PRINT_PAGE_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), GNOME_TYPE_PRINT_PAGE_SELECTOR, GnomePrintPageSelectorClass))
#define GNOME_IS_PRINT_PAGE_SELECTOR(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GNOME_TYPE_PRINT_PAGE_SELECTOR))
#define GNOME_IS_PRINT_PAGE_SELECTOR_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GNOME_TYPE_PRINT_PAGE_SELECTOR))
#define GNOME_PRINT_PAGE_SELECTOR_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GNOME_TYPE_PRINT_PAGE_SELECTOR, GnomePrintPageSelectorClass))

typedef struct _GnomePrintPageSelector GnomePrintPageSelector;
typedef struct _GnomePrintPageSelectorClass GnomePrintPageSelectorClass;

GType gnome_print_page_selector_get_type (void);

G_END_DECLS

#endif /* __GNOME_PRINT_PAGE_SELECTOR_H__ */

--=-y0L+PALab+5EaOKjk+Du
Content-Disposition: attachment; filename=GnomePrintPageSelector.png
Content-Type: image/png; name=GnomePrintPageSelector.png
Content-Transfer-Encoding: base64

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
d3/A5gAAAABJRU5ErkJggh==


--=-y0L+PALab+5EaOKjk+Du
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
gnome-print-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnome-print-list

--=-y0L+PALab+5EaOKjk+Du--