Page selection in GnomePrintDialog



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
-- 
Lutz Müller <lutz users sourceforge net>
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;
#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;
}
#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__ */

Attachment: GnomePrintPageSelector.png
Description: PNG image



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