Import print-operation into gtk+

2006-03-24  Alexander Larsson  <alexl@redhat.com>

        Import print-operation into gtk+

	* .cvsignore:
	* Makefile.am:
	* gtk+-unix-print-2.0.pc.in:
	Add gtk+-unix-print-2.0.pc

	* configure.in:
	Look for cups
	Look for various _NL_* extensions
	Output new makefiles and .pc.in

	* gtk/Makefile.am:
	Add new files

	* gtk/gtk.h:
	Include gtkprintoperation.h

	* gtk/gtkenums.h:
	Add printing enums

	* gtk/gtkmarshalers.list:
	Add required new marshallers

	* gtk/gtkpagesetup.[ch]:
	* gtk/gtkpagesetupunixdialog.[ch]:
	* gtk/gtkpagesetupunixdialog.h:
	* gtk/gtkpapersize.[ch]:
	* gtk/gtkprint-win32.[ch]:
	* gtk/gtkprintbackend.[ch]:
	* gtk/gtkprintcontext.[ch]:
	* gtk/gtkprinter-private.h:
	* gtk/gtkprinter.[ch]:
	* gtk/gtkprinteroption.[ch]:
	* gtk/gtkprinteroptionset.[ch]:
	* gtk/gtkprinteroptionwidget.[ch]:
	* gtk/gtkprintjob.[ch]:
	* gtk/gtkprintoperation-private.h:
	* gtk/gtkprintoperation-unix.c:
	* gtk/gtkprintoperation-win32.c:
	* gtk/gtkprintoperation.[ch]:
	* gtk/gtkprintsettings.[ch]:
	* gtk/gtkprintunixdialog.[ch]:
	* gtk/paper_names.c:
	Generic printing support

	* modules/Makefile.am:
	* modules/printbackends/Makefile.am:
	* modules/printbackends/cups/Makefile.am:
	* modules/printbackends/cups/gtkcupsutils.[ch]:
	* modules/printbackends/cups/gtkprintbackendcups.[ch]:
	* modules/printbackends/cups/gtkprintercups.[ch]:
	Cups backend

	* tests/.cvsignore:
	* tests/Makefile.am:
	* tests/print-editor.c:
	Add printing test app
This commit is contained in:
Alexander Larsson
2006-03-24 16:33:21 +00:00
committed by Alexander Larsson
parent 112f3289d6
commit 65df7d0a56
56 changed files with 16710 additions and 408 deletions

View File

@@ -19,6 +19,7 @@ stamp-h.in
gtk+.spec
gtk+-2.0.pc
gtk+-2.0-uninstalled.pc
gtk+-unix-print-2.0.pc
gtk+-linux-fb-2.0.pc
gtk+-nanox-2.0.pc
gtk+-x11-2.0.pc

View File

@@ -1,3 +1,64 @@
2006-03-24 Alexander Larsson <alexl@redhat.com>
Import print-operation into gtk+
* .cvsignore:
* Makefile.am:
* gtk+-unix-print-2.0.pc.in:
Add gtk+-unix-print-2.0.pc
* configure.in:
Look for cups
Look for various _NL_* extensions
Output new makefiles and .pc.in
* gtk/Makefile.am:
Add new files
* gtk/gtk.h:
Include gtkprintoperation.h
* gtk/gtkenums.h:
Add printing enums
* gtk/gtkmarshalers.list:
Add required new marshallers
* gtk/gtkpagesetup.[ch]:
* gtk/gtkpagesetupunixdialog.[ch]:
* gtk/gtkpagesetupunixdialog.h:
* gtk/gtkpapersize.[ch]:
* gtk/gtkprint-win32.[ch]:
* gtk/gtkprintbackend.[ch]:
* gtk/gtkprintcontext.[ch]:
* gtk/gtkprinter-private.h:
* gtk/gtkprinter.[ch]:
* gtk/gtkprinteroption.[ch]:
* gtk/gtkprinteroptionset.[ch]:
* gtk/gtkprinteroptionwidget.[ch]:
* gtk/gtkprintjob.[ch]:
* gtk/gtkprintoperation-private.h:
* gtk/gtkprintoperation-unix.c:
* gtk/gtkprintoperation-win32.c:
* gtk/gtkprintoperation.[ch]:
* gtk/gtkprintsettings.[ch]:
* gtk/gtkprintunixdialog.[ch]:
* gtk/paper_names.c:
Generic printing support
* modules/Makefile.am:
* modules/printbackends/Makefile.am:
* modules/printbackends/cups/Makefile.am:
* modules/printbackends/cups/gtkcupsutils.[ch]:
* modules/printbackends/cups/gtkprintbackendcups.[ch]:
* modules/printbackends/cups/gtkprintercups.[ch]:
Cups backend
* tests/.cvsignore:
* tests/Makefile.am:
* tests/print-editor.c:
Add printing test app
2006-03-23 Matthias Clasen <mclasen@redhat.com>
* AUTHORS: small update

View File

@@ -1,3 +1,64 @@
2006-03-24 Alexander Larsson <alexl@redhat.com>
Import print-operation into gtk+
* .cvsignore:
* Makefile.am:
* gtk+-unix-print-2.0.pc.in:
Add gtk+-unix-print-2.0.pc
* configure.in:
Look for cups
Look for various _NL_* extensions
Output new makefiles and .pc.in
* gtk/Makefile.am:
Add new files
* gtk/gtk.h:
Include gtkprintoperation.h
* gtk/gtkenums.h:
Add printing enums
* gtk/gtkmarshalers.list:
Add required new marshallers
* gtk/gtkpagesetup.[ch]:
* gtk/gtkpagesetupunixdialog.[ch]:
* gtk/gtkpagesetupunixdialog.h:
* gtk/gtkpapersize.[ch]:
* gtk/gtkprint-win32.[ch]:
* gtk/gtkprintbackend.[ch]:
* gtk/gtkprintcontext.[ch]:
* gtk/gtkprinter-private.h:
* gtk/gtkprinter.[ch]:
* gtk/gtkprinteroption.[ch]:
* gtk/gtkprinteroptionset.[ch]:
* gtk/gtkprinteroptionwidget.[ch]:
* gtk/gtkprintjob.[ch]:
* gtk/gtkprintoperation-private.h:
* gtk/gtkprintoperation-unix.c:
* gtk/gtkprintoperation-win32.c:
* gtk/gtkprintoperation.[ch]:
* gtk/gtkprintsettings.[ch]:
* gtk/gtkprintunixdialog.[ch]:
* gtk/paper_names.c:
Generic printing support
* modules/Makefile.am:
* modules/printbackends/Makefile.am:
* modules/printbackends/cups/Makefile.am:
* modules/printbackends/cups/gtkcupsutils.[ch]:
* modules/printbackends/cups/gtkprintbackendcups.[ch]:
* modules/printbackends/cups/gtkprintercups.[ch]:
Cups backend
* tests/.cvsignore:
* tests/Makefile.am:
* tests/print-editor.c:
Add printing test app
2006-03-23 Matthias Clasen <mclasen@redhat.com>
* AUTHORS: small update

View File

@@ -132,9 +132,10 @@ gdk-$(GDKTARGET)-2.0-uninstalled.pc: gdk-2.0-uninstalled.pc
cp gdk-2.0-uninstalled.pc gdk-$(GDKTARGET)-2.0-uninstalled.pc
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA= gdk-pixbuf-2.0.pc gdk-$(GDKTARGET)-2.0.pc gtk+-$(GDKTARGET)-2.0.pc
pkgconfig_DATA= gdk-pixbuf-2.0.pc gdk-$(GDKTARGET)-2.0.pc gtk+-$(GDKTARGET)-2.0.pc gtk+-unix-print-2.0.pc
DISTCLEANFILES = \
gtk+-unix-print-2.0.pc \
gtk+-$(GDKTARGET)-2.0.pc \
gdk-$(GDKTARGET)-2.0.pc \
gtk+-$(GDKTARGET)-2.0-uninstalled.pc \

View File

@@ -416,6 +416,42 @@ if test "$gtk_ok" = "yes"; then
[Define if _NL_TIME_FIRST_WEEKDAY is available])
fi
# _NL_MEASUREMENT_MEASUREMENT is an enum and not a define
AC_MSG_CHECKING([for _NL_MEASUREMENT_MEASUREMENT])
AC_TRY_LINK([#include <langinfo.h>], [
char c;
c = *((unsigned char *) nl_langinfo(_NL_MEASUREMENT_MEASUREMENT));
], gtk_ok=yes, gtk_ok=no)
AC_MSG_RESULT($gtk_ok)
if test "$gtk_ok" = "yes"; then
AC_DEFINE([HAVE__NL_MEASUREMENT_MEASUREMENT], [1],
[Define if _NL_MEASUREMENT_MEASUREMENT is available])
fi
# _NL_PAPER_HEIGHT is an enum and not a define
AC_MSG_CHECKING([for _NL_PAPER_HEIGHT])
AC_TRY_LINK([#include <langinfo.h>], [
char c;
c = *((unsigned char *) nl_langinfo(_NL_PAPER_HEIGHT));
], gtk_ok=yes, gtk_ok=no)
AC_MSG_RESULT($gtk_ok)
if test "$gtk_ok" = "yes"; then
AC_DEFINE([HAVE__NL_PAPER_HEIGHT], [1],
[Define if _NL_PAPER_HEIGHT is available])
fi
# _NL_PAPER_WIDTH is an enum and not a define
AC_MSG_CHECKING([for _NL_PAPER_WIDTH])
AC_TRY_LINK([#include <langinfo.h>], [
char c;
c = *((unsigned char *) nl_langinfo(_NL_PAPER_WIDTH));
], gtk_ok=yes, gtk_ok=no)
AC_MSG_RESULT($gtk_ok)
if test "$gtk_ok" = "yes"; then
AC_DEFINE([HAVE__NL_PAPER_WIDTH], [1],
[Define if _NL_PAPER_WIDTH is available])
fi
# sigsetjmp is a macro on some platforms, so AC_CHECK_FUNCS is not reliable
AC_MSG_CHECKING(for sigsetjmp)
AC_TRY_LINK([#include <setjmp.h>], [
@@ -1499,6 +1535,20 @@ AC_SUBST(GTK_DEP_CFLAGS)
AC_SUBST(GTK_DEBUG_FLAGS)
AC_SUBST(GTK_XIM_FLAGS)
################################################################
# Printing system checks
################################################################
AC_PATH_PROG(CUPS_CONFIG, cups-config, no)
if test "x$CUPS_CONFIG" != "xno"; then
CUPS_CFLAGS=`cups-config --cflags | sed 's/-O[0-9]*//' | sed 's/-m[^\t]*//g'`
CUPS_LIBS=`cups-config --libs`
AC_SUBST(CUPS_CFLAGS)
AC_SUBST(CUPS_LIBS)
fi
################################################################
# Strip -export-dynamic from the link lines of various libraries
################################################################
@@ -1638,6 +1688,7 @@ Makefile
gdk-pixbuf-2.0.pc
gdk-2.0.pc
gtk+-2.0.pc
gtk+-unix-print-2.0.pc
gdk-pixbuf-2.0-uninstalled.pc
gdk-2.0-uninstalled.pc
gtk+-2.0-uninstalled.pc
@@ -1684,6 +1735,8 @@ modules/engines/pixbuf/Makefile
modules/engines/ms-windows/Makefile
modules/engines/ms-windows/Theme/Makefile
modules/engines/ms-windows/Theme/gtk-2.0/Makefile
modules/printbackends/Makefile
modules/printbackends/cups/Makefile
perf/Makefile
contrib/Makefile
contrib/gdk-pixbuf-xlib/Makefile

View File

@@ -1,392 +0,0 @@
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <demos.h>
static GtkTextBuffer *info_buffer;
static GtkTextBuffer *source_buffer;
static gchar *current_file = NULL;
enum {
TITLE_COLUMN,
FILENAME_COLUMN,
FUNC_COLUMN,
ITALIC_COLUMN,
NUM_COLUMNS
};
gboolean
read_line (FILE *stream, GString *str)
{
int n_read = 0;
flockfile (stream);
g_string_truncate (str, 0);
while (1)
{
int c;
c = getc_unlocked (stream);
if (c == EOF)
goto done;
else
n_read++;
switch (c)
{
case '\r':
case '\n':
{
int next_c = getc_unlocked (stream);
if (!(next_c == EOF ||
(c == '\r' && next_c == '\n') ||
(c == '\n' && next_c == '\r')))
ungetc (next_c, stream);
goto done;
}
default:
g_string_append_c (str, c);
}
}
done:
funlockfile (stream);
return n_read > 0;
}
void
load_file (const gchar *filename)
{
FILE *file;
GtkTextIter start, end;
GString *buffer = g_string_new (NULL);
int state = 0;
gboolean in_para = 0;
if (current_file && !strcmp (current_file, filename))
return;
g_free (current_file);
current_file = g_strdup (filename);
gtk_text_buffer_get_bounds (info_buffer, &start, &end);
gtk_text_buffer_delete (info_buffer, &start, &end);
gtk_text_buffer_get_bounds (source_buffer, &start, &end);
gtk_text_buffer_delete (source_buffer, &start, &end);
file = fopen (filename, "r");
if (!file)
{
g_warning ("Cannot open %s: %s\n", filename, g_strerror (errno));
return;
}
gtk_text_buffer_get_iter_at_offset (info_buffer, &start, 0);
while (read_line (file, buffer))
{
gchar *p = buffer->str;
gchar *q;
switch (state)
{
case 0:
/* Reading title */
while (*p == '/' || *p == '*' || isspace (*p))
p++;
q = p + strlen (p);
while (q > p && isspace (*(q - 1)))
q--;
if (q > p)
{
int len_chars = g_utf8_pointer_to_offset (p, q);
end = start;
g_assert (strlen (p) >= q - p);
gtk_text_buffer_insert (info_buffer, &end, p, q - p);
start = end;
gtk_text_iter_backward_chars (&start, len_chars);
gtk_text_buffer_apply_tag_by_name (info_buffer, "title", &start, &end);
start = end;
state++;
}
break;
case 1:
/* Reading body of info section */
while (isspace (*p))
p++;
if (*p == '*' && *(p + 1) == '/')
{
gtk_text_buffer_get_iter_at_offset (source_buffer, &start, 0);
state++;
}
else
{
int len;
while (*p == '*' || isspace (*p))
p++;
len = strlen (p);
while (isspace (*(p + len - 1)))
len--;
if (len > 0)
{
if (in_para)
gtk_text_buffer_insert (info_buffer, &start, " ", 1);
g_assert (strlen (p) >= len);
gtk_text_buffer_insert (info_buffer, &start, p, len);
in_para = 1;
}
else
{
gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
in_para = 0;
}
}
break;
case 2:
/* Skipping blank lines */
while (isspace (*p))
p++;
if (*p)
{
p = buffer->str;
state++;
/* Fall through */
}
else
break;
case 3:
/* Reading program body */
gtk_text_buffer_insert (source_buffer, &start, p, -1);
gtk_text_buffer_insert (info_buffer, &start, "\n", 1);
break;
}
}
gtk_text_buffer_get_bounds (source_buffer, &start, &end);
gtk_text_buffer_apply_tag_by_name (info_buffer, "source", &start, &end);
}
gboolean
button_press_event_cb (GtkTreeView *tree_view,
GdkEventButton *event,
GtkTreeModel *model)
{
if (event->type == GDK_2BUTTON_PRESS)
{
GtkTreePath *path = NULL;
gtk_tree_view_get_path_at_pos (tree_view,
event->window,
event->x,
event->y,
&path,
NULL);
if (path)
{
GtkTreeIter iter;
gboolean italic;
GVoidFunc func;
gtk_tree_model_get_iter (model, &iter, path);
gtk_tree_store_get (GTK_TREE_STORE (model),
&iter,
FUNC_COLUMN, &func,
ITALIC_COLUMN, &italic,
-1);
(func) ();
gtk_tree_store_set (GTK_TREE_STORE (model),
&iter,
ITALIC_COLUMN, !italic,
-1);
gtk_tree_path_free (path);
}
gtk_signal_emit_stop_by_name (GTK_OBJECT (tree_view),
"button_press_event");
return TRUE;
}
return FALSE;
}
static void
selection_cb (GtkTreeSelection *selection,
GtkTreeModel *model)
{
GtkTreeIter iter;
GValue value = {0, };
if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
return;
gtk_tree_model_get_value (model, &iter,
FILENAME_COLUMN,
&value);
load_file (g_value_get_string (&value));
g_value_unset (&value);
}
static GtkWidget *
create_text (GtkTextBuffer **buffer,
gboolean is_source)
{
GtkWidget *scrolled_window;
GtkWidget *text_view;
PangoFontDescription *font_desc;
scrolled_window = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_window),
GTK_SHADOW_IN);
text_view = gtk_text_view_new ();
gtk_container_add (GTK_CONTAINER (scrolled_window), text_view);
*buffer = gtk_text_buffer_new (NULL);
gtk_text_view_set_buffer (GTK_TEXT_VIEW (text_view), *buffer);
gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
gtk_text_view_set_cursor_visible (GTK_TEXT_VIEW (text_view), FALSE);
if (is_source)
{
font_desc = pango_font_description_from_string ("Courier 10");
gtk_widget_modify_font (text_view, font_desc);
pango_font_description_free (font_desc);
}
gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (text_view), !is_source);
return scrolled_window;
}
/* Technically a list, but if we do go to 80 demos, we may want to move to a tree */
static GtkWidget *
create_tree (void)
{
GtkTreeSelection *selection;
GtkCellRenderer *cell;
GtkWidget *tree_view;
GtkTreeViewColumn *column;
GtkTreeStore *model;
GtkTreeIter iter;
gint i;
model = gtk_tree_store_new_with_types (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_POINTER, G_TYPE_BOOLEAN);
tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view));
gtk_tree_selection_set_type (GTK_TREE_SELECTION (selection),
GTK_TREE_SELECTION_SINGLE);
gtk_widget_set_usize (tree_view, 200, -1);
for (i=0; i < G_N_ELEMENTS (testgtk_demos); i++)
{
gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
gtk_tree_store_set (GTK_TREE_STORE (model),
&iter,
TITLE_COLUMN, testgtk_demos[i].title,
FILENAME_COLUMN, testgtk_demos[i].filename,
FUNC_COLUMN, testgtk_demos[i].func,
ITALIC_COLUMN, FALSE,
-1);
}
cell = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes ("Widget",
cell,
"text", TITLE_COLUMN,
"italic", ITALIC_COLUMN,
NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view),
GTK_TREE_VIEW_COLUMN (column));
gtk_signal_connect (GTK_OBJECT (selection), "selection_changed", selection_cb, model);
gtk_signal_connect (GTK_OBJECT (tree_view), "button_press_event", GTK_SIGNAL_FUNC (button_press_event_cb), model);
return tree_view;
}
int
main (int argc, char **argv)
{
GtkWidget *window;
GtkWidget *notebook;
GtkWidget *hbox;
GtkWidget *tree;
GtkTextTag *tag;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
hbox = gtk_hbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), hbox);
tree = create_tree ();
gtk_box_pack_start (GTK_BOX (hbox), tree, FALSE, FALSE, 0);
notebook = gtk_notebook_new ();
gtk_box_pack_start (GTK_BOX (hbox), notebook, TRUE, TRUE, 0);
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
create_text (&info_buffer, FALSE),
gtk_label_new ("Info"));
gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
create_text (&source_buffer, TRUE),
gtk_label_new ("Source"));
tag = gtk_text_buffer_create_tag (info_buffer, "title");
gtk_object_set (GTK_OBJECT (tag),
"font", "Sans 18",
NULL);
tag = gtk_text_buffer_create_tag (info_buffer, "source");
gtk_object_set (GTK_OBJECT (tag),
"font", "Courier 10",
"pixels_above_lines", 0,
"pixels_below_lines", 0,
NULL);
gtk_window_set_default_size (GTK_WINDOW (window), 600, 400);
gtk_widget_show_all (window);
load_file (testgtk_demos[0].filename);
gtk_main ();
return 0;
}

14
gtk+-unix-print-2.0.pc.in Normal file
View File

@@ -0,0 +1,14 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
target=@gdktarget@
gtk_binary_version=@GTK_BINARY_VERSION@
gtk_host=@host@
Name: GTK+
Description: GIMP Tool Kit Unix print support
Version: @VERSION@
Requires: gtk-${target}-2.0 @GTK_PACKAGES@
Cflags: -I${includedir}/gtk-unix-print-2.0

View File

@@ -26,6 +26,7 @@ INCLUDES = \
-DGDK_DISABLE_DEPRECATED \
-DGTK_DISABLE_DEPRECATED \
-DGTK_FILE_SYSTEM_ENABLE_UNSUPPORTED \
-DGTK_PRINT_BACKEND_ENABLE_UNSUPPORTED \
$(GTK_DEBUG_FLAGS) \
$(GTK_DEP_CFLAGS)
@@ -214,10 +215,15 @@ gtk_public_h_sources = \
gtkobject.h \
gtkoldeditable.h \
gtkoptionmenu.h \
gtkpagesetup.h \
gtkpaned.h \
gtkpapersize.h \
gtkpixmap.h \
gtkplug.h \
gtkpreview.h \
gtkprintcontext.h \
gtkprintoperation.h \
gtkprintsettings.h \
gtkprivate.h \
gtkprogress.h \
gtkprogressbar.h \
@@ -288,6 +294,11 @@ gtk_public_h_sources = \
gtkwidget.h \
gtkwindow.h
gtk_unix_print_public_h_sources = \
gtkpagesetupunixdialog.h \
gtkprinter.h \
gtkprintunixdialog.h
# Installed header files without compatibility guarantees
# that are not include in gtk/gtk.h
gtk_semi_private_h_sources = \
@@ -298,32 +309,33 @@ gtk_semi_private_h_sources = \
gtk_private_h_sources = \
gtkdndcursors.h \
gtkentryprivate.h \
gtkfilechooserdefault.h \
gtkfilechooserembed.h \
gtkfilechooserentry.h \
gtkfilechooserdefault.h \
gtkfilechooserprivate.h \
gtkfilechooserutils.h \
gtkfilesystemunix.h \
gtkfilesystemmodel.h \
gtkfilesystemunix.h \
gtkiconcache.h \
gtkpathbar.h \
gtkplugprivate.h \
gtkprintoperation-private.h\
gtkrbtree.h \
gtksequence.h \
gtksocketprivate.h \
gtktextbtree.h \
gtktextchildprivate.h \
gtktextsegment.h \
gtktexttypes.h \
gtktextutil.h \
gtktextiterprivate.h \
gtktextmarkprivate.h \
gtktextsegment.h \
gtktexttagprivate.h \
gtktexttypes.h \
gtktextutil.h \
gtkthemes.h \
gtktoggleactionprivate.h\
gtktreedatalist.h \
gtktreeprivate.h \
gtkwindow-decorate.h \
gtktoggleactionprivate.h
gtkwindow-decorate.h
# GTK+ C sources to build the library from
gtk_c_sources = \
@@ -378,10 +390,10 @@ gtk_c_sources = \
gtkexpander.c \
gtkfilechooser.c \
gtkfilechooserbutton.c \
gtkfilechooserdefault.c \
gtkfilechooserdialog.c \
gtkfilechooserembed.c \
gtkfilechooserentry.c \
gtkfilechooserdefault.c \
gtkfilechooserutils.c \
gtkfilechooserwidget.c \
gtkfilefilter.c \
@@ -404,8 +416,8 @@ gtk_c_sources = \
gtkhseparator.c \
gtkhsv.c \
gtkhsv.h \
gtkiconfactory.c \
gtkiconcache.c \
gtkiconfactory.c \
gtkicontheme.c \
gtkiconview.c \
gtkimage.c \
@@ -444,11 +456,16 @@ gtk_c_sources = \
gtkobject.c \
gtkoldeditable.c \
gtkoptionmenu.c \
gtkpagesetup.c \
gtkpaned.c \
gtkpapersize.c \
gtkpathbar.c \
gtkpixmap.c \
gtkplug.c \
gtkpreview.c \
gtkprintcontext.c \
gtkprintoperation.c \
gtkprintsettings.c \
gtkprogress.c \
gtkprogressbar.c \
gtkradioaction.c \
@@ -462,11 +479,11 @@ gtk_c_sources = \
gtkscale.c \
gtkscrollbar.c \
gtkscrolledwindow.c \
gtksequence.c \
gtkselection.c \
gtkseparator.c \
gtkseparatormenuitem.c \
gtkseparatortoolitem.c \
gtksequence.c \
gtksettings.c \
gtksignal.c \
gtksizegroup.c \
@@ -536,13 +553,37 @@ gtk_c_sources = \
$(gtk_clipboard_dnd_c_sources)
if OS_UNIX
gtk_private_h_sources += gtkfilesystemunix.h
gtk_c_sources += gtkfilesystemunix.c
gtk_private_h_sources += \
gtkfilesystemunix.h \
gtkprintbackend.h \
gtkprinter-private.h \
gtkprinteroption.h \
gtkprinteroptionset.h \
gtkprinteroptionwidget.h \
gtkprintjob.h
gtk_c_sources += \
gtkfilesystemunix.c \
gtkpagesetupunixdialog.c \
gtkprinter.c \
gtkprinteroption.c \
gtkprinteroptionset.c \
gtkprinteroptionwidget.c \
gtkprintjob.c \
gtkprintoperation-unix.c \
gtkprintunixdialog.c \
gtkprintbackend.c
endif
if OS_WIN32
gtk_private_h_sources += gtkfilesystemwin32.h
gtk_c_sources += gtkfilesystemwin32.c
gtk_private_h_sources +=
gtkfilesystemwin32.h \
gtkprint-win32.h
gtk_c_sources += \
gtkfilesystemwin32.c \
gtkprint-win32.c \
gtkprintoperation-win32.c
endif
if USE_X11
@@ -603,6 +644,7 @@ stamp_files = \
# that don't serve as direct make target sources, i.e. they don't have
# their own .lo rules and don't get publically installed
gtk_extra_sources = \
paper_names.c \
gtk.symbols \
gtkversion.h.in \
gtkmarshalers.list \
@@ -686,6 +728,9 @@ lib_LTLIBRARIES = $(gtktargetlib)
gtkincludedir = $(includedir)/gtk-2.0/gtk
gtkinclude_HEADERS = $(gtk_public_h_sources) $(gtk_semi_private_h_sources) $(gtk_built_public_sources) gtkversion.h
gtkunixprintincludedir = $(includedir)/gtk-unix-print-2.0/gtk
gtkunixprintinclude_HEADERS = $(gtk_unix_print_public_h_sources)
libgtk_x11_2_0_la_SOURCES = $(gtk_c_sources)
libgtk_linux_fb_2_0_la_SOURCES = $(gtk_c_sources)
libgtk_win32_2_0_la_SOURCES = $(gtk_c_sources)

View File

@@ -132,6 +132,7 @@
#include <gtk/gtkpixmap.h>
#include <gtk/gtkplug.h>
#include <gtk/gtkpreview.h>
#include <gtk/gtkprintoperation.h>
#include <gtk/gtkprogress.h>
#include <gtk/gtkprogressbar.h>
#include <gtk/gtkradioaction.h>

View File

@@ -466,6 +466,46 @@ typedef enum
GTK_PACK_DIRECTION_BTT
} GtkPackDirection;
typedef enum {
GTK_PRINT_PAGES_ALL,
GTK_PRINT_PAGES_CURRENT,
GTK_PRINT_PAGES_RANGES
} GtkPrintPages;
typedef enum {
GTK_PAGE_SET_ALL,
GTK_PAGE_SET_EVEN,
GTK_PAGE_SET_ODD
} GtkPageSet;
typedef enum {
GTK_PAGE_ORIENTATION_PORTRAIT,
GTK_PAGE_ORIENTATION_LANDSCAPE,
GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT,
GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE
} GtkPageOrientation;
typedef enum {
GTK_PRINT_QUALITY_LOW,
GTK_PRINT_QUALITY_NORMAL,
GTK_PRINT_QUALITY_HIGH,
GTK_PRINT_QUALITY_DRAFT
} GtkPrintQuality;
typedef enum {
GTK_PRINT_DUPLEX_SIMPLEX,
GTK_PRINT_DUPLEX_HORIZONTAL,
GTK_PRINT_DUPLEX_VERTICAL
} GtkPrintDuplex;
typedef enum {
GTK_UNIT_PIXEL,
GTK_UNIT_POINTS,
GTK_UNIT_INCH,
GTK_UNIT_MM
} GtkUnit;
G_END_DECLS
#endif /* __GTK_ENUMS_H__ */

View File

@@ -78,6 +78,8 @@ VOID:OBJECT
VOID:OBJECT,BOOLEAN
VOID:OBJECT,BOXED,BOXED
VOID:OBJECT,BOXED,UINT,UINT
VOID:OBJECT,INT
VOID:OBJECT,INT,OBJECT
VOID:OBJECT,INT,INT
VOID:OBJECT,INT,INT,BOXED,UINT,UINT
VOID:OBJECT,OBJECT

281
gtk/gtkpagesetup.c Normal file
View File

@@ -0,0 +1,281 @@
/* GTK - The GIMP Toolkit
* gtkpagesetup.c: Page Setup
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gtkpagesetup.h"
#define MM_PER_INCH 25.4
#define POINTS_PER_INCH 72
typedef struct _GtkPageSetupClass GtkPageSetupClass;
#define GTK_IS_PAGE_SETUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PAGE_SETUP))
#define GTK_PAGE_SETUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PAGE_SETUP, GtkPageSetupClass))
#define GTK_PAGE_SETUP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PAGE_SETUP, GtkPageSetupClass))
struct _GtkPageSetup
{
GObject parent_instance;
GtkPageOrientation orientation;
GtkPaperSize *paper_size;
/* These are stored in mm */
double top_margin, bottom_margin, left_margin, right_margin;
};
struct _GtkPageSetupClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE (GtkPageSetup, gtk_page_setup, G_TYPE_OBJECT)
static double
to_mm (double len, GtkUnit unit)
{
switch (unit)
{
case GTK_UNIT_MM:
return len;
case GTK_UNIT_INCH:
return len * MM_PER_INCH;
default:
case GTK_UNIT_PIXEL:
g_warning ("Unsupported unit");
/* Fall through */
case GTK_UNIT_POINTS:
return len * (MM_PER_INCH / POINTS_PER_INCH);
break;
}
}
static double
from_mm (double len, GtkUnit unit)
{
switch (unit)
{
case GTK_UNIT_MM:
return len;
case GTK_UNIT_INCH:
return len / MM_PER_INCH;
default:
case GTK_UNIT_PIXEL:
g_warning ("Unsupported unit");
/* Fall through */
case GTK_UNIT_POINTS:
return len / (MM_PER_INCH / POINTS_PER_INCH);
break;
}
}
static void
gtk_page_setup_finalize (GObject *object)
{
GtkPageSetup *setup = GTK_PAGE_SETUP (object);
gtk_paper_size_free (setup->paper_size);
G_OBJECT_CLASS (gtk_page_setup_parent_class)->finalize (object);
}
static void
gtk_page_setup_init (GtkPageSetup *setup)
{
setup->paper_size = gtk_paper_size_new (NULL);
setup->orientation = GTK_PAGE_ORIENTATION_PORTRAIT;
setup->top_margin = gtk_paper_size_get_default_top_margin (setup->paper_size, GTK_UNIT_MM);
setup->bottom_margin = gtk_paper_size_get_default_bottom_margin (setup->paper_size, GTK_UNIT_MM);
setup->left_margin = gtk_paper_size_get_default_left_margin (setup->paper_size, GTK_UNIT_MM);
setup->right_margin = gtk_paper_size_get_default_right_margin (setup->paper_size, GTK_UNIT_MM);
}
static void
gtk_page_setup_class_init (GtkPageSetupClass *class)
{
GObjectClass *gobject_class = (GObjectClass *)class;
gobject_class->finalize = gtk_page_setup_finalize;
}
GtkPageSetup *
gtk_page_setup_new (void)
{
return g_object_new (GTK_TYPE_PAGE_SETUP, NULL);
}
GtkPageSetup *
gtk_page_setup_copy (GtkPageSetup *other)
{
GtkPageSetup *copy;
copy = gtk_page_setup_new ();
copy->orientation = other->orientation;
copy->paper_size = gtk_paper_size_copy (other->paper_size);
copy->top_margin = other->top_margin;
copy->bottom_margin = other->bottom_margin;
copy->left_margin = other->left_margin;
copy->right_margin = other->right_margin;
return copy;
}
GtkPageOrientation
gtk_page_setup_get_orientation (GtkPageSetup *setup)
{
return setup->orientation;
}
void
gtk_page_setup_set_orientation (GtkPageSetup *setup,
GtkPageOrientation orientation)
{
setup->orientation = orientation;
}
GtkPaperSize *
gtk_page_setup_get_paper_size (GtkPageSetup *setup)
{
return setup->paper_size;
}
void
gtk_page_setup_set_paper_size (GtkPageSetup *setup,
GtkPaperSize *size)
{
setup->paper_size = gtk_paper_size_copy (size);
}
void
gtk_page_setup_set_paper_size_and_default_margins (GtkPageSetup *setup,
GtkPaperSize *size)
{
setup->paper_size = gtk_paper_size_copy (size);
setup->top_margin = gtk_paper_size_get_default_top_margin (setup->paper_size, GTK_UNIT_MM);
setup->bottom_margin = gtk_paper_size_get_default_bottom_margin (setup->paper_size, GTK_UNIT_MM);
setup->left_margin = gtk_paper_size_get_default_left_margin (setup->paper_size, GTK_UNIT_MM);
setup->right_margin = gtk_paper_size_get_default_right_margin (setup->paper_size, GTK_UNIT_MM);
}
double
gtk_page_setup_get_top_margin (GtkPageSetup *setup,
GtkUnit unit)
{
return from_mm (setup->top_margin, unit);
}
void
gtk_page_setup_set_top_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit)
{
setup->top_margin = to_mm (margin, unit);
}
double
gtk_page_setup_get_bottom_margin (GtkPageSetup *setup,
GtkUnit unit)
{
return from_mm (setup->bottom_margin, unit);
}
void
gtk_page_setup_set_bottom_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit)
{
setup->bottom_margin = to_mm (margin, unit);
}
double
gtk_page_setup_get_left_margin (GtkPageSetup *setup,
GtkUnit unit)
{
return from_mm (setup->left_margin, unit);
}
void
gtk_page_setup_set_left_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit)
{
setup->left_margin = to_mm (margin, unit);
}
double
gtk_page_setup_get_right_margin (GtkPageSetup *setup,
GtkUnit unit)
{
return from_mm (setup->right_margin, unit);
}
void
gtk_page_setup_set_right_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit)
{
setup->right_margin = to_mm (margin, unit);
}
/* These take orientation, but not margins into consideration */
double
gtk_page_setup_get_paper_width (GtkPageSetup *setup,
GtkUnit unit)
{
if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
return gtk_paper_size_get_width (setup->paper_size, unit);
else
return gtk_paper_size_get_height (setup->paper_size, unit);
}
double
gtk_page_setup_get_paper_height (GtkPageSetup *setup,
GtkUnit unit)
{
if (setup->orientation == GTK_PAGE_ORIENTATION_PORTRAIT ||
setup->orientation == GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT)
return gtk_paper_size_get_height (setup->paper_size, unit);
else
return gtk_paper_size_get_width (setup->paper_size, unit);
}
/* These take orientation, and margins into consideration */
double
gtk_page_setup_get_page_width (GtkPageSetup *setup,
GtkUnit unit)
{
double width;
width = gtk_page_setup_get_paper_width (setup, GTK_UNIT_MM);
width -= setup->left_margin + setup->right_margin;
return from_mm (width, unit);
}
double
gtk_page_setup_get_page_height (GtkPageSetup *setup,
GtkUnit unit)
{
double height;
height = gtk_page_setup_get_paper_height (setup, GTK_UNIT_MM);
height -= setup->top_margin + setup->bottom_margin;
return from_mm (height, unit);
}

85
gtk/gtkpagesetup.h Normal file
View File

@@ -0,0 +1,85 @@
/* EGG - The GIMP Toolkit
* gtkpagesetup.h: Page Setup
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PAGE_SETUP_H__
#define __GTK_PAGE_SETUP_H__
#include <glib-object.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkpapersize.h>
G_BEGIN_DECLS
typedef struct _GtkPageSetup GtkPageSetup;
#define GTK_TYPE_PAGE_SETUP (gtk_page_setup_get_type ())
#define GTK_PAGE_SETUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PAGE_SETUP, GtkPageSetup))
#define GTK_IS_PAGE_SETUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PAGE_SETUP))
GType gtk_page_setup_get_type (void);
GtkPageSetup * gtk_page_setup_new (void);
GtkPageSetup * gtk_page_setup_copy (GtkPageSetup *other);
GtkPageOrientation gtk_page_setup_get_orientation (GtkPageSetup *setup);
void gtk_page_setup_set_orientation (GtkPageSetup *setup,
GtkPageOrientation orientation);
GtkPaperSize * gtk_page_setup_get_paper_size (GtkPageSetup *setup);
void gtk_page_setup_set_paper_size (GtkPageSetup *setup,
GtkPaperSize *size);
double gtk_page_setup_get_top_margin (GtkPageSetup *setup,
GtkUnit unit);
void gtk_page_setup_set_top_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit);
double gtk_page_setup_get_bottom_margin (GtkPageSetup *setup,
GtkUnit unit);
void gtk_page_setup_set_bottom_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit);
double gtk_page_setup_get_left_margin (GtkPageSetup *setup,
GtkUnit unit);
void gtk_page_setup_set_left_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit);
double gtk_page_setup_get_right_margin (GtkPageSetup *setup,
GtkUnit unit);
void gtk_page_setup_set_right_margin (GtkPageSetup *setup,
double margin,
GtkUnit unit);
void gtk_page_setup_set_paper_size_and_default_margins (GtkPageSetup *setup,
GtkPaperSize *size);
/* These take orientation, but not margins into consideration */
double gtk_page_setup_get_paper_width (GtkPageSetup *setup,
GtkUnit unit);
double gtk_page_setup_get_paper_height (GtkPageSetup *setup,
GtkUnit unit);
/* These take orientation, and margins into consideration */
double gtk_page_setup_get_page_width (GtkPageSetup *setup,
GtkUnit unit);
double gtk_page_setup_get_page_height (GtkPageSetup *setup,
GtkUnit unit);
G_END_DECLS
#endif /* __GTK_PAGE_SETUP_H__ */

1875
gtk/gtkpagesetupunixdialog.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,74 @@
/* GtkPageSetupUnixDialog
* Copyright (C) 2006 Alexander Larsson <alexl@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PAGE_SETUP_UNIX_DIALOG_H__
#define __GTK_PAGE_SETUP_UNIX_DIALOG_H__
#include <gtk/gtk.h>
#include "gtkpagesetup.h"
#include "gtkprintsettings.h"
G_BEGIN_DECLS
#define GTK_TYPE_PAGE_SETUP_UNIX_DIALOG (gtk_page_setup_unix_dialog_get_type ())
#define GTK_PAGE_SETUP_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PAGE_SETUP_UNIX_DIALOG, GtkPageSetupUnixDialog))
#define GTK_PAGE_SETUP_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PAGE_SETUP_UNIX_DIALOG, GtkPageSetupUnixDialogClass))
#define GTK_IS_PAGE_SETUP_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PAGE_SETUP_UNIX_DIALOG))
#define GTK_IS_PAGE_SETUP_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PAGE_SETUP_UNIX_DIALOG))
#define GTK_PAGE_SETUP_UNIX_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PAGE_SETUP_UNIX_DIALOG, GtkPageSetupUnixDialogClass))
typedef struct _GtkPageSetupUnixDialog GtkPageSetupUnixDialog;
typedef struct _GtkPageSetupUnixDialogClass GtkPageSetupUnixDialogClass;
typedef struct GtkPageSetupUnixDialogPrivate GtkPageSetupUnixDialogPrivate;
struct _GtkPageSetupUnixDialog
{
GtkDialog parent_instance;
GtkPageSetupUnixDialogPrivate *priv;
};
struct _GtkPageSetupUnixDialogClass
{
GtkDialogClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
};
GType gtk_page_setup_unix_dialog_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_page_setup_unix_dialog_new (const gchar *title,
GtkWindow *parent);
void gtk_page_setup_unix_dialog_set_page_setup (GtkPageSetupUnixDialog *dialog,
GtkPageSetup *page_setup);
GtkPageSetup * gtk_page_setup_unix_dialog_get_page_setup (GtkPageSetupUnixDialog *dialog);
void gtk_page_setup_unix_dialog_set_print_settings (GtkPageSetupUnixDialog *dialog,
GtkPrintSettings *print_settings);
GtkPrintSettings *gtk_page_setup_unix_dialog_get_print_settings (GtkPageSetupUnixDialog *dialog);
G_END_DECLS
#endif /* __GTK_PAGE_SETUP_UNIX_DIALOG_H__ */

533
gtk/gtkpapersize.c Normal file
View File

@@ -0,0 +1,533 @@
/* GTK - The GIMP Toolkit
* gtkpapersize.c: Paper Size
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include <locale.h>
#include <langinfo.h>
#include "gtkpapersize.h"
#define MM_PER_INCH 25.4
#define POINTS_PER_INCH 72
typedef struct
{
const char *name;
const char *size;
const char *display_name;
const char *ppd_name;
} PaperInfo;
struct _GtkPaperSize
{
const PaperInfo *info;
/* If these are not set we fall back to info */
char *name;
char *display_name;
char *ppd_name;
double width, height; /* Stored in mm */
gboolean is_custom;
};
#include "paper_names.c"
GType
gtk_paper_size_get_type (void)
{
static GType our_type = 0;
if (our_type == 0)
our_type = g_boxed_type_register_static ("GtkPaperSize",
(GBoxedCopyFunc)gtk_paper_size_copy,
(GBoxedFreeFunc)gtk_paper_size_free);
return our_type;
}
static int
paper_info_compare (const void *_a, const void *_b)
{
const PaperInfo *a = _a;
const PaperInfo *b = _b;
return strcmp (a->name, b->name);
}
static PaperInfo *
lookup_paper_info (const char *name)
{
PaperInfo key;
PaperInfo *info;
key.name = name;
info = bsearch (&key, standard_names, G_N_ELEMENTS (standard_names),
sizeof (PaperInfo), paper_info_compare);
return info;
}
static double
to_mm (double len, GtkUnit unit)
{
switch (unit)
{
case GTK_UNIT_MM:
return len;
case GTK_UNIT_INCH:
return len * MM_PER_INCH;
default:
case GTK_UNIT_PIXEL:
g_warning ("Unsupported unit");
/* Fall through */
case GTK_UNIT_POINTS:
return len * (MM_PER_INCH / POINTS_PER_INCH);
break;
}
}
static double
from_mm (double len, GtkUnit unit)
{
switch (unit)
{
case GTK_UNIT_MM:
return len;
case GTK_UNIT_INCH:
return len / MM_PER_INCH;
default:
case GTK_UNIT_PIXEL:
g_warning ("Unsupported unit");
/* Fall through */
case GTK_UNIT_POINTS:
return len / (MM_PER_INCH / POINTS_PER_INCH);
break;
}
}
static gboolean
parse_media_size (const char *size,
double *width_mm, double *height_mm)
{
const char *p;
char *e;
double short_dim, long_dim;
p = size;
short_dim = g_ascii_strtod (p, &e);
if (p == e || *e != 'x')
return FALSE;
p = e + 1; /* Skip x */
long_dim = g_ascii_strtod (p, &e);
if (p == e)
return FALSE;
p = e;
if (strcmp (p, "in") == 0)
{
short_dim = short_dim * MM_PER_INCH;
long_dim = long_dim * MM_PER_INCH;
}
else if (strcmp (p, "mm") != 0)
return FALSE;
if (width_mm)
*width_mm = short_dim;
if (height_mm)
*height_mm = long_dim;
return TRUE;
}
static gboolean
parse_full_media_size_name (const char *full_name,
char **name,
double *width_mm, double *height_mm)
{
const char *p;
const char *end_of_name;
/* From the spec:
media-size-self-describing-name =
( class-in "_" size-name "_" short-dim "x" long-dim "in" ) |
( class-mm "_" size-name "_" short-dim "x" long-dim "mm" )
class-in = "custom" | "na" | "asme" | "roc" | "oe"
class-mm = "custom" | "iso" | "jis" | "jpn" | "prc" | "om"
size-name = ( lowalpha | digit ) *( lowalpha | digit | "-" )
short-dim = dim
long-dim = dim
dim = integer-part [fraction-part] | "0" fraction-part
integer-part = non-zero-digit *digit
fraction-part = "." *digit non-zero-digit
lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
"j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
"s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
non-zero-digit = "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
*/
p = strchr (full_name, '_');
if (p == NULL)
return FALSE;
p++; /* Skip _ */
p = strchr (p, '_');
if (p == NULL)
return FALSE;
end_of_name = p;
p++; /* Skip _ */
if (!parse_media_size (p, width_mm, height_mm))
return FALSE;
if (name)
*name = g_strndup (full_name, end_of_name - full_name);
return TRUE;
}
static GtkPaperSize *
gtk_paper_size_new_from_info (const PaperInfo *info)
{
GtkPaperSize *size;
size = g_new0 (GtkPaperSize, 1);
size->info = info;
parse_media_size (info->size, &size->width, &size->height);
return size;
}
GtkPaperSize *
gtk_paper_size_new (const char *name)
{
GtkPaperSize *size;
char *short_name;
double width, height;
PaperInfo *info;
if (name == NULL)
name = gtk_paper_size_get_default ();
if (parse_full_media_size_name (name, &short_name, &width, &height))
{
size = g_new0 (GtkPaperSize, 1);
size->width = width;
size->height = height;
size->name = short_name;
size->display_name = g_strdup (short_name);
}
else
{
info = lookup_paper_info (name);
if (info != NULL)
size = gtk_paper_size_new_from_info (info);
else
{
g_warning ("Unknown paper size %s\n", name);
size = g_new0 (GtkPaperSize, 1);
size->name = g_strdup (name);
size->display_name = g_strdup (name);
/* Default to A4 size */
size->width = 210;
size->height = 297;
}
}
return size;
}
GtkPaperSize *
gtk_paper_size_new_from_ppd (const char *ppd_name,
const char *ppd_display_name,
double width,
double height)
{
char *name;
GtkPaperSize *size;
int i;
for (i = 0; i < G_N_ELEMENTS(standard_names); i++)
{
if (standard_names[i].ppd_name != NULL &&
strcmp (standard_names[i].ppd_name, ppd_name) == 0)
return gtk_paper_size_new_from_info (&standard_names[i]);
}
for (i = 0; i < G_N_ELEMENTS(extra_ppd_names); i++)
{
if (strcmp (extra_ppd_names[i].ppd_name, ppd_name) == 0)
{
size = gtk_paper_size_new (extra_ppd_names[i].standard_name);
size->ppd_name = g_strdup (ppd_name);
return size;
}
}
name = g_strdup_printf ("ppd_%s", ppd_name);
size = gtk_paper_size_new_custom (name, ppd_display_name, width, height, GTK_UNIT_POINTS);
g_free (name);
size->ppd_name = g_strdup (ppd_name);
return size;
}
GtkPaperSize *
gtk_paper_size_new_custom (const char *name, const char *display_name,
double width, double height, GtkUnit unit)
{
GtkPaperSize *size;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (unit != GTK_UNIT_PIXEL, NULL);
size = g_new0 (GtkPaperSize, 1);
size->name = g_strdup (name);
size->display_name = g_strdup (display_name);
size->is_custom = TRUE;
/* Width is always the shorter one */
if (width > height)
{
double t = width;
width = height;
height = t;
}
size->width = to_mm (width, unit);
size->height = to_mm (height, unit);
return size;
}
GtkPaperSize *
gtk_paper_size_copy (GtkPaperSize *other)
{
GtkPaperSize *size;
size = g_new0 (GtkPaperSize, 1);
size->info = other->info;
if (other->name)
size->name = g_strdup (other->name);
if (other->display_name)
size->display_name = g_strdup (other->display_name);
if (other->ppd_name)
size->ppd_name = g_strdup (other->ppd_name);
size->width = other->width;
size->height = other->height;
size->is_custom = other->is_custom;
return size;
}
void
gtk_paper_size_free (GtkPaperSize *size)
{
g_free (size->name);
g_free (size->display_name);
g_free (size->ppd_name);
g_free (size);
}
gboolean
gtk_paper_size_is_equal (GtkPaperSize *size1,
GtkPaperSize *size2)
{
if (size1->info != NULL && size2->info != NULL)
return size1->info == size2->info;
return strcmp (gtk_paper_size_get_name (size1),
gtk_paper_size_get_name (size2)) == 0;
}
G_CONST_RETURN char *
gtk_paper_size_get_name (GtkPaperSize *size)
{
if (size->name)
return size->name;
g_assert (size->info != NULL);
return size->info->name;
}
G_CONST_RETURN char *
gtk_paper_size_get_display_name (GtkPaperSize *size)
{
if (size->display_name)
return size->display_name;
g_assert (size->info != NULL);
return size->info->display_name;
}
G_CONST_RETURN char *
gtk_paper_size_get_ppd_name (GtkPaperSize *size)
{
if (size->ppd_name)
return size->ppd_name;
if (size->info)
return size->info->ppd_name;
return NULL;
}
double
gtk_paper_size_get_width (GtkPaperSize *size, GtkUnit unit)
{
return from_mm (size->width, unit);
}
double
gtk_paper_size_get_height (GtkPaperSize *size, GtkUnit unit)
{
return from_mm (size->height, unit);
}
gboolean
gtk_paper_size_is_custom (GtkPaperSize *size)
{
return size->is_custom;
}
/* Only for custom sizes: */
void
gtk_paper_size_set_size (GtkPaperSize *size, double width, double height, GtkUnit unit)
{
g_return_if_fail (size != NULL);
g_return_if_fail (size->is_custom);
/* Width is always the shorter one */
if (width > height)
{
double t = width;
width = height;
height = t;
}
size->width = to_mm (width, unit);
size->height = to_mm (height, unit);
}
#define NL_PAPER_GET(x) \
((union { char *string; unsigned int word; })nl_langinfo(x)).word
G_CONST_RETURN char *
gtk_paper_size_get_default (void)
{
char *locale;
#if defined(HAVE__NL_PAPER_HEIGHT) && defined(HAVE__NL_PAPER_WIDTH)
{
int width = NL_PAPER_GET (_NL_PAPER_WIDTH);
int height = NL_PAPER_GET (_NL_PAPER_HEIGHT);
if (width == 210 && height == 297)
return GTK_PAPER_NAME_A4;
if (width == 216 && height == 279)
return GTK_PAPER_NAME_LETTER;
}
#endif
#ifdef LC_PAPER
locale = setlocale(LC_PAPER, NULL);
#else
locale = setlocale(LC_MESSAGES, NULL);
#endif
if (g_str_has_prefix (locale, "en_CA") ||
g_str_has_prefix (locale, "en_US") ||
g_str_has_prefix (locale, "es_PR") ||
g_str_has_prefix (locale, "es_US"))
return GTK_PAPER_NAME_LETTER;
return GTK_PAPER_NAME_A4;
}
/* These get the default margins used for the paper size. Its
* larger than most printers margins, so that it will be within
* the imageble area on any printer.
*
* I've taken the actual values used from the OSX page setup dialog.
* I'm not sure exactly where they got these values for, but might
* correspond to this (from ghostscript docs):
*
* All DeskJets have 0.5 inches (1.27cm) of unprintable bottom margin,
* due to the mechanical arrangement used to grab the paper. Side margins
* are approximately 0.25 inches (0.64cm) for U.S. letter paper, and 0.15
* inches (0.38cm) for A4.
*/
double
gtk_paper_size_get_default_top_margin (GtkPaperSize *size, GtkUnit unit)
{
double margin;
margin = to_mm (0.25, GTK_UNIT_INCH);
return from_mm (margin, unit);
}
double
gtk_paper_size_get_default_bottom_margin (GtkPaperSize *size, GtkUnit unit)
{
double margin;
const char *name;
margin = to_mm (0.25, GTK_UNIT_INCH);
name = gtk_paper_size_get_name (size);
if (strcmp (name, "na_letter") == 0 ||
strcmp (name, "na_legal") == 0 ||
strcmp (name, "iso_a4") == 0)
margin = to_mm (0.56, GTK_UNIT_INCH);
return from_mm (margin, unit);
}
double
gtk_paper_size_get_default_left_margin (GtkPaperSize *size, GtkUnit unit)
{
double margin;
margin = to_mm (0.25, GTK_UNIT_INCH);
return from_mm (margin, unit);
}
double
gtk_paper_size_get_default_right_margin (GtkPaperSize *size, GtkUnit unit)
{
double margin;
margin = to_mm (0.25, GTK_UNIT_INCH);
return from_mm (margin, unit);
}

85
gtk/gtkpapersize.h Normal file
View File

@@ -0,0 +1,85 @@
/* EGG - The GIMP Toolkit
* gtkpapersize.h: Paper Size
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PAPER_SIZE_H__
#define __GTK_PAPER_SIZE_H__
#include <glib-object.h>
#include <gtk/gtkenums.h>
G_BEGIN_DECLS
typedef struct _GtkPaperSize GtkPaperSize;
#define GTK_TYPE_PAPER_SIZE (gtk_paper_size_get_type ())
/* Common names, from PWG 5101.1-2002 PWG: Standard for Media Standardized Names */
#define GTK_PAPER_NAME_A3 "iso_a3"
#define GTK_PAPER_NAME_A4 "iso_a4"
#define GTK_PAPER_NAME_A5 "iso_a5"
#define GTK_PAPER_NAME_B5 "iso_b5"
#define GTK_PAPER_NAME_LETTER "na_letter"
#define GTK_PAPER_NAME_EXECUTIVE "na_executive"
#define GTK_PAPER_NAME_LEGAL "na_legal"
GType gtk_paper_size_get_type (void);
GtkPaperSize *gtk_paper_size_new (const char *name);
GtkPaperSize *gtk_paper_size_new_from_ppd (const char *ppd_name,
const char *ppd_display_name,
double width,
double height);
GtkPaperSize *gtk_paper_size_new_custom (const char *name,
const char *display_name,
double width,
double height,
GtkUnit unit);
GtkPaperSize *gtk_paper_size_copy (GtkPaperSize *other);
void gtk_paper_size_free (GtkPaperSize *size);
gboolean gtk_paper_size_is_equal (GtkPaperSize *size1,
GtkPaperSize *size2);
/* The width is always the shortest side, measure in mm */
G_CONST_RETURN char * gtk_paper_size_get_name (GtkPaperSize *size);
G_CONST_RETURN char * gtk_paper_size_get_display_name (GtkPaperSize *size);
G_CONST_RETURN char * gtk_paper_size_get_ppd_name (GtkPaperSize *size);
double gtk_paper_size_get_width (GtkPaperSize *size, GtkUnit unit);
double gtk_paper_size_get_height (GtkPaperSize *size, GtkUnit unit);
gboolean gtk_paper_size_is_custom (GtkPaperSize *size);
/* Only for custom sizes: */
void gtk_paper_size_set_size (GtkPaperSize *size, double width, double height, GtkUnit unit);
double gtk_paper_size_get_default_top_margin (GtkPaperSize *size,
GtkUnit unit);
double gtk_paper_size_get_default_bottom_margin (GtkPaperSize *size,
GtkUnit unit);
double gtk_paper_size_get_default_left_margin (GtkPaperSize *size,
GtkUnit unit);
double gtk_paper_size_get_default_right_margin (GtkPaperSize *size,
GtkUnit unit);
G_CONST_RETURN char * gtk_paper_size_get_default (void);
G_END_DECLS
#endif /* __GTK_PAPER_SIZE_H__ */

107
gtk/gtkprint-win32.c Normal file
View File

@@ -0,0 +1,107 @@
/* GTK - The GIMP Toolkit
* gtkprintoperation.c: Print Operation
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef _MSC_VER
#define _WIN32_WINNT 0x0500
#define WINVER _WIN32_WINNT
#endif
#include "gtkprint-win32.h"
void
gtk_print_win32_devnames_free (GtkPrintWin32Devnames *devnames)
{
g_free (devnames->driver);
g_free (devnames->device);
g_free (devnames->output);
g_free (devnames);
}
GtkPrintWin32Devnames *
gtk_print_win32_devnames_from_win32 (HGLOBAL global)
{
LPDEVNAMES win = GlobalLock (global);
gunichar2 *data = (gunichar2 *)win;
GtkPrintWin32Devnames *devnames = g_new (GtkPrintWin32Devnames, 1);
devnames->driver = g_utf16_to_utf8 (data + win->wDriverOffset,
-1, NULL, NULL, NULL);
devnames->device = g_utf16_to_utf8 (data + win->wDeviceOffset,
-1, NULL, NULL, NULL);
devnames->output = g_utf16_to_utf8 (data + win->wOutputOffset,
-1, NULL, NULL, NULL);
devnames->flags = win->wDefault;
GlobalUnlock (global);
return devnames;
}
HGLOBAL
gtk_print_win32_devnames_to_win32 (const GtkPrintWin32Devnames *devnames)
{
HGLOBAL global;
LPDEVNAMES windevnames;
gunichar2 *data;
gunichar2 *driver, *device, *output;
glong driver_len, device_len, output_len;
int i;
driver = g_utf8_to_utf16 (devnames->driver, -1, NULL, &driver_len, NULL);
device = g_utf8_to_utf16 (devnames->device, -1, NULL, &device_len, NULL);
output = g_utf8_to_utf16 (devnames->output, -1, NULL, &output_len, NULL);
global = GlobalAlloc (GMEM_MOVEABLE,
sizeof (DEVNAMES) +
(driver_len + 1) * 2 +
(device_len + 1) * 2 +
(output_len + 1) * 2);
windevnames = GlobalLock (global);
data = (gunichar2 *)windevnames;
i = sizeof(DEVNAMES) / sizeof (gunichar2);
windevnames->wDriverOffset = i;
memcpy (data + i, driver, (driver_len + 1) * sizeof (gunichar2));
i += driver_len + 1;
windevnames->wDeviceOffset = i;
memcpy (data + i, device, (device_len + 1) * sizeof (gunichar2));
i += device_len + 1;
windevnames->wOutputOffset = i;
memcpy (data + i, output, (output_len + 1) * sizeof (gunichar2));
i += output_len + 1;
windevnames->wDefault = devnames->flags;
GlobalUnlock (global);
g_free (driver);
g_free (device);
g_free (output);
return global;
}
HGLOBAL
gtk_print_win32_devnames_from_printer_name (const char *printer)
{
const GtkPrintWin32Devnames devnames = { "", (char *)printer, "", 0 };
return gtk_print_win32_devnames_to_win32 (&devnames);
}

65
gtk/gtkprint-win32.h Normal file
View File

@@ -0,0 +1,65 @@
/* EGG - The GIMP Toolkit
* gtkprint-win32.h: Win32 Print utils
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_WIN32_H__
#define __GTK_PRINT_WIN32_H__
#ifndef _MSC_VER
#define _WIN32_WINNT 0x0500
#define WINVER _WIN32_WINNT
#endif
#include <gdk/gdkwin32.h>
G_BEGIN_DECLS
#ifndef START_PAGE_GENERAL
#define START_PAGE_GENERAL 0xffffffff
#endif
#ifndef PD_RESULT_CANCEL
#define PD_RESULT_CANCEL 0
#define PD_RESULT_PRINT 1
#define PD_RESULT_APPLY 2
#endif
#ifndef PD_NOCURRENTPAGE
#define PD_NOCURRENTPAGE 0x00800000
#endif
#ifndef PD_CURRENTPAGE
#define PD_CURRENTPAGE 0x00400000
#endif
typedef struct {
char *driver;
char *device;
char *output;
int flags;
} GtkPrintWin32Devnames;
void gtk_print_win32_devnames_free (GtkPrintWin32Devnames *devnames);
GtkPrintWin32Devnames *gtk_print_win32_devnames_from_win32 (HGLOBAL global);
HGLOBAL gtk_print_win32_devnames_to_win32 (const GtkPrintWin32Devnames *devnames);
HGLOBAL gtk_print_win32_devnames_from_printer_name (const char *printer);
G_END_DECLS
#endif /* __GTK_PRINT_WIN32_H__ */

458
gtk/gtkprintbackend.c Normal file
View File

@@ -0,0 +1,458 @@
/* GTK - The GIMP Toolkit
* gtkprintbackend.h: Abstract printer backend interfaces
* Copyright (C) 2003, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <gmodule.h>
#include "gtkintl.h"
#include <gtk/gtkprivate.h>
#include "gtkprintbackend.h"
#include <string.h>
static void gtk_print_backend_base_init (gpointer g_class);
GQuark
gtk_print_backend_error_quark (void)
{
static GQuark quark = 0;
if (quark == 0)
quark = g_quark_from_static_string ("gtk-print-backend-error-quark");
return quark;
}
/*****************************************
* GtkPrintBackendModule modules *
*****************************************/
typedef struct _GtkPrintBackendModule GtkPrintBackendModule;
typedef struct _GtkPrintBackendModuleClass GtkPrintBackendModuleClass;
struct _GtkPrintBackendModule
{
GTypeModule parent_instance;
GModule *library;
void (*init) (GTypeModule *module);
void (*exit) (void);
GtkPrintBackend* (*create) (void);
gchar *path;
};
struct _GtkPrintBackendModuleClass
{
GTypeModuleClass parent_class;
};
G_DEFINE_TYPE (GtkPrintBackendModule, _gtk_print_backend_module, G_TYPE_TYPE_MODULE);
#define GTK_TYPE_PRINT_BACKEND_MODULE (_gtk_print_backend_module_get_type ())
#define GTK_PRINT_BACKEND_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_PRINT_BACKEND_MODULE, GtkPrintBackendModule))
static GSList *loaded_backends;
static gboolean
gtk_print_backend_module_load (GTypeModule *module)
{
GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module);
gpointer initp, exitp, createp;
pb_module->library = g_module_open (pb_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
if (!pb_module->library)
{
g_warning (g_module_error());
return FALSE;
}
/* extract symbols from the lib */
if (!g_module_symbol (pb_module->library, "pb_module_init",
&initp) ||
!g_module_symbol (pb_module->library, "pb_module_exit",
&exitp) ||
!g_module_symbol (pb_module->library, "pb_module_create",
&createp))
{
g_warning (g_module_error());
g_module_close (pb_module->library);
return FALSE;
}
pb_module->init = initp;
pb_module->exit = exitp;
pb_module->create = createp;
/* call the filesystems's init function to let it */
/* setup anything it needs to set up. */
pb_module->init (module);
return TRUE;
}
static void
gtk_print_backend_module_unload (GTypeModule *module)
{
GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module);
pb_module->exit();
g_module_close (pb_module->library);
pb_module->library = NULL;
pb_module->init = NULL;
pb_module->exit = NULL;
pb_module->create = NULL;
}
/* This only will ever be called if an error occurs during
* initialization
*/
static void
gtk_print_backend_module_finalize (GObject *object)
{
GtkPrintBackendModule *module = GTK_PRINT_BACKEND_MODULE (object);
g_free (module->path);
G_OBJECT_CLASS (_gtk_print_backend_module_parent_class)->finalize (object);
}
static void
_gtk_print_backend_module_class_init (GtkPrintBackendModuleClass *class)
{
GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
module_class->load = gtk_print_backend_module_load;
module_class->unload = gtk_print_backend_module_unload;
gobject_class->finalize = gtk_print_backend_module_finalize;
}
static void
_gtk_print_backend_module_init (GtkPrintBackendModule *pb_module)
{
}
static GtkPrintBackend *
_gtk_print_backend_module_create (GtkPrintBackendModule *pb_module)
{
GtkPrintBackend *pb;
if (g_type_module_use (G_TYPE_MODULE (pb_module)))
{
pb = pb_module->create ();
g_type_module_unuse (G_TYPE_MODULE (pb_module));
return pb;
}
return NULL;
}
/* Like g_module_path, but use .la as the suffix
*/
static gchar*
module_build_la_path (const gchar *directory,
const gchar *module_name)
{
gchar *filename;
gchar *result;
if (strncmp (module_name, "lib", 3) == 0)
filename = (gchar *)module_name;
else
filename = g_strconcat ("libgtkprintbackend", module_name, ".la", NULL);
if (directory && *directory)
result = g_build_filename (directory, filename, NULL);
else
result = g_strdup (filename);
if (filename != module_name)
g_free (filename);
return result;
}
GtkPrintBackend *
_gtk_print_backend_create (const char *backend_name)
{
GSList *l;
char *module_path;
GtkPrintBackendModule *pb_module;
GtkPrintBackend *pb;
/* TODO: make module loading code work */
for (l = loaded_backends; l != NULL; l = l->next)
{
pb_module = l->data;
if (strcmp (G_TYPE_MODULE (pb_module)->name, backend_name) == 0)
return _gtk_print_backend_module_create (pb_module);
}
pb = NULL;
if (g_module_supported ())
{
module_path = _gtk_find_module (backend_name, "printbackends");
if (module_path)
{
pb_module = g_object_new (GTK_TYPE_PRINT_BACKEND_MODULE, NULL);
g_type_module_set_name (G_TYPE_MODULE (pb_module), backend_name);
pb_module->path = g_strdup (module_path);
loaded_backends = g_slist_prepend (loaded_backends,
pb_module);
pb = _gtk_print_backend_module_create (pb_module);
}
g_free (module_path);
}
return pb;
return NULL;
}
static GList *
property_parse_list (const gchar *string)
{
GScanner *scanner;
gboolean success = FALSE;
gboolean need_closing_brace = FALSE;
GList *results = NULL;
scanner = gtk_rc_scanner_new ();
g_scanner_input_text (scanner, string, strlen (string));
g_scanner_get_next_token (scanner);
if (scanner->token == G_TOKEN_LEFT_CURLY)
{
need_closing_brace = TRUE;
g_scanner_get_next_token (scanner);
}
while (scanner->token != G_TOKEN_EOF && scanner->token != G_TOKEN_RIGHT_CURLY)
{
if (scanner->token == G_TOKEN_STRING)
{
results = g_list_append (results, g_strdup (scanner->value.v_string));
}
else if (scanner->token == G_TOKEN_IDENTIFIER)
{
results = g_list_append (results, g_strdup (scanner->value.v_identifier));
}
else if (scanner->token == G_TOKEN_COMMA)
{
/* noop */
}
else
goto err;
g_scanner_get_next_token (scanner);
}
if (scanner->token == G_TOKEN_RIGHT_CURLY && need_closing_brace)
success = TRUE;
if (scanner->token == G_TOKEN_RIGHT_CURLY && !need_closing_brace)
success = TRUE;
err:
if (!success)
if (results)
{
g_list_free (results);
results = NULL;
}
g_scanner_destroy (scanner);
return results;
}
static void
gtk_print_backend_initialize (void)
{
static gboolean initialized = FALSE;
if (!initialized)
{
gtk_settings_install_property (g_param_spec_string ("gtk-print-backends",
P_("Default print backend"),
P_("List of the GtkPrintBackend backends to use by default"),
"{\"pdf\", \"cups\"}",
GTK_PARAM_READWRITE));
initialized = TRUE;
}
}
GList *
gtk_print_backend_load_modules ()
{
GList *result;
GtkPrintBackend *backend;
gchar * s_backend_list;
GList *backend_list, *node;
GtkSettings *settings;
result = NULL;
gtk_print_backend_initialize ();
settings = gtk_settings_get_default ();
g_object_get (settings, "gtk-print-backends", &s_backend_list, NULL);
backend_list = property_parse_list (s_backend_list);
node = backend_list;
while (node)
{
g_message ("node: %s", (char *)node->data);
backend = _gtk_print_backend_create ((char *)node->data);
if (backend)
result = g_list_append (result, backend);
node = node->next;
}
g_free (s_backend_list);
if (backend_list)
g_list_free (backend_list);
return result;
}
/*****************************************
* GtkPrintBackend *
*****************************************/
GType
gtk_print_backend_get_type (void)
{
static GType print_backend_type = 0;
if (!print_backend_type)
{
static const GTypeInfo print_backend_info =
{
sizeof (GtkPrintBackendIface), /* class_size */
gtk_print_backend_base_init, /* base_init */
NULL, /* base_finalize */
};
print_backend_type = g_type_register_static (G_TYPE_INTERFACE,
"GtkPrintBackend",
&print_backend_info, 0);
g_type_interface_add_prerequisite (print_backend_type, G_TYPE_OBJECT);
}
return print_backend_type;
}
static void
gtk_print_backend_base_init (gpointer g_class)
{
static gboolean initialized = FALSE;
if (!initialized)
{
GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
g_signal_new ("printer-list-changed",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_list_changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_signal_new ("printer-added",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_added),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
g_signal_new ("printer-removed",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_removed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
g_signal_new ("printer-status-changed",
iface_type,
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintBackendIface, printer_status_changed),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, G_TYPE_OBJECT);
initialized = TRUE;
}
}
GList *
gtk_print_backend_get_printer_list (GtkPrintBackend *print_backend)
{
g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL);
return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->get_printer_list (print_backend);
}
GtkPrinter *
gtk_print_backend_find_printer (GtkPrintBackend *print_backend,
const gchar *printer_name)
{
g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL);
return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->find_printer (print_backend, printer_name);
}
void
gtk_print_backend_print_stream (GtkPrintBackend *print_backend,
GtkPrintJob *job,
const gchar *title,
gint data_fd,
GtkPrintJobCompleteFunc callback,
gpointer user_data)
{
g_return_if_fail (GTK_IS_PRINT_BACKEND (print_backend));
return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->print_stream (print_backend,
job,
title,
data_fd,
callback,
user_data);
}

123
gtk/gtkprintbackend.h Normal file
View File

@@ -0,0 +1,123 @@
/* GTK - The GIMP Toolkit
* gtkprintbackend.h: Abstract printer backend interfaces
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_BACKEND_H__
#define __GTK_PRINT_BACKEND_H__
/* This is a "semi-private" header; it is meant only for
* alternate GtkPrintDialog backend modules; no stability guarantees
* are made at this point
*/
#ifndef GTK_PRINT_BACKEND_ENABLE_UNSUPPORTED
#error "GtkPrintBackend is not supported API for general use"
#endif
#include <glib-object.h>
#include <gtk/gtk.h>
#include <cairo.h>
#include <gtk/gtkprinter-private.h>
#include <gtk/gtkprintsettings.h>
#include <gtk/gtkprinteroption.h>
#include <gtk/gtkprintjob.h>
G_BEGIN_DECLS
typedef struct _GtkPrintBackendIface GtkPrintBackendIface;
#define GTK_PRINT_BACKEND_ERROR (gtk_print_backend_error_quark ())
typedef enum
{
/* TODO: add specific errors */
GTK_PRINT_BACKEND_ERROR_GENERIC
} GtkPrintBackendError;
GQuark gtk_print_backend_error_quark (void);
#define GTK_TYPE_PRINT_BACKEND (gtk_print_backend_get_type ())
#define GTK_PRINT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_BACKEND, GtkPrintBackend))
#define GTK_IS_PRINT_BACKEND(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_BACKEND))
#define GTK_PRINT_BACKEND_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_PRINT_BACKEND, GtkPrintBackendIface))
struct _GtkPrintBackendIface
{
GTypeInterface base_iface;
/* Global backend methods: */
GList * (*get_printer_list) (GtkPrintBackend *printer_backend);
GtkPrinter * (*find_printer) (GtkPrintBackend *print_backend,
const gchar *printer_name);
void (*print_stream) (GtkPrintBackend *print_backend,
GtkPrintJob *job,
const gchar *title,
gint data_fd,
GtkPrintJobCompleteFunc callback,
gpointer user_data);
/* Printer methods: */
void (*printer_request_details) (GtkPrinter *printer);
cairo_surface_t * (*printer_create_cairo_surface) (GtkPrinter *printer,
gdouble height,
gdouble width,
gint cache_fd);
GtkPrinterOptionSet * (*printer_get_options) (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup);
gboolean (*printer_mark_conflicts) (GtkPrinter *printer,
GtkPrinterOptionSet *options);
void (*printer_get_settings_from_options) (GtkPrinter *printer,
GtkPrinterOptionSet *options,
GtkPrintSettings *settings);
void (*printer_prepare_for_print) (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup);
GList * (*printer_list_papers) (GtkPrinter *printer);
void (*printer_get_hard_margins) (GtkPrinter *printer,
double *top,
double *bottom,
double *left,
double *right);
/* Signals
*/
void (*printer_list_changed) (void);
void (*printer_added) (GtkPrinter *printer);
void (*printer_removed) (GtkPrinter *printer);
void (*printer_status_changed) (GtkPrinter *printer);
};
GType gtk_print_backend_get_type (void) G_GNUC_CONST;
GList *gtk_print_backend_get_printer_list (GtkPrintBackend *print_backend);
GtkPrinter *gtk_print_backend_find_printer (GtkPrintBackend *print_backend,
const gchar *printer_name);
void gtk_print_backend_print_stream (GtkPrintBackend *print_backend,
GtkPrintJob *job,
const gchar *title,
gint data_fd,
GtkPrintJobCompleteFunc callback,
gpointer user_data);
GList * gtk_print_backend_load_modules (void);
G_END_DECLS
#endif /* __GTK_PRINT_BACKEND_H__ */

288
gtk/gtkprintcontext.c Normal file
View File

@@ -0,0 +1,288 @@
/* GTK - The GIMP Toolkit
* gtkprintcontext.c: Print Context
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gtkprintoperation-private.h"
typedef struct _GtkPrintContextClass GtkPrintContextClass;
#define GTK_IS_PRINT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_CONTEXT))
#define GTK_PRINT_CONTEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))
#define GTK_PRINT_CONTEXT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_CONTEXT, GtkPrintContextClass))
#define MM_PER_INCH 25.4
#define POINTS_PER_INCH 72
struct _GtkPrintContext
{
GObject parent_instance;
GtkPrintOperation *op;
cairo_t *cr;
GtkPageSetup *page_setup;
PangoFontMap *fontmap;
double pixels_per_unit_x, pixels_per_unit_y;
};
struct _GtkPrintContextClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE (GtkPrintContext, gtk_print_context, G_TYPE_OBJECT)
static void
gtk_print_context_finalize (GObject *object)
{
GtkPrintContext *context = GTK_PRINT_CONTEXT (object);
g_object_unref (context->fontmap);
if (context->page_setup)
g_object_unref (context->page_setup);
cairo_destroy (context->cr);
G_OBJECT_CLASS (gtk_print_context_parent_class)->finalize (object);
}
static void
gtk_print_context_init (GtkPrintContext *context)
{
}
static void
gtk_print_context_class_init (GtkPrintContextClass *class)
{
GObjectClass *gobject_class = (GObjectClass *)class;
gobject_class->finalize = gtk_print_context_finalize;
}
GtkPrintContext *
_gtk_print_context_new (GtkPrintOperation *op)
{
GtkPrintContext *context;
context = g_object_new (GTK_TYPE_PRINT_CONTEXT, NULL);
context->op = op;
context->cr = cairo_create (op->priv->surface);
switch (op->priv->unit)
{
default:
case GTK_UNIT_PIXEL:
/* Do nothing, this is the cairo default unit */
context->pixels_per_unit_x = 1.0;
context->pixels_per_unit_y = 1.0;
break;
case GTK_UNIT_POINTS:
context->pixels_per_unit_x = op->priv->dpi_x / POINTS_PER_INCH;
context->pixels_per_unit_y = op->priv->dpi_y / POINTS_PER_INCH;
break;
case GTK_UNIT_INCH:
context->pixels_per_unit_x = op->priv->dpi_x;
context->pixels_per_unit_y = op->priv->dpi_y;
break;
case GTK_UNIT_MM:
context->pixels_per_unit_x = op->priv->dpi_x / MM_PER_INCH;
context->pixels_per_unit_y = op->priv->dpi_y / MM_PER_INCH;
break;
}
cairo_scale (context->cr,
context->pixels_per_unit_x,
context->pixels_per_unit_y);
context->fontmap = pango_cairo_font_map_new ();
/* We use the unit-scaled resolution, as we still want fonts given in points to work */
pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (context->fontmap),
op->priv->dpi_y / context->pixels_per_unit_y);
return context;
}
void
_gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context)
{
cairo_t *cr = context->cr;
cairo_matrix_t matrix;
GtkPaperSize *paper_size;
double width, height;
paper_size = gtk_page_setup_get_paper_size (context->page_setup);
width = gtk_paper_size_get_width (paper_size, GTK_UNIT_INCH);
width = width * context->op->priv->dpi_x / context->pixels_per_unit_x;
height = gtk_paper_size_get_height (paper_size, GTK_UNIT_INCH);
height = height * context->op->priv->dpi_y / context->pixels_per_unit_y;
switch (gtk_page_setup_get_orientation (context->page_setup))
{
default:
case GTK_PAGE_ORIENTATION_PORTRAIT:
break;
case GTK_PAGE_ORIENTATION_LANDSCAPE:
cairo_translate (cr, width, 0);
cairo_matrix_init (&matrix,
0, 1,
-1, 0,
0, 0);
cairo_transform (cr, &matrix);
break;
case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
cairo_translate (cr, width, height);
cairo_matrix_init (&matrix,
-1, 0,
0, -1,
0, 0);
cairo_transform (cr, &matrix);
break;
case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
cairo_translate (cr, 0, height);
cairo_matrix_init (&matrix,
0, -1,
1, 0,
0, 0);
cairo_transform (cr, &matrix);
break;
}
}
void
_gtk_print_context_translate_into_margin (GtkPrintContext *context)
{
double left, top;
g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
/* We do it this way to also handle GTK_UNIT_PIXELS */
left = gtk_page_setup_get_left_margin (context->page_setup, GTK_UNIT_INCH);
top = gtk_page_setup_get_top_margin (context->page_setup, GTK_UNIT_INCH);
cairo_translate (context->cr,
left * context->op->priv->dpi_x / context->pixels_per_unit_x,
top * context->op->priv->dpi_y / context->pixels_per_unit_y);
}
void
_gtk_print_context_set_page_setup (GtkPrintContext *context,
GtkPageSetup *page_setup)
{
g_return_if_fail (GTK_IS_PRINT_CONTEXT (context));
g_return_if_fail (page_setup == NULL ||
GTK_IS_PAGE_SETUP (page_setup));
g_object_ref (page_setup);
if (context->page_setup != NULL)
g_object_unref (context->page_setup);
context->page_setup = page_setup;
}
cairo_t *
gtk_print_context_get_cairo (GtkPrintContext *context)
{
return context->cr;
}
GtkPageSetup *
gtk_print_context_get_page_setup (GtkPrintContext *context)
{
return context->page_setup;
}
double
gtk_print_context_get_width (GtkPrintContext *context)
{
double width;
if (context->op->priv->use_full_page)
width = gtk_page_setup_get_paper_width (context->page_setup, GTK_UNIT_INCH);
else
width = gtk_page_setup_get_page_width (context->page_setup, GTK_UNIT_INCH);
/* Really dpi_x? What about landscape? what does dpi_x mean in that case? */
return width * context->op->priv->dpi_x / context->pixels_per_unit_x;
}
double
gtk_print_context_get_height (GtkPrintContext *context)
{
double height;
if (context->op->priv->use_full_page)
height = gtk_page_setup_get_paper_height (context->page_setup, GTK_UNIT_INCH);
else
height = gtk_page_setup_get_page_height (context->page_setup, GTK_UNIT_INCH);
/* Really dpi_x? What about landscape? what does dpi_x mean in that case? */
return height * context->op->priv->dpi_y / context->pixels_per_unit_y;
}
double
gtk_print_context_get_dpi_x (GtkPrintContext *context)
{
return context->op->priv->dpi_x;
}
double
gtk_print_context_get_dpi_y (GtkPrintContext *context)
{
return context->op->priv->dpi_y;
}
/* Fonts */
PangoFontMap *
gtk_print_context_get_fontmap (GtkPrintContext *context)
{
return context->fontmap;
}
PangoContext *
gtk_print_context_create_context (GtkPrintContext *context)
{
PangoContext *pango_context;
pango_context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (context->fontmap));
return pango_context;
}
PangoLayout *
gtk_print_context_create_layout (GtkPrintContext *context)
{
PangoContext *pango_context;
PangoLayout *layout;
g_return_val_if_fail (context != NULL, NULL);
pango_context = gtk_print_context_create_context (context);
layout = pango_layout_new (pango_context);
pango_cairo_update_context (context->cr, pango_context);
g_object_unref (pango_context);
return layout;
}

58
gtk/gtkprintcontext.h Normal file
View File

@@ -0,0 +1,58 @@
/* EGG - The GIMP Toolkit
* gtkprintcontext.h: Print Context
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_CONTEXT_H__
#define __GTK_PRINT_CONTEXT_H__
#include <glib-object.h>
#include <pango/pango-layout.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkpagesetup.h>
G_BEGIN_DECLS
typedef struct _GtkPrintContext GtkPrintContext;
#define GTK_TYPE_PRINT_CONTEXT (gtk_print_context_get_type ())
#define GTK_PRINT_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_CONTEXT, GtkPrintContext))
#define GTK_IS_PRINT_CONTEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_CONTEXT))
GType gtk_print_context_get_type (void);
/* Rendering */
cairo_t * gtk_print_context_get_cairo (GtkPrintContext *context);
GtkPageSetup *gtk_print_context_get_page_setup (GtkPrintContext *context);
double gtk_print_context_get_width (GtkPrintContext *context);
double gtk_print_context_get_height (GtkPrintContext *context);
double gtk_print_context_get_dpi_x (GtkPrintContext *context);
double gtk_print_context_get_dpi_y (GtkPrintContext *context);
/* Fonts */
PangoFontMap *gtk_print_context_get_fontmap (GtkPrintContext *context);
PangoContext *gtk_print_context_create_context (GtkPrintContext *context);
PangoLayout * gtk_print_context_create_layout (GtkPrintContext *context);
G_END_DECLS
#endif /* __GTK_PRINT_CONTEXT_H__ */

76
gtk/gtkprinter-private.h Normal file
View File

@@ -0,0 +1,76 @@
/* EGG - The GIMP Toolkit
* gtkprintoperation.h: Print Operation
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINTER_PRIVATE_H__
#define __GTK_PRINTER_PRIVATE_H__
#include <glib.h>
#include "gtkprinter.h"
#include "gtkprintsettings.h"
#include "gtkprinteroptionset.h"
#include "gtkpagesetup.h"
G_BEGIN_DECLS
struct _GtkPrinterPrivate
{
gchar *name;
gchar *location;
gchar *description;
gchar *icon_name;
guint is_active: 1;
guint is_new: 1;
guint is_virtual : 1;
guint has_details: 1;
gchar *state_message;
gint job_count;
GtkPrintBackend *backend;
};
gboolean _gtk_printer_has_details (GtkPrinter *printer);
void _gtk_printer_request_details (GtkPrinter *printer);
GtkPrinterOptionSet *_gtk_printer_get_options (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup);
gboolean _gtk_printer_mark_conflicts (GtkPrinter *printer,
GtkPrinterOptionSet *options);
void _gtk_printer_get_settings_from_options (GtkPrinter *printer,
GtkPrinterOptionSet *options,
GtkPrintSettings *settings);
void _gtk_printer_prepare_for_print (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup);
cairo_surface_t * _gtk_printer_create_cairo_surface (GtkPrinter *printer,
gdouble width,
gdouble height,
gint cache_fd);
GList * _gtk_printer_list_papers (GtkPrinter *printer);
void _gtk_printer_get_hard_margins (GtkPrinter *printer,
double *top,
double *bottom,
double *left,
double *right);
GHashTable * _gtk_printer_get_custom_widgets (GtkPrinter *printer);
G_END_DECLS
#endif /* __GTK_PRINT_OPERATION_PRIVATE_H__ */

403
gtk/gtkprinter.c Normal file
View File

@@ -0,0 +1,403 @@
/* GtkPrinter
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "gtkintl.h"
#include <gtk/gtk.h>
#include <gtk/gtkprivate.h>
#include "gtkprinter.h"
#include "gtkprinter-private.h"
#include "gtkprintbackend.h"
#include "gtkprintjob.h"
#define GTK_PRINTER_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINTER, GtkPrinterPrivate))
static void gtk_printer_finalize (GObject *object);
enum {
DETAILS_ACQUIRED,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_NAME,
PROP_STATE_MESSAGE,
PROP_LOCATION,
PROP_ICON_NAME,
PROP_JOB_COUNT
};
static guint signals[LAST_SIGNAL] = { 0 };
static void gtk_printer_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_printer_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
G_DEFINE_TYPE (GtkPrinter, gtk_printer, G_TYPE_OBJECT);
static void
gtk_printer_class_init (GtkPrinterClass *class)
{
GObjectClass *object_class;
object_class = (GObjectClass *) class;
object_class->finalize = gtk_printer_finalize;
object_class->set_property = gtk_printer_set_property;
object_class->get_property = gtk_printer_get_property;
g_type_class_add_private (class, sizeof (GtkPrinterPrivate));
g_object_class_install_property (G_OBJECT_CLASS (class),
PROP_NAME,
g_param_spec_string ("name",
P_("Name"),
P_("Name of the printer job"),
NULL,
GTK_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (class),
PROP_STATE_MESSAGE,
g_param_spec_string ("state-message",
P_("State Message"),
P_("String giving the current state of the printer"),
NULL,
GTK_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (class),
PROP_LOCATION,
g_param_spec_string ("location",
P_("Location"),
P_("The location of the printer"),
NULL,
GTK_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (class),
PROP_ICON_NAME,
g_param_spec_string ("icon-name",
P_("Icon Name"),
P_("The icon name to use for the printer"),
NULL,
GTK_PARAM_READABLE));
g_object_class_install_property (G_OBJECT_CLASS (class),
PROP_JOB_COUNT,
g_param_spec_int ("job-count",
P_("Job Count"),
P_("Number of jobs queued in the printer"),
0,
G_MAXINT,
0,
GTK_PARAM_READABLE));
signals[DETAILS_ACQUIRED] =
g_signal_new ("details-acquired",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrinterClass, details_acquired),
NULL, NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
}
static void
gtk_printer_init (GtkPrinter *printer)
{
printer->priv = GTK_PRINTER_GET_PRIVATE (printer);
printer->priv->name = NULL;
printer->priv->location = NULL;
printer->priv->description = NULL;
printer->priv->icon_name = NULL;
printer->priv->is_active = TRUE;
printer->priv->is_new = TRUE;
printer->priv->has_details = FALSE;
printer->priv->state_message = NULL;
printer->priv->job_count = 0;
}
static void
gtk_printer_finalize (GObject *object)
{
g_return_if_fail (object != NULL);
GtkPrinter *printer = GTK_PRINTER (object);
g_free (printer->priv->name);
g_free (printer->priv->location);
g_free (printer->priv->description);
g_free (printer->priv->state_message);
g_free (printer->priv->icon_name);
if (G_OBJECT_CLASS (gtk_printer_parent_class)->finalize)
G_OBJECT_CLASS (gtk_printer_parent_class)->finalize (object);
}
static void
gtk_printer_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
/* No writable properties */
}
static void
gtk_printer_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPrinter *printer = GTK_PRINTER (object);
switch (prop_id)
{
case PROP_NAME:
if (printer->priv->name)
g_value_set_string (value, printer->priv->name);
else
g_value_set_string (value, "");
break;
case PROP_STATE_MESSAGE:
if (printer->priv->state_message)
g_value_set_string (value, printer->priv->state_message);
else
g_value_set_string (value, "");
break;
case PROP_LOCATION:
if (printer->priv->location)
g_value_set_string (value, printer->priv->location);
else
g_value_set_string (value, "");
break;
case PROP_ICON_NAME:
if (printer->priv->icon_name)
g_value_set_string (value, printer->priv->icon_name);
else
g_value_set_string (value, "");
break;
case PROP_JOB_COUNT:
g_value_set_int (value, printer->priv->job_count);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
/**
* gtk_printer_new:
*
* Creates a new #GtkPrinter.
*
* Return value: a new #GtkPrinter
*
* Since: 2.8
**/
GtkPrinter *
gtk_printer_new (void)
{
GObject *result;
result = g_object_new (GTK_TYPE_PRINTER,
NULL);
return (GtkPrinter *) result;
}
GtkPrintBackend *
gtk_printer_get_backend (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
return printer->priv->backend;
}
const gchar *
gtk_printer_get_name (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
return printer->priv->name;
}
const gchar *
gtk_printer_get_state_message (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
return printer->priv->state_message;
}
const gchar *
gtk_printer_get_location (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
return printer->priv->location;
}
const gchar *
gtk_printer_get_icon_name (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
return printer->priv->icon_name;
}
gint
gtk_printer_get_job_count (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), 0);
return printer->priv->job_count;
}
gboolean
_gtk_printer_has_details (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
return printer->priv->has_details;
}
gboolean
gtk_printer_is_active (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
return printer->priv->is_active;
}
gboolean
gtk_printer_is_virtual (GtkPrinter *printer)
{
g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
return printer->priv->is_virtual;
}
GtkPrintJob *
gtk_printer_prep_job (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup,
const gchar *title,
GError **error)
{
GtkPrintJob *job;
job = gtk_print_job_new (title,
settings,
page_setup,
printer);
if (!gtk_print_job_prep (job, error))
{
g_object_unref (G_OBJECT (job));
job = NULL;
}
return job;
}
void
_gtk_printer_request_details (GtkPrinter *printer)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
return backend_iface->printer_request_details (printer);
}
GtkPrinterOptionSet *
_gtk_printer_get_options (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
return backend_iface->printer_get_options (printer, settings, page_setup);
}
gboolean
_gtk_printer_mark_conflicts (GtkPrinter *printer,
GtkPrinterOptionSet *options)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
return backend_iface->printer_mark_conflicts (printer, options);
}
void
_gtk_printer_get_settings_from_options (GtkPrinter *printer,
GtkPrinterOptionSet *options,
GtkPrintSettings *settings)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
return backend_iface->printer_get_settings_from_options (printer, options, settings);
}
void
_gtk_printer_prepare_for_print (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
return backend_iface->printer_prepare_for_print (printer, settings, page_setup);
}
cairo_surface_t *
_gtk_printer_create_cairo_surface (GtkPrinter *printer,
gdouble width,
gdouble height,
gint cache_fd)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
return backend_iface->printer_create_cairo_surface (printer, width, height, cache_fd);
}
GList *
_gtk_printer_list_papers (GtkPrinter *printer)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
return backend_iface->printer_list_papers (printer);
}
void
_gtk_printer_get_hard_margins (GtkPrinter *printer,
double *top,
double *bottom,
double *left,
double *right)
{
GtkPrintBackendIface *backend_iface = GTK_PRINT_BACKEND_GET_IFACE (printer->priv->backend);
backend_iface->printer_get_hard_margins (printer, top, bottom, left, right);
}

89
gtk/gtkprinter.h Normal file
View File

@@ -0,0 +1,89 @@
/* GtkPrinter
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINTER_H__
#define __GTK_PRINTER_H__
#include <glib-object.h>
#include <cairo.h>
#include "gtkprintsettings.h"
#include "gtkpagesetup.h"
G_BEGIN_DECLS
#define GTK_TYPE_PRINTER (gtk_printer_get_type ())
#define GTK_PRINTER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINTER, GtkPrinter))
#define GTK_PRINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINTER, GtkPrinterClass))
#define GTK_IS_PRINTER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINTER))
#define GTK_IS_PRINTER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINTER))
#define GTK_PRINTER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINTER, GtkPrinterClass))
typedef struct _GtkPrinter GtkPrinter;
typedef struct _GtkPrinterClass GtkPrinterClass;
typedef struct _GtkPrinterPrivate GtkPrinterPrivate;
typedef struct _GtkPrintBackend GtkPrintBackend;
typedef struct _GtkPrintJob GtkPrintJob;
struct _GtkPrintBackend;
struct _GtkPrintJob;
struct _GtkPrinter
{
GObject parent_instance;
GtkPrinterPrivate *priv;
};
struct _GtkPrinterClass
{
GObjectClass parent_class;
void (*details_acquired) (GtkPrinter *printer, gboolean success);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
};
GType gtk_printer_get_type (void) G_GNUC_CONST;
GtkPrinter *gtk_printer_new (void);
GtkPrintBackend *gtk_printer_get_backend (GtkPrinter *printer);
const gchar *gtk_printer_get_name (GtkPrinter *printer);
const gchar *gtk_printer_get_state_message (GtkPrinter *printer);
const gchar *gtk_printer_get_location (GtkPrinter *printer);
const gchar *gtk_printer_get_icon_name (GtkPrinter *printer);
gint gtk_printer_get_job_count (GtkPrinter *printer);
gboolean gtk_printer_is_active (GtkPrinter *printer);
gboolean gtk_printer_is_virtual (GtkPrinter *printer);
GtkPrintJob *gtk_printer_prep_job (GtkPrinter *printer,
GtkPrintSettings *settings,
GtkPageSetup *page_setup,
const gchar *title,
GError **error);
G_END_DECLS
#endif /* __GTK_PRINTER_H__ */

198
gtk/gtkprinteroption.c Normal file
View File

@@ -0,0 +1,198 @@
/* GTK - The GIMP Toolkit
* gtkprinteroption.c: Handling possible settings for a specific printer setting
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <gmodule.h>
#include <string.h>
#include "gtkprinteroption.h"
/*****************************************
* GtkPrinterOption *
*****************************************/
enum {
CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GtkPrinterOption, gtk_printer_option, G_TYPE_OBJECT)
static void
gtk_printer_option_finalize (GObject *object)
{
GtkPrinterOption *option = GTK_PRINTER_OPTION (object);
int i;
g_free (option->name);
g_free (option->display_text);
g_free (option->value);
for (i = 0; i < option->num_choices; i++)
{
g_free (option->choices[i]);
g_free (option->choices_display[i]);
}
g_free (option->choices);
g_free (option->choices_display);
g_free (option->group);
G_OBJECT_CLASS (gtk_printer_option_parent_class)->finalize (object);
}
static void
gtk_printer_option_init (GtkPrinterOption *option)
{
}
static void
gtk_printer_option_class_init (GtkPrinterOptionClass *class)
{
GObjectClass *gobject_class = (GObjectClass *)class;
gobject_class->finalize = gtk_printer_option_finalize;
signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrinterOptionClass, changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
GtkPrinterOption *
gtk_printer_option_new (const char *name, const char *display_text,
GtkPrinterOptionType type)
{
GtkPrinterOption *option;
option = g_object_new (GTK_TYPE_PRINTER_OPTION, NULL);
option->name = g_strdup (name);
option->display_text = g_strdup (display_text);
option->type = type;
return option;
}
static void
emit_changed (GtkPrinterOption *option)
{
g_signal_emit (option, signals[CHANGED], 0);
}
void
gtk_printer_option_set (GtkPrinterOption *option,
const char *value)
{
if ((option->value == NULL && value == NULL) ||
(option->value != NULL && value != NULL &&
strcmp (option->value, value) == 0))
return;
if (option->type == GTK_PRINTER_OPTION_TYPE_PICKONE &&
value != NULL)
{
int i;
for (i = 0; i < option->num_choices; i++)
{
if (g_ascii_strcasecmp (value, option->choices[i]) == 0)
{
value = option->choices[i];
break;
}
}
if (i == option->num_choices)
return; /* Not found in availible choices */
}
g_free (option->value);
option->value = g_strdup (value);
emit_changed (option);
}
void
gtk_printer_option_set_boolean (GtkPrinterOption *option,
gboolean value)
{
gtk_printer_option_set (option, value ? "True" : "False");
}
void
gtk_printer_option_set_has_conflict (GtkPrinterOption *option,
gboolean has_conflict)
{
has_conflict = has_conflict != 0;
if (option->has_conflict == has_conflict)
return;
option->has_conflict = has_conflict;
emit_changed (option);
}
void
gtk_printer_option_clear_has_conflict (GtkPrinterOption *option)
{
gtk_printer_option_set_has_conflict (option, FALSE);
}
void
gtk_printer_option_allocate_choices (GtkPrinterOption *option,
int num)
{
g_free (option->choices);
g_free (option->choices_display);
option->num_choices = num;
if (num == 0)
{
option->choices = NULL;
option->choices_display = NULL;
}
else
{
option->choices = g_new0 (char *, num);
option->choices_display = g_new0 (char *, num);
}
}
void
gtk_printer_option_choices_from_array (GtkPrinterOption *option,
int num_choices,
char *choices[],
char *choices_display[])
{
int i;
gtk_printer_option_allocate_choices (option, num_choices);
for (i = 0; i < num_choices; i++)
{
option->choices[i] = g_strdup (choices[i]);
option->choices_display[i] = g_strdup (choices_display[i]);
}
}

111
gtk/gtkprinteroption.h Normal file
View File

@@ -0,0 +1,111 @@
/* GTK - The GIMP Toolkit
* gtkprinteroption.h: printer option
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINTER_OPTION_H__
#define __GTK_PRINTER_OPTION_H__
/* This is a "semi-private" header; it is meant only for
* alternate GtkPrintDialog backend modules; no stability guarantees
* are made at this point
*/
#ifndef GTK_PRINT_BACKEND_ENABLE_UNSUPPORTED
#error "GtkPrintBackend is not supported API for general use"
#endif
#include <glib-object.h>
G_BEGIN_DECLS
#define GTK_TYPE_PRINTER_OPTION (gtk_printer_option_get_type ())
#define GTK_PRINTER_OPTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINTER_OPTION, GtkPrinterOption))
#define GTK_IS_PRINTER_OPTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINTER_OPTION))
typedef struct _GtkPrinterOption GtkPrinterOption;
typedef struct _GtkPrinterOptionClass GtkPrinterOptionClass;
#define GTK_PRINTER_OPTION_GROUP_IMAGE_QUALITY "ImageQuality"
#define GTK_PRINTER_OPTION_GROUP_FINISHING "Finishing"
typedef enum {
GTK_PRINTER_OPTION_TYPE_BOOLEAN,
GTK_PRINTER_OPTION_TYPE_PICKONE,
GTK_PRINTER_OPTION_TYPE_STRING,
GTK_PRINTER_OPTION_TYPE_FILESAVE
} GtkPrinterOptionType;
struct _GtkPrinterOption
{
GObject parent_instance;
char *name;
char *display_text;
GtkPrinterOptionType type;
char *value;
int num_choices;
char **choices;
char **choices_display;
gboolean has_conflict;
char *group;
};
struct _GtkPrinterOptionClass
{
GObjectClass parent_class;
void (*changed) (GtkPrinterOption *option);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
};
GType gtk_printer_option_get_type (void) G_GNUC_CONST;
GtkPrinterOption *gtk_printer_option_new (const char *name,
const char *display_text,
GtkPrinterOptionType type);
void gtk_printer_option_set (GtkPrinterOption *setting,
const char *value);
void gtk_printer_option_set_has_conflict (GtkPrinterOption *setting,
gboolean has_conflict);
void gtk_printer_option_clear_has_conflict (GtkPrinterOption *setting);
void gtk_printer_option_set_boolean (GtkPrinterOption *setting,
gboolean value);
void gtk_printer_option_allocate_choices (GtkPrinterOption *setting,
int num);
void gtk_printer_option_choices_from_array (GtkPrinterOption *setting,
int num_choices,
char *choices[],
char *choices_display[]);
G_END_DECLS
#endif /* __GTK_PRINTER_OPTION_H__ */

198
gtk/gtkprinteroptionset.c Normal file
View File

@@ -0,0 +1,198 @@
/* GTK - The GIMP Toolkit
* gtkprintbackend.h: Abstract printer backend interfaces
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <gmodule.h>
#include <glib.h>
#include <string.h>
#include "gtkprinteroptionset.h"
/*****************************************
* GtkPrinterOptionSet *
*****************************************/
enum {
CHANGED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GtkPrinterOptionSet, gtk_printer_option_set, G_TYPE_OBJECT)
static void
gtk_printer_option_set_finalize (GObject *object)
{
GtkPrinterOptionSet *set = GTK_PRINTER_OPTION_SET (object);
g_hash_table_destroy (set->hash);
g_ptr_array_foreach (set->array, (GFunc)g_object_unref, NULL);
g_ptr_array_free (set->array, TRUE);
G_OBJECT_CLASS (gtk_printer_option_set_parent_class)->finalize (object);
}
static void
gtk_printer_option_set_init (GtkPrinterOptionSet *set)
{
set->array = g_ptr_array_new ();
set->hash = g_hash_table_new (g_str_hash, g_str_equal);
}
static void
gtk_printer_option_set_class_init (GtkPrinterOptionSetClass *class)
{
GObjectClass *gobject_class = (GObjectClass *)class;
gobject_class->finalize = gtk_printer_option_set_finalize;
signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrinterOptionSetClass, changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
}
static void
emit_changed (GtkPrinterOptionSet *set)
{
g_signal_emit (set, signals[CHANGED], 0);
}
GtkPrinterOptionSet *
gtk_printer_option_set_new (void)
{
return g_object_new (GTK_TYPE_PRINTER_OPTION_SET, NULL);
}
void
gtk_printer_option_set_remove (GtkPrinterOptionSet *set,
GtkPrinterOption *option)
{
int i;
for (i = 0; i < set->array->len; i++)
{
if (g_ptr_array_index (set->array, i) == option)
{
g_ptr_array_remove_index (set->array, i);
g_hash_table_remove (set->hash, option->name);
g_signal_handlers_disconnect_by_func (option, emit_changed, set);
g_object_unref (option);
break;
}
}
}
void
gtk_printer_option_set_add (GtkPrinterOptionSet *set,
GtkPrinterOption *option)
{
g_object_ref (option);
if (gtk_printer_option_set_lookup (set, option->name))
gtk_printer_option_set_remove (set, option);
g_ptr_array_add (set->array, option);
g_hash_table_insert (set->hash, option->name, option);
g_signal_connect_object (option, "changed", G_CALLBACK (emit_changed), set, G_CONNECT_SWAPPED);
}
GtkPrinterOption *
gtk_printer_option_set_lookup (GtkPrinterOptionSet *set,
const char *name)
{
gpointer ptr;
ptr = g_hash_table_lookup (set->hash, name);
return GTK_PRINTER_OPTION (ptr);
}
void
gtk_printer_option_set_clear_conflicts (GtkPrinterOptionSet *set)
{
gtk_printer_option_set_foreach (set,
(GtkPrinterOptionSetFunc)gtk_printer_option_clear_has_conflict,
NULL);
}
static int
safe_strcmp (const char *a, const char *b)
{
if (a == NULL)
a = "";
if (b == NULL)
b = "";
return strcmp (a, b);
}
GList *
gtk_printer_option_set_get_groups (GtkPrinterOptionSet *set)
{
GtkPrinterOption *option;
GList *list = NULL;
int i;
for (i = 0; i < set->array->len; i++)
{
option = g_ptr_array_index (set->array, i);
if (g_list_find_custom (list, option->group, (GCompareFunc)safe_strcmp) == NULL)
list = g_list_prepend (list, g_strdup (option->group));
}
return g_list_reverse (list);
}
void
gtk_printer_option_set_foreach_in_group (GtkPrinterOptionSet *set,
const char *group,
GtkPrinterOptionSetFunc func,
gpointer user_data)
{
GtkPrinterOption *option;
int i;
for (i = 0; i < set->array->len; i++)
{
option = g_ptr_array_index (set->array, i);
if (group == NULL ||
(option->group != NULL && strcmp (group, option->group) == 0))
func (option, user_data);
}
}
void
gtk_printer_option_set_foreach (GtkPrinterOptionSet *set,
GtkPrinterOptionSetFunc func,
gpointer user_data)
{
gtk_printer_option_set_foreach_in_group (set, NULL, func, user_data);
}

96
gtk/gtkprinteroptionset.h Normal file
View File

@@ -0,0 +1,96 @@
/* GTK - The GIMP Toolkit
* gtkprinteroptionset.h: printer option set
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINTER_OPTION_SET_H__
#define __GTK_PRINTER_OPTION_SET_H__
/* This is a "semi-private" header; it is meant only for
* alternate GtkPrintDialog backend modules; no stability guarantees
* are made at this point
*/
#ifndef GTK_PRINT_BACKEND_ENABLE_UNSUPPORTED
#error "GtkPrintBackend is not supported API for general use"
#endif
#include <glib-object.h>
#include "gtkprinteroption.h"
G_BEGIN_DECLS
#define GTK_TYPE_PRINTER_OPTION_SET (gtk_printer_option_set_get_type ())
#define GTK_PRINTER_OPTION_SET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINTER_OPTION_SET, GtkPrinterOptionSet))
#define GTK_IS_PRINTER_OPTION_SET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINTER_OPTION_SET))
typedef struct _GtkPrinterOptionSet GtkPrinterOptionSet;
typedef struct _GtkPrinterOptionSetClass GtkPrinterOptionSetClass;
struct _GtkPrinterOptionSet
{
GObject parent_instance;
/*< private >*/
GPtrArray *array;
GHashTable *hash;
};
struct _GtkPrinterOptionSetClass
{
GObjectClass parent_class;
void (*changed) (GtkPrinterOptionSet *option);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
};
typedef void (*GtkPrinterOptionSetFunc) (GtkPrinterOption *option,
gpointer user_data);
GType gtk_printer_option_set_get_type (void) G_GNUC_CONST;
GtkPrinterOptionSet *gtk_printer_option_set_new (void);
void gtk_printer_option_set_add (GtkPrinterOptionSet *set,
GtkPrinterOption *option);
void gtk_printer_option_set_remove (GtkPrinterOptionSet *set,
GtkPrinterOption *option);
GtkPrinterOption * gtk_printer_option_set_lookup (GtkPrinterOptionSet *set,
const char *name);
void gtk_printer_option_set_foreach (GtkPrinterOptionSet *set,
GtkPrinterOptionSetFunc func,
gpointer user_data);
void gtk_printer_option_set_clear_conflicts (GtkPrinterOptionSet *set);
GList * gtk_printer_option_set_get_groups (GtkPrinterOptionSet *set);
void gtk_printer_option_set_foreach_in_group (GtkPrinterOptionSet *set,
const char *group,
GtkPrinterOptionSetFunc func,
gpointer user_data);
G_END_DECLS
#endif /* __GTK_PRINTER_OPTION_SET_H__ */

View File

@@ -0,0 +1,602 @@
/* GtkPrinterOptionWidget
* Copyright (C) 2006 Alexander Larsson <alexl@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "gtkintl.h"
#include <gtk/gtk.h>
#include <gtk/gtkprivate.h>
#include "gtkprinteroptionwidget.h"
#define GTK_PRINTER_OPTION_WIDGET_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINTER_OPTION_WIDGET, GtkPrinterOptionWidgetPrivate))
static void gtk_printer_option_widget_finalize (GObject *object);
static void deconstruct_widgets (GtkPrinterOptionWidget *widget);
static void construct_widgets (GtkPrinterOptionWidget *widget);
static void update_widgets (GtkPrinterOptionWidget *widget);
struct GtkPrinterOptionWidgetPrivate
{
GtkPrinterOption *source;
gulong source_changed_handler;
GtkWidget *check;
GtkWidget *combo;
GtkWidget *entry;
GtkWidget *image;
GtkWidget *label;
GtkWidget *filechooser;
};
enum {
CHANGED,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_SOURCE,
};
static guint signals[LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (GtkPrinterOptionWidget, gtk_printer_option_widget, GTK_TYPE_HBOX);
static void gtk_printer_option_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_printer_option_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void
gtk_printer_option_widget_class_init (GtkPrinterOptionWidgetClass *class)
{
GObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
object_class->finalize = gtk_printer_option_widget_finalize;
object_class->set_property = gtk_printer_option_widget_set_property;
object_class->get_property = gtk_printer_option_widget_get_property;
g_type_class_add_private (class, sizeof (GtkPrinterOptionWidgetPrivate));
signals[CHANGED] =
g_signal_new ("changed",
G_TYPE_FROM_CLASS (class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrinterOptionWidgetClass, changed),
NULL, NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
g_object_class_install_property (object_class,
PROP_SOURCE,
g_param_spec_object ("source",
P_("Source option"),
P_("The PrinterOption backing this widget"),
GTK_TYPE_PRINTER_OPTION,
GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT));
}
static void
gtk_printer_option_widget_init (GtkPrinterOptionWidget *widget)
{
widget->priv = GTK_PRINTER_OPTION_WIDGET_GET_PRIVATE (widget);
}
static void
gtk_printer_option_widget_finalize (GObject *object)
{
GtkPrinterOptionWidget *widget;
widget = GTK_PRINTER_OPTION_WIDGET (object);
if (widget->priv->source)
{
g_object_unref (widget->priv->source);
widget->priv->source = NULL;
}
if (G_OBJECT_CLASS (gtk_printer_option_widget_parent_class)->finalize)
G_OBJECT_CLASS (gtk_printer_option_widget_parent_class)->finalize (object);
}
static void
gtk_printer_option_widget_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPrinterOptionWidget *widget;
widget = GTK_PRINTER_OPTION_WIDGET (object);
switch (prop_id)
{
case PROP_SOURCE:
gtk_printer_option_widget_set_source (widget, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_printer_option_widget_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPrinterOptionWidget *widget;
widget = GTK_PRINTER_OPTION_WIDGET (object);
switch (prop_id)
{
case PROP_SOURCE:
g_value_set_object (value, widget->priv->source);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
emit_changed (GtkPrinterOptionWidget *widget)
{
g_signal_emit (widget, signals[CHANGED], 0);
}
GtkWidget *
gtk_printer_option_widget_new (GtkPrinterOption *source)
{
return g_object_new (GTK_TYPE_PRINTER_OPTION_WIDGET, "source", source, NULL);
}
static void
source_changed_cb (GtkPrinterOption *source,
GtkPrinterOptionWidget *widget)
{
update_widgets (widget);
emit_changed (widget);
}
void
gtk_printer_option_widget_set_source (GtkPrinterOptionWidget *widget,
GtkPrinterOption *source)
{
if (source)
g_object_ref (source);
if (widget->priv->source)
{
g_signal_handler_disconnect (widget->priv->source,
widget->priv->source_changed_handler);
g_object_unref (widget->priv->source);
}
widget->priv->source = source;
if (source)
widget->priv->source_changed_handler =
g_signal_connect (source, "changed", G_CALLBACK (source_changed_cb), widget);
construct_widgets (widget);
update_widgets (widget);
g_object_notify (G_OBJECT (widget), "source");
}
static GtkWidget *
combo_box_new (void)
{
GtkWidget *combo_box;
GtkCellRenderer *cell;
GtkListStore *store;
store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
g_object_unref (store);
cell = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), cell, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), cell,
"text", 0,
NULL);
return combo_box;
}
static void
combo_box_append (GtkWidget *combo,
const char *display_text,
const char *value)
{
GtkTreeModel *model;
GtkListStore *store;
GtkTreeIter iter;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
store = GTK_LIST_STORE (model);
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
0, display_text,
1, value,
-1);
}
struct ComboSet {
GtkComboBox *combo;
const char *value;
};
static gboolean
set_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, gpointer data)
{
struct ComboSet *set_data = data;
gboolean found;
char *value;
gtk_tree_model_get (model, iter, 1, &value, -1);
found = (strcmp (value, set_data->value) == 0);
g_free (value);
if (found)
gtk_combo_box_set_active_iter (set_data->combo, iter);
return found;
}
static void
combo_box_set (GtkWidget *combo,
const char *value)
{
GtkTreeModel *model;
GtkListStore *store;
struct ComboSet set_data;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
store = GTK_LIST_STORE (model);
set_data.combo = GTK_COMBO_BOX (combo);
set_data.value = value;
gtk_tree_model_foreach (model, set_cb, &set_data);
}
static char *
combo_box_get (GtkWidget *combo)
{
GtkTreeModel *model;
char *val;
GtkTreeIter iter;
model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
val = NULL;
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
gtk_tree_model_get (model, &iter,
1, &val,
-1);
return val;
}
static void
deconstruct_widgets (GtkPrinterOptionWidget *widget)
{
if (widget->priv->check)
{
gtk_widget_destroy (widget->priv->check);
widget->priv->check = NULL;
}
if (widget->priv->combo)
{
gtk_widget_destroy (widget->priv->combo);
widget->priv->combo = NULL;
}
if (widget->priv->entry)
{
gtk_widget_destroy (widget->priv->entry);
widget->priv->entry = NULL;
}
/* make sure entry and combo are destroyed first */
/* as we use the two of them to create the filechooser */
if (widget->priv->filechooser)
{
gtk_widget_destroy (widget->priv->filechooser);
widget->priv->filechooser = NULL;
}
if (widget->priv->image)
{
gtk_widget_destroy (widget->priv->image);
widget->priv->image = NULL;
}
if (widget->priv->label)
{
gtk_widget_destroy (widget->priv->label);
widget->priv->label = NULL;
}
}
static void
check_toggled_cb (GtkToggleButton *toggle_button,
GtkPrinterOptionWidget *widget)
{
g_signal_handler_block (widget->priv->source, widget->priv->source_changed_handler);
gtk_printer_option_set_boolean (widget->priv->source,
gtk_toggle_button_get_active (toggle_button));
g_signal_handler_unblock (widget->priv->source, widget->priv->source_changed_handler);
emit_changed (widget);
}
static void
filesave_changed_cb (GtkWidget *w,
GtkPrinterOptionWidget *widget)
{
char *value;
char *directory;
const char *file;
/* combine the value of the chooser with the value of the entry */
g_signal_handler_block (widget->priv->source, widget->priv->source_changed_handler);
/* TODO: how do we support nonlocal file systems? */
directory = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (widget->priv->combo));
file = gtk_entry_get_text (GTK_ENTRY (widget->priv->entry));
value = g_build_filename (directory, file, NULL);
if (value)
gtk_printer_option_set (widget->priv->source, value);
g_free (directory);
g_free (value);
g_signal_handler_unblock (widget->priv->source, widget->priv->source_changed_handler);
emit_changed (widget);
}
static void
combo_changed_cb (GtkWidget *combo,
GtkPrinterOptionWidget *widget)
{
char *value;
g_signal_handler_block (widget->priv->source, widget->priv->source_changed_handler);
value = combo_box_get (combo);
if (value)
gtk_printer_option_set (widget->priv->source, value);
g_free (value);
g_signal_handler_unblock (widget->priv->source, widget->priv->source_changed_handler);
emit_changed (widget);
}
static void
entry_changed_cb (GtkWidget *entry,
GtkPrinterOptionWidget *widget)
{
const char *value;
g_signal_handler_block (widget->priv->source, widget->priv->source_changed_handler);
value = gtk_entry_get_text (GTK_ENTRY (entry));
if (value)
gtk_printer_option_set (widget->priv->source, value);
g_signal_handler_unblock (widget->priv->source, widget->priv->source_changed_handler);
emit_changed (widget);
}
static void
construct_widgets (GtkPrinterOptionWidget *widget)
{
GtkPrinterOption *source;
char *text;
int i;
source = widget->priv->source;
deconstruct_widgets (widget);
if (source == NULL)
{
widget->priv->combo = combo_box_new ();
combo_box_append (widget->priv->combo,_("Not available"), "None");
gtk_combo_box_set_active (GTK_COMBO_BOX (widget->priv->combo), 0);
gtk_widget_set_sensitive (widget->priv->combo, FALSE);
gtk_widget_show (widget->priv->combo);
gtk_box_pack_start (GTK_BOX (widget), widget->priv->combo, TRUE, TRUE, 0);
}
else switch (source->type)
{
case GTK_PRINTER_OPTION_TYPE_BOOLEAN:
widget->priv->check = gtk_check_button_new_with_mnemonic (source->display_text);
g_signal_connect (widget->priv->check, "toggled", G_CALLBACK (check_toggled_cb), widget);
gtk_widget_show (widget->priv->check);
gtk_box_pack_start (GTK_BOX (widget), widget->priv->check, TRUE, TRUE, 0);
break;
case GTK_PRINTER_OPTION_TYPE_PICKONE:
widget->priv->combo = combo_box_new ();
for (i = 0; i < source->num_choices; i++)
combo_box_append (widget->priv->combo,
source->choices_display[i],
source->choices[i]);
gtk_widget_show (widget->priv->combo);
gtk_box_pack_start (GTK_BOX (widget), widget->priv->combo, TRUE, TRUE, 0);
g_signal_connect (widget->priv->combo, "changed", G_CALLBACK (combo_changed_cb), widget);
text = g_strdup_printf ("%s: ", source->display_text);
widget->priv->label = gtk_label_new_with_mnemonic (text);
g_free (text);
gtk_widget_show (widget->priv->label);
break;
case GTK_PRINTER_OPTION_TYPE_STRING:
widget->priv->entry = gtk_entry_new ();
gtk_widget_show (widget->priv->entry);
gtk_box_pack_start (GTK_BOX (widget), widget->priv->entry, TRUE, TRUE, 0);
g_signal_connect (widget->priv->entry, "changed", G_CALLBACK (entry_changed_cb), widget);
text = g_strdup_printf ("%s: ", source->display_text);
widget->priv->label = gtk_label_new_with_mnemonic (text);
g_free (text);
gtk_widget_show (widget->priv->label);
break;
case GTK_PRINTER_OPTION_TYPE_FILESAVE:
{
GtkWidget *label;
GtkWidget *align;
widget->priv->filechooser = gtk_table_new (2, 2, FALSE);
/* TODO: make this a gtkfilechooserentry once we move to GTK */
widget->priv->entry = gtk_entry_new ();
widget->priv->combo = gtk_file_chooser_button_new ("Print to PDF",
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER);
align = gtk_alignment_new (0, 0.5, 0, 0);
label = gtk_label_new ("Name:");
gtk_container_add (GTK_CONTAINER (align), label);
gtk_table_attach (GTK_TABLE (widget->priv->filechooser), align,
0, 1, 0, 1, GTK_FILL, 0,
0, 0);
gtk_table_attach (GTK_TABLE (widget->priv->filechooser), widget->priv->entry,
1, 2, 0, 1, GTK_FILL, 0,
0, 0);
align = gtk_alignment_new (0, 0.5, 0, 0);
label = gtk_label_new ("Save in folder:");
gtk_container_add (GTK_CONTAINER (align), label);
gtk_table_attach (GTK_TABLE (widget->priv->filechooser), align,
0, 1, 1, 2, GTK_FILL, 0,
0, 0);
gtk_table_attach (GTK_TABLE (widget->priv->filechooser), widget->priv->combo,
1, 2, 1, 2, GTK_FILL, 0,
0, 0);
gtk_widget_show_all (widget->priv->filechooser);
gtk_box_pack_start (GTK_BOX (widget), widget->priv->filechooser, TRUE, TRUE, 0);
g_signal_connect (widget->priv->entry, "changed", G_CALLBACK (filesave_changed_cb), widget);
g_signal_connect (widget->priv->combo, "current-folder-changed", G_CALLBACK (filesave_changed_cb), widget);
}
break;
default:
break;
}
widget->priv->image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_MENU);
gtk_box_pack_start (GTK_BOX (widget), widget->priv->image, FALSE, FALSE, 0);
}
static void
update_widgets (GtkPrinterOptionWidget *widget)
{
GtkPrinterOption *source;
source = widget->priv->source;
if (source == NULL)
{
gtk_widget_hide (widget->priv->image);
return;
}
switch (source->type)
{
case GTK_PRINTER_OPTION_TYPE_BOOLEAN:
if (strcmp (source->value, "True") == 0)
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->priv->check), TRUE);
else
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget->priv->check), FALSE);
break;
case GTK_PRINTER_OPTION_TYPE_PICKONE:
combo_box_set (widget->priv->combo, source->value);
break;
case GTK_PRINTER_OPTION_TYPE_STRING:
gtk_entry_set_text (GTK_ENTRY (widget->priv->entry), source->value);
break;
case GTK_PRINTER_OPTION_TYPE_FILESAVE:
{
char *basename = g_path_get_basename (source->value);
char *dirname = g_path_get_dirname (source->value);
gtk_entry_set_text (GTK_ENTRY (widget->priv->entry), basename);
if (g_path_is_absolute (dirname))
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (widget->priv->combo),
dirname);
g_free (basename);
g_free (dirname);
break;
}
default:
break;
}
if (source->has_conflict)
gtk_widget_show (widget->priv->image);
else
gtk_widget_hide (widget->priv->image);
}
gboolean
gtk_printer_option_widget_has_external_label (GtkPrinterOptionWidget *widget)
{
return widget->priv->label != NULL;
}
GtkWidget *
gtk_printer_option_widget_get_external_label (GtkPrinterOptionWidget *widget)
{
return widget->priv->label;
}
const char *
gtk_printer_option_widget_get_value (GtkPrinterOptionWidget *widget)
{
if (widget->priv->source)
return widget->priv->source->value;
return "";
}

View File

@@ -0,0 +1,64 @@
/* GtkPrinterOptionWidget
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINTER_OPTION_WIDGET_H__
#define __GTK_PRINTER_OPTION_WIDGET_H__
#include "gtkprinteroption.h"
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_PRINTER_OPTION_WIDGET (gtk_printer_option_widget_get_type ())
#define GTK_PRINTER_OPTION_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINTER_OPTION_WIDGET, GtkPrinterOptionWidget))
#define GTK_PRINTER_OPTION_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINTER_OPTION_WIDGET, GtkPrinterOptionWidgetClass))
#define GTK_IS_PRINTER_OPTION_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINTER_OPTION_WIDGET))
#define GTK_IS_PRINTER_OPTION_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINTER_OPTION_WIDGET))
#define GTK_PRINTER_OPTION_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINTER_OPTION_WIDGET, GtkPrinterOptionWidgetClass))
typedef struct _GtkPrinterOptionWidget GtkPrinterOptionWidget;
typedef struct _GtkPrinterOptionWidgetClass GtkPrinterOptionWidgetClass;
typedef struct GtkPrinterOptionWidgetPrivate GtkPrinterOptionWidgetPrivate;
struct _GtkPrinterOptionWidget
{
GtkHBox parent_instance;
GtkPrinterOptionWidgetPrivate *priv;
};
struct _GtkPrinterOptionWidgetClass
{
GtkHBoxClass parent_class;
void (*changed) (GtkPrinterOptionWidget *widget);
};
GType gtk_printer_option_widget_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_printer_option_widget_new (GtkPrinterOption *source);
void gtk_printer_option_widget_set_source (GtkPrinterOptionWidget *setting,
GtkPrinterOption *source);
gboolean gtk_printer_option_widget_has_external_label (GtkPrinterOptionWidget *setting);
GtkWidget * gtk_printer_option_widget_get_external_label (GtkPrinterOptionWidget *setting);
const char *gtk_printer_option_widget_get_value (GtkPrinterOptionWidget *setting);
G_END_DECLS
#endif /* __GTK_PRINTER_OPTION_WIDGET_H__ */

345
gtk/gtkprintjob.c Normal file
View File

@@ -0,0 +1,345 @@
/* GtkPrintJob
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "gtkintl.h"
#include <gtk/gtk.h>
#include <gtk/gtkprivate.h>
#include "gtkprintjob.h"
#include "gtkprinter.h"
#include "gtkprintbackend.h"
struct _GtkPrintJobPrivate
{
gchar *title;
gint cache_fd;
cairo_surface_t *surface;
GtkPrintSettings *settings;
GtkPageSetup *page_setup;
GtkPrintBackend *backend;
GtkPrinter *printer;
gint printer_set : 1;
gint page_setup_set : 1;
gint settings_set : 1;
gint prepped : 1;
};
#define GTK_PRINT_JOB_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINT_JOB, GtkPrintJobPrivate))
static void gtk_print_job_finalize (GObject *object);
static void gtk_print_job_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gtk_print_job_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
enum {
PROP_0,
GTK_PRINT_JOB_PROP_TITLE,
GTK_PRINT_JOB_PROP_PRINTER,
GTK_PRINT_JOB_PROP_PAGE_SETUP,
GTK_PRINT_JOB_PROP_SETTINGS
};
G_DEFINE_TYPE (GtkPrintJob, gtk_print_job, G_TYPE_OBJECT);
static void
gtk_print_job_class_init (GtkPrintJobClass *class)
{
GObjectClass *object_class;
object_class = (GObjectClass *) class;
object_class->finalize = gtk_print_job_finalize;
object_class->set_property = gtk_print_job_set_property;
object_class->get_property = gtk_print_job_get_property;
g_type_class_add_private (class, sizeof (GtkPrintJobPrivate));
g_object_class_install_property (G_OBJECT_CLASS (class),
GTK_PRINT_JOB_PROP_TITLE,
g_param_spec_string ("title",
P_("Title"),
P_("Title of the print job"),
NULL,
GTK_PARAM_WRITABLE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (G_OBJECT_CLASS (class),
GTK_PRINT_JOB_PROP_PRINTER,
g_param_spec_object ("printer",
P_("Printer"),
P_("Printer to print the job to"),
GTK_TYPE_PRINTER,
GTK_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (G_OBJECT_CLASS (class),
GTK_PRINT_JOB_PROP_SETTINGS,
g_param_spec_object ("settings",
P_("Settings"),
P_("Printer settings"),
GTK_TYPE_PRINT_SETTINGS,
GTK_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (G_OBJECT_CLASS (class),
GTK_PRINT_JOB_PROP_PAGE_SETUP,
g_param_spec_object ("page-setup",
P_("Page Setup"),
P_("Page Setup"),
GTK_TYPE_PAGE_SETUP,
GTK_PARAM_READWRITE |
G_PARAM_CONSTRUCT_ONLY));
}
static void
gtk_print_job_init (GtkPrintJob *print_job)
{
print_job->priv = GTK_PRINT_JOB_GET_PRIVATE (print_job);
print_job->priv->cache_fd = 0;
print_job->priv->title = NULL;
print_job->priv->surface = NULL;
print_job->priv->backend = NULL;
print_job->priv->printer = NULL;
print_job->priv->printer_set = FALSE;
print_job->priv->settings_set = FALSE;
print_job->priv->page_setup_set = FALSE;
}
static void
gtk_print_job_finalize (GObject *object)
{
g_return_if_fail (object != NULL);
GtkPrintJob *print_job = GTK_PRINT_JOB (object);
if (print_job->priv->cache_fd != 0)
close (print_job->priv->cache_fd);
if (print_job->priv->backend)
g_object_unref (G_OBJECT (print_job->priv->backend));
if (print_job->priv->printer)
g_object_unref (G_OBJECT (print_job->priv->printer));
if (print_job->priv->surface)
cairo_surface_destroy (print_job->priv->surface);
if (print_job->priv->settings)
g_object_unref (print_job->priv->settings);
if (print_job->priv->page_setup)
g_object_unref (print_job->priv->page_setup);
if (G_OBJECT_CLASS (gtk_print_job_parent_class)->finalize)
G_OBJECT_CLASS (gtk_print_job_parent_class)->finalize (object);
}
/**
* gtk_print_job_new:
*
* Creates a new #GtkPrintJob.
*
* Return value: a new #GtkPrintJob
*
* Since: 2.8
**/
GtkPrintJob *
gtk_print_job_new (const gchar *title,
GtkPrintSettings *settings,
GtkPageSetup *page_setup,
GtkPrinter *printer)
{
GObject *result;
result = g_object_new (GTK_TYPE_PRINT_JOB,
"title", title,
"printer", printer,
"settings", settings,
"page-setup", page_setup,
NULL);
return (GtkPrintJob *) result;
}
GtkPrintSettings *
gtk_print_job_get_settings (GtkPrintJob *print_job)
{
g_assert (GTK_IS_PRINT_SETTINGS (print_job->priv->settings));
return print_job->priv->settings;
}
GtkPrinter *
gtk_print_job_get_printer (GtkPrintJob *print_job)
{
g_return_val_if_fail (GTK_IS_PRINT_JOB (print_job), NULL);
return print_job->priv->printer;
}
cairo_surface_t *
gtk_print_job_get_surface (GtkPrintJob *print_job)
{
g_return_val_if_fail (GTK_IS_PRINT_JOB (print_job), NULL);
return print_job->priv->surface;
}
gboolean
gtk_print_job_prep (GtkPrintJob *job,
GError **error)
{
char *filename;
double width, height;
GtkPaperSize *paper_size;
/* TODO: populate GError */
if (!(job->priv->printer_set &&
job->priv->settings_set &&
job->priv->page_setup_set))
return FALSE;
job->priv->prepped = TRUE;
job->priv->cache_fd = g_file_open_tmp ("gtkprint_XXXXXX",
&filename,
error);
fchmod (job->priv->cache_fd, S_IRUSR | S_IWUSR);
unlink (filename);
if (error != NULL && *error != NULL)
return FALSE;
paper_size = gtk_page_setup_get_paper_size (job->priv->page_setup);
width = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS);
height = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS);
job->priv->surface = _gtk_printer_create_cairo_surface (job->priv->printer,
width, height,
job->priv->cache_fd);
_gtk_printer_prepare_for_print (job->priv->printer,
job->priv->settings,
job->priv->page_setup);
return TRUE;
}
static void
gtk_print_job_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GtkPrintJob *impl = GTK_PRINT_JOB (object);
switch (prop_id)
{
case GTK_PRINT_JOB_PROP_TITLE:
impl->priv->title = g_value_dup_string (value);
break;
case GTK_PRINT_JOB_PROP_PRINTER:
impl->priv->printer = GTK_PRINTER (g_value_dup_object (value));
impl->priv->printer_set = TRUE;
impl->priv->backend = g_object_ref (gtk_printer_get_backend (impl->priv->printer));
break;
case GTK_PRINT_JOB_PROP_PAGE_SETUP:
impl->priv->page_setup = GTK_PAGE_SETUP (g_value_dup_object (value));
impl->priv->page_setup_set = TRUE;
break;
case GTK_PRINT_JOB_PROP_SETTINGS:
impl->priv->settings = GTK_PRINT_SETTINGS (g_value_dup_object (value));
impl->priv->settings_set = TRUE;
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gtk_print_job_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GtkPrintJob *impl = GTK_PRINT_JOB (object);
switch (prop_id)
{
case GTK_PRINT_JOB_PROP_PRINTER:
g_value_set_object (value, impl->priv->printer);
break;
case GTK_PRINT_JOB_PROP_SETTINGS:
g_value_set_object (value, impl->priv->settings);
break;
case GTK_PRINT_JOB_PROP_PAGE_SETUP:
g_value_set_object (value, impl->priv->page_setup);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
gboolean
gtk_print_job_send (GtkPrintJob *print_job,
GtkPrintJobCompleteFunc callback,
gpointer user_data,
GError **error)
{
/* TODO: set gerror */
if (!print_job->priv->prepped)
return FALSE;
lseek (print_job->priv->cache_fd, 0, SEEK_SET);
gtk_print_backend_print_stream (print_job->priv->backend,
print_job,
print_job->priv->title,
print_job->priv->cache_fd,
callback,
user_data);
return TRUE;
}

88
gtk/gtkprintjob.h Normal file
View File

@@ -0,0 +1,88 @@
/* GtkPrintJob
* Copyright (C) 2006 Red Hat,Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_JOB_H__
#define __GTK_PRINT_JOB_H__
#include <glib-object.h>
#include <cairo.h>
#include "gtkprinter.h"
#include "gtkprintsettings.h"
G_BEGIN_DECLS
#define GTK_TYPE_PRINT_JOB (gtk_print_job_get_type ())
#define GTK_PRINT_JOB(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_JOB, GtkPrintJob))
#define GTK_PRINT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_JOB, GtkPrintJobClass))
#define GTK_IS_PRINT_JOB(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_JOB))
#define GTK_IS_PRINT_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_JOB))
#define GTK_PRINT_JOB_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_JOB, GtkPrintJobClass))
typedef struct _GtkPrintJobClass GtkPrintJobClass;
typedef struct _GtkPrintJobPrivate GtkPrintJobPrivate;
typedef void (*GtkPrintJobCompleteFunc) (GtkPrintJob *print_job,
void *user_data,
GError **error);
struct _GtkPrinter;
struct _GtkPrintJob
{
GObject parent_instance;
GtkPrintJobPrivate *priv;
};
struct _GtkPrintJobClass
{
GObjectClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
};
GType gtk_print_job_get_type (void) G_GNUC_CONST;
GtkPrintJob *gtk_print_job_new (const gchar *title,
GtkPrintSettings *settings,
GtkPageSetup *page_setup,
GtkPrinter *printer);
GtkPrintSettings *gtk_print_job_get_settings (GtkPrintJob *print_job);
GtkPrinter *gtk_print_job_get_printer (GtkPrintJob *print_job);
cairo_surface_t *gtk_print_job_get_surface (GtkPrintJob *print_job);
gboolean gtk_print_job_send (GtkPrintJob *print_job,
GtkPrintJobCompleteFunc callback,
gpointer user_data,
GError **error);
gboolean gtk_print_job_prep (GtkPrintJob *job,
GError **error);
G_END_DECLS
#endif /* __GTK_PRINT_JOB_H__ */

View File

@@ -0,0 +1,76 @@
/* EGG - The GIMP Toolkit
* gtkprintoperation.h: Print Operation
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_OPERATION_PRIVATE_H__
#define __GTK_PRINT_OPERATION_PRIVATE_H__
#include "gtkprintoperation.h"
G_BEGIN_DECLS
struct _GtkPrintOperationPrivate
{
GtkPageSetup *default_page_setup;
GtkPrintSettings *print_settings;
char *job_name;
int nr_of_pages;
int current_page;
gboolean use_full_page;
GtkUnit unit;
gboolean show_dialog;
char *pdf_target;
/* Data for the print job: */
cairo_surface_t *surface;
double dpi_x, dpi_y;
int manual_num_copies;
gboolean manual_collation;
gboolean manual_orientation;
double manual_scale;
void *platform_data;
void (*start_page) (GtkPrintOperation *operation,
GtkPrintContext *print_context,
GtkPageSetup *page_setup);
void (*end_page) (GtkPrintOperation *operation,
GtkPrintContext *print_context);
void (*end_run) (GtkPrintOperation *operation);
};
GtkPrintOperationResult _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *operation,
GtkWindow *parent,
gboolean *do_print,
GError **error);
/* GtkPrintContext private functions: */
GtkPrintContext *_gtk_print_context_new (GtkPrintOperation *op);
void _gtk_print_context_set_page_setup (GtkPrintContext *context,
GtkPageSetup *page_setup);
void _gtk_print_context_translate_into_margin (GtkPrintContext *context);
void _gtk_print_context_rotate_according_to_orientation (GtkPrintContext *context);
G_END_DECLS
#endif /* __GTK_PRINT_OPERATION_PRIVATE_H__ */

View File

@@ -0,0 +1,229 @@
/* EGG - The GIMP Toolkit
* gtkprintoperation-unix.c: Print Operation Details for Unix and Unix like platforms
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gtkprintoperation-private.h"
#include "gtkmarshal.h"
#include "gtkprintunixdialog.h"
#include "gtkpagesetupunixdialog.h"
#include "gtkprintbackend.h"
#include "gtkprinter.h"
#include "gtkprintjob.h"
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
typedef struct {
GtkPrintJob *job; /* the job we are sending to the printer */
GtkWindow *parent; /* parent window just in case we need to throw error dialogs */
} GtkPrintOperationUnix;
static void
unix_start_page (GtkPrintOperation *op,
GtkPrintContext *print_context,
GtkPageSetup *page_setup)
{
}
static void
unix_end_page (GtkPrintOperation *op,
GtkPrintContext *print_context)
{
cairo_t *cr;
cr = gtk_print_context_get_cairo (print_context);
cairo_show_page (cr);
}
static void
_op_unix_free (GtkPrintOperationUnix *op_unix)
{
if (op_unix->job)
g_object_unref (G_OBJECT (op_unix->job));
g_free (op_unix);
}
static void
unix_finish_send (GtkPrintJob *job,
void *user_data,
GError **error)
{
GtkPrintOperationUnix *op_unix;
GtkWindow *parent;
op_unix = (GtkPrintOperationUnix *) user_data;
parent = op_unix->parent;
_op_unix_free (op_unix);
if (error != NULL && *error != NULL)
{
GtkWidget *edialog;
GError *err = *error;
edialog = gtk_message_dialog_new (parent,
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Error printing: %s",
err->message);
gtk_dialog_run (GTK_DIALOG (edialog));
gtk_widget_destroy (edialog);
}
}
static void
unix_end_run (GtkPrintOperation *op)
{
GtkPrintOperationUnix *op_unix = op->priv->platform_data;
/* TODO: Check for error */
gtk_print_job_send (g_object_ref (op_unix->job),
unix_finish_send,
op_unix, NULL);
op->priv->platform_data = NULL;
}
GtkPrintOperationResult
_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
GtkWindow *parent,
gboolean *do_print,
GError **error)
{
GtkWidget *pd;
GtkPrintOperationResult result;
GtkPageSetup *page_setup;
result = GTK_PRINT_OPERATION_RESULT_CANCEL;
if (op->priv->default_page_setup)
page_setup = gtk_page_setup_copy (op->priv->default_page_setup);
else
page_setup = gtk_page_setup_new ();
pd = gtk_print_unix_dialog_new (NULL, parent);
if (op->priv->print_settings)
gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (pd),
op->priv->print_settings);
gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (pd), page_setup);
*do_print = FALSE;
if (gtk_dialog_run (GTK_DIALOG (pd)) == GTK_RESPONSE_ACCEPT)
{
GtkPrintOperationUnix *op_unix;
GtkPrinter *printer;
GtkPrintSettings *settings, *settings_copy;
result = GTK_PRINT_OPERATION_RESULT_APPLY;
printer = gtk_print_unix_dialog_get_selected_printer (GTK_PRINT_UNIX_DIALOG (pd));
if (printer == NULL)
goto out;
*do_print = TRUE;
settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd));
/* We save a copy to return to the user to avoid exposing
the extra settings preparint the printer job adds. */
settings_copy = gtk_print_settings_copy (settings);
gtk_print_operation_set_print_settings (op, settings_copy);
g_object_unref (settings_copy);
op_unix = g_new (GtkPrintOperationUnix, 1);
op_unix->job = gtk_printer_prep_job (printer,
settings,
page_setup,
"Title",
error);
g_object_unref (settings);
if (error != NULL && *error != NULL)
{
*do_print = FALSE;
_op_unix_free (op_unix);
result = GTK_PRINT_OPERATION_RESULT_ERROR;
goto out;
}
op_unix->parent = parent;
op->priv->surface = gtk_print_job_get_surface (op_unix->job);
op->priv->dpi_x = 72;
op->priv->dpi_y = 72;
op->priv->platform_data = op_unix;
/* TODO: hook up to dialog elements */
op->priv->manual_num_copies =
gtk_print_settings_get_int_with_default (settings, "manual-num-copies", 1);
op->priv->manual_collation =
gtk_print_settings_get_bool (settings, "manual-collate");
op->priv->manual_scale =
gtk_print_settings_get_double_with_default (settings, "manual-scale", 100.0);
op->priv->manual_orientation =
gtk_print_settings_get_bool (settings, "manual-orientation");
}
op->priv->start_page = unix_start_page;
op->priv->end_page = unix_end_page;
op->priv->end_run = unix_end_run;
out:
g_object_unref (page_setup);
gtk_widget_destroy (pd);
return result;
}
GtkPageSetup *
gtk_print_run_page_setup_dialog (GtkWindow *parent,
GtkPageSetup *page_setup,
GtkPrintSettings *settings)
{
GtkWidget *dialog;
GtkPageSetup *new_page_setup;
dialog = gtk_page_setup_unix_dialog_new (NULL, parent);
if (page_setup)
gtk_page_setup_unix_dialog_set_page_setup (GTK_PAGE_SETUP_UNIX_DIALOG (dialog),
page_setup);
gtk_page_setup_unix_dialog_set_print_settings (GTK_PAGE_SETUP_UNIX_DIALOG (dialog),
settings);
gtk_dialog_run (GTK_DIALOG (dialog));
new_page_setup = gtk_page_setup_unix_dialog_get_page_setup (GTK_PAGE_SETUP_UNIX_DIALOG (dialog));
gtk_widget_destroy (dialog);
return new_page_setup;
}

File diff suppressed because it is too large Load Diff

510
gtk/gtkprintoperation.c Normal file
View File

@@ -0,0 +1,510 @@
/* GTK - The GIMP Toolkit
* gtkprintoperation.c: Print Operation
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gtkprintoperation-private.h"
#include "gtkmarshalers.h"
#include <cairo-pdf.h>
#define GTK_PRINT_OPERATION_GET_PRIVATE(obj)(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_PRINT_OPERATION, GtkPrintOperationPrivate))
enum {
BEGIN_PRINT,
REQUEST_PAGE_SETUP,
DRAW_PAGE,
END_PRINT,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL] = { 0 };
static int job_nr = 1;
G_DEFINE_TYPE (GtkPrintOperation, gtk_print_operation, G_TYPE_OBJECT)
GQuark
gtk_print_error_quark (void)
{
static GQuark quark = 0;
if (quark == 0)
quark = g_quark_from_static_string ("gtk-print-error-quark");
return quark;
}
static void
gtk_print_operation_finalize (GObject *object)
{
GtkPrintOperation *print_operation = GTK_PRINT_OPERATION (object);
if (print_operation->priv->default_page_setup)
g_object_unref (print_operation->priv->default_page_setup);
if (print_operation->priv->print_settings)
g_object_unref (print_operation->priv->print_settings);
g_free (print_operation->priv->pdf_target);
g_free (print_operation->priv->job_name);
G_OBJECT_CLASS (gtk_print_operation_parent_class)->finalize (object);
}
static void
gtk_print_operation_init (GtkPrintOperation *operation)
{
const char *appname;
operation->priv = GTK_PRINT_OPERATION_GET_PRIVATE (operation);
operation->priv->default_page_setup = NULL;
operation->priv->print_settings = NULL;
operation->priv->nr_of_pages = -1;
operation->priv->current_page = -1;
operation->priv->use_full_page = FALSE;
operation->priv->show_dialog = TRUE;
operation->priv->pdf_target = NULL;
operation->priv->unit = GTK_UNIT_PIXEL;
appname = g_get_application_name ();
operation->priv->job_name = g_strdup_printf ("%s job #%d",
appname, job_nr++);
}
static void
gtk_print_operation_class_init (GtkPrintOperationClass *class)
{
GObjectClass *gobject_class = (GObjectClass *)class;
gobject_class->finalize = gtk_print_operation_finalize;
g_type_class_add_private (gobject_class, sizeof (GtkPrintOperationPrivate));
signals[BEGIN_PRINT] =
g_signal_new ("begin_print",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, begin_print),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
signals[REQUEST_PAGE_SETUP] =
g_signal_new ("request_page_setup",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, request_page_setup),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_INT_OBJECT,
G_TYPE_NONE, 3,
GTK_TYPE_PRINT_CONTEXT,
G_TYPE_INT,
GTK_TYPE_PAGE_SETUP);
signals[DRAW_PAGE] =
g_signal_new ("draw_page",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, draw_page),
NULL, NULL,
_gtk_marshal_VOID__OBJECT_INT,
G_TYPE_NONE, 2,
GTK_TYPE_PRINT_CONTEXT,
G_TYPE_INT);
signals[END_PRINT] =
g_signal_new ("end_print",
G_TYPE_FROM_CLASS (gobject_class),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GtkPrintOperationClass, end_print),
NULL, NULL,
g_cclosure_marshal_VOID__OBJECT,
G_TYPE_NONE, 1, GTK_TYPE_PRINT_CONTEXT);
}
GtkPrintOperation *
gtk_print_operation_new ()
{
GtkPrintOperation *print_operation;
print_operation = g_object_new (GTK_TYPE_PRINT_OPERATION, NULL);
return print_operation;
}
void
gtk_print_operation_set_default_page_setup (GtkPrintOperation *op,
GtkPageSetup *default_page_setup)
{
g_return_if_fail (op != NULL);
if (default_page_setup)
g_object_ref (default_page_setup);
if (op->priv->default_page_setup)
g_object_unref (op->priv->default_page_setup);
op->priv->default_page_setup = default_page_setup;
}
GtkPageSetup *
gtk_print_operation_get_default_page_setup (GtkPrintOperation *op)
{
g_return_val_if_fail (op != NULL, NULL);
return op->priv->default_page_setup;
}
void
gtk_print_operation_set_print_settings (GtkPrintOperation *op,
GtkPrintSettings *print_settings)
{
g_return_if_fail (op != NULL);
g_return_if_fail (print_settings != NULL);
if (print_settings)
g_object_ref (print_settings);
if (op->priv->print_settings)
g_object_unref (op->priv->print_settings);
op->priv->print_settings = print_settings;
}
GtkPrintSettings *
gtk_print_operation_get_print_settings (GtkPrintOperation *op)
{
g_return_val_if_fail (op != NULL, NULL);
if (op->priv->print_settings)
return op->priv->print_settings;
return NULL;
}
void
gtk_print_operation_set_job_name (GtkPrintOperation *op,
const char *job_name)
{
g_return_if_fail (g_utf8_validate (job_name, -1, NULL));
g_free (op->priv->job_name);
op->priv->job_name = g_strdup (job_name);
}
void
gtk_print_operation_set_nr_of_pages (GtkPrintOperation *op,
int n_pages)
{
g_return_if_fail (op != NULL);
op->priv->nr_of_pages = n_pages;
}
void
gtk_print_operation_set_current_page (GtkPrintOperation *op,
int current_page)
{
g_return_if_fail (op != NULL);
op->priv->current_page = current_page;
}
void
gtk_print_operation_set_use_full_page (GtkPrintOperation *op,
gboolean full_page)
{
g_return_if_fail (op != NULL);
op->priv->use_full_page = full_page;
}
void
gtk_print_operation_set_unit (GtkPrintOperation *op,
GtkUnit unit)
{
op->priv->unit = unit;
}
void
gtk_print_operation_set_show_dialog (GtkPrintOperation *op,
gboolean show_dialog)
{
g_return_if_fail (op != NULL);
op->priv->show_dialog = show_dialog;
}
void
gtk_print_operation_set_pdf_target (GtkPrintOperation *op,
const char * filename)
{
g_return_if_fail (op != NULL);
g_free (op->priv->pdf_target);
op->priv->pdf_target = g_strdup (filename);
}
/* Creates the initial page setup used for printing unless the
* app overrides this on a per-page basis using request_page_setup.
*
* Data is taken from, in order, if existing:
*
* PrintSettings returned from the print dialog
* (initial dialog values are set from default_page_setup
if unset in app specified print_settings)
* default_page_setup
* per-locale default setup
*/
static GtkPageSetup *
create_page_setup (GtkPrintOperation *op)
{
GtkPageSetup *page_setup;
GtkPrintSettings *settings;
if (op->priv->default_page_setup)
page_setup = gtk_page_setup_copy (op->priv->default_page_setup);
else
page_setup = gtk_page_setup_new ();
settings = op->priv->print_settings;
if (settings)
{
GtkPaperSize *paper_size;
if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
gtk_page_setup_set_orientation (page_setup,
gtk_print_settings_get_orientation (settings));
paper_size = gtk_print_settings_get_paper_size (settings);
if (paper_size)
{
gtk_page_setup_set_paper_size (page_setup, paper_size);
gtk_paper_size_free (paper_size);
}
/* TODO: Margins? */
}
return page_setup;
}
static void
pdf_start_page (GtkPrintOperation *op,
GtkPrintContext *print_context,
GtkPageSetup *page_setup)
{
/* TODO: Set up page size, not supported in cairo yet */
}
static void
pdf_end_page (GtkPrintOperation *op,
GtkPrintContext *print_context)
{
cairo_t *cr;
cr = gtk_print_context_get_cairo (print_context);
cairo_show_page (cr);
}
static void
pdf_end_run (GtkPrintOperation *op)
{
cairo_surface_destroy (op->priv->surface);
op->priv->surface = NULL;
}
static GtkPrintOperationResult
run_pdf (GtkPrintOperation *op,
GtkWindow *parent,
gboolean *do_print,
GError **error)
{
GtkPageSetup *page_setup;
double width, height;
/* This will be overwritten later by the non-default size, but
we need to pass some size: */
page_setup = create_page_setup (op);
width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS);
height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS);
g_object_unref (page_setup);
op->priv->surface = cairo_pdf_surface_create (op->priv->pdf_target,
width, height);
/* TODO: DPI from settings object? */
cairo_pdf_surface_set_dpi (op->priv->surface, 300, 300);
op->priv->dpi_x = 72;
op->priv->dpi_y = 72;
op->priv->manual_num_copies = 1;
op->priv->manual_collation = FALSE;
*do_print = TRUE;
op->priv->start_page = pdf_start_page;
op->priv->end_page = pdf_end_page;
op->priv->end_run = pdf_end_run;
return GTK_PRINT_OPERATION_RESULT_APPLY;
}
static GtkPrintOperationResult
run_print_dialog (GtkPrintOperation *op,
GtkWindow *parent,
gboolean *do_print,
GError **error)
{
if (op->priv->pdf_target != NULL)
return run_pdf (op, parent, do_print, error);
/* This does:
* Open print dialog
* set print settings on dialog
* run dialog, if show_dialog set
* extract print settings from dialog
* create cairo surface and data for print job
* return correct result val
*/
return _gtk_print_operation_platform_backend_run_dialog (op, parent,
do_print,
error);
}
GtkPrintOperationResult
gtk_print_operation_run (GtkPrintOperation *op,
GtkWindow *parent,
GError **error)
{
int page, range;
GtkPageSetup *initial_page_setup, *page_setup;
GtkPrintContext *print_context;
cairo_t *cr;
gboolean do_print;
int uncollated_copies, collated_copies;
int i, j;
GtkPageRange *ranges;
int num_ranges;
GtkPrintOperationResult result;
result = run_print_dialog (op, parent, &do_print, error);
if (!do_print)
return result;
if (op->priv->manual_collation)
{
uncollated_copies = 1;
collated_copies = op->priv->manual_num_copies;
}
else
{
uncollated_copies = op->priv->manual_num_copies;
collated_copies = 1;
}
print_context = _gtk_print_context_new (op);
initial_page_setup = create_page_setup (op);
_gtk_print_context_set_page_setup (print_context, initial_page_setup);
g_signal_emit (op, signals[BEGIN_PRINT], 0, print_context);
g_return_val_if_fail (op->priv->nr_of_pages != -1, FALSE);
if (op->priv->print_settings == NULL)
{
ranges = g_new (GtkPageRange, 1);
num_ranges = 1;
ranges[0].start = 0;
ranges[0].end = op->priv->nr_of_pages - 1;
}
else
{
GtkPrintPages print_pages = gtk_print_settings_get_print_pages (op->priv->print_settings);
ranges = NULL;
if (print_pages == GTK_PRINT_PAGES_RANGES)
ranges = gtk_print_settings_get_page_ranges (op->priv->print_settings,
&num_ranges);
if (ranges == NULL)
{
ranges = g_new (GtkPageRange, 1);
num_ranges = 1;
if (print_pages == GTK_PRINT_PAGES_CURRENT &&
op->priv->current_page != -1)
{
/* Current */
ranges[0].start = op->priv->current_page;
ranges[0].end = op->priv->current_page;
}
else
{
/* All */
ranges[0].start = 0;
ranges[0].end = op->priv->nr_of_pages - 1;
}
}
}
for (i = 0; i < uncollated_copies; i++)
{
for (range = 0; range < num_ranges; range ++)
{
for (page = ranges[range].start; page <= ranges[range].end; page ++)
{
for (j = 0; j < collated_copies; j++)
{
page_setup = gtk_page_setup_copy (initial_page_setup);
g_signal_emit (op, signals[REQUEST_PAGE_SETUP], 0, print_context, page, page_setup);
_gtk_print_context_set_page_setup (print_context, page_setup);
op->priv->start_page (op, print_context, page_setup);
cr = gtk_print_context_get_cairo (print_context);
cairo_save (cr);
if (op->priv->manual_scale != 100.0)
cairo_scale (cr,
op->priv->manual_scale / 100.0,
op->priv->manual_scale / 100.0);
if (op->priv->manual_orientation)
_gtk_print_context_rotate_according_to_orientation (print_context);
if (!op->priv->use_full_page)
_gtk_print_context_translate_into_margin (print_context);
g_signal_emit (op, signals[DRAW_PAGE], 0,
print_context, page);
op->priv->end_page (op, print_context);
cairo_restore (cr);
g_object_unref (page_setup);
}
}
}
}
g_signal_emit (op, signals[END_PRINT], 0, print_context);
g_object_unref (print_context);
g_object_unref (initial_page_setup);
cairo_surface_finish (op->priv->surface);
op->priv->end_run (op);
return GTK_PRINT_OPERATION_RESULT_APPLY;
}

123
gtk/gtkprintoperation.h Normal file
View File

@@ -0,0 +1,123 @@
/* EGG - The GIMP Toolkit
* gtkprintoperation.h: Print Operation
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_OPERATION_H__
#define __GTK_PRINT_OPERATION_H__
#include <glib-object.h>
#include <cairo.h>
#include <gtk/gtk.h>
#include <gtk/gtkenums.h>
#include <gtk/gtkpagesetup.h>
#include <gtk/gtkprintsettings.h>
#include <gtk/gtkprintcontext.h>
G_BEGIN_DECLS
#define GTK_TYPE_PRINT_OPERATION (gtk_print_operation_get_type ())
#define GTK_PRINT_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_OPERATION, GtkPrintOperation))
#define GTK_IS_PRINT_OPERATION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_OPERATION))
typedef struct _GtkPrintOperationClass GtkPrintOperationClass;
typedef struct _GtkPrintOperationPrivate GtkPrintOperationPrivate;
typedef struct _GtkPrintOperation GtkPrintOperation;
struct _GtkPrintOperation
{
GObject parent_instance;
GtkPrintOperationPrivate *priv;
};
struct _GtkPrintOperationClass
{
GObjectClass parent_class;
void (*begin_print) (GtkPrintOperation *operation, GtkPrintContext *context);
void (*request_page_setup) (GtkPrintOperation *operation,
GtkPrintContext *context,
int page_nr,
GtkPageSetup *setup);
void (*draw_page) (GtkPrintOperation *operation,
GtkPrintContext *context,
int page_nr);
void (*end_print) (GtkPrintOperation *operation,
GtkPrintContext *context);
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
};
typedef enum {
GTK_PRINT_OPERATION_RESULT_ERROR,
GTK_PRINT_OPERATION_RESULT_APPLY,
GTK_PRINT_OPERATION_RESULT_CANCEL
} GtkPrintOperationResult;
#define GTK_PRINT_ERROR gtk_print_error_quark ()
typedef enum
{
GTK_PRINT_ERROR_GENERAL,
GTK_PRINT_ERROR_INTERNAL_ERROR,
GTK_PRINT_ERROR_NOMEM
} GtkPrintError;
GQuark gtk_print_error_quark (void);
GType gtk_print_operation_get_type (void);
GtkPrintOperation * gtk_print_operation_new (void);
void gtk_print_operation_set_default_page_setup (GtkPrintOperation *op,
GtkPageSetup *default_page_setup);
GtkPageSetup * gtk_print_operation_get_default_page_setup (GtkPrintOperation *op);
void gtk_print_operation_set_print_settings (GtkPrintOperation *op,
GtkPrintSettings *print_settings);
GtkPrintSettings * gtk_print_operation_get_print_settings (GtkPrintOperation *op);
void gtk_print_operation_set_job_name (GtkPrintOperation *op,
const char *job_name);
void gtk_print_operation_set_nr_of_pages (GtkPrintOperation *op,
int n_pages);
void gtk_print_operation_set_current_page (GtkPrintOperation *op,
int current_page);
void gtk_print_operation_set_use_full_page (GtkPrintOperation *op,
gboolean full_page);
void gtk_print_operation_set_unit (GtkPrintOperation *op,
GtkUnit unit);
void gtk_print_operation_set_show_dialog (GtkPrintOperation *op,
gboolean show_dialog);
void gtk_print_operation_set_pdf_target (GtkPrintOperation *op,
const char *filename);
GtkPrintOperationResult gtk_print_operation_run (GtkPrintOperation *op,
GtkWindow *parent,
GError **error);
GtkPageSetup *gtk_print_run_page_setup_dialog (GtkWindow *parent,
GtkPageSetup *page_setup,
GtkPrintSettings *settings);
G_END_DECLS
#endif /* __GTK_PRINT_OPERATION_H__ */

911
gtk/gtkprintsettings.c Normal file
View File

@@ -0,0 +1,911 @@
/* GTK - The GIMP Toolkit
* gtkprintsettings.c: Print Settings
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gtkprintsettings.h"
#include <string.h>
#include <stdlib.h>
#include <glib/gprintf.h>
#define MM_PER_INCH 25.4
#define POINTS_PER_INCH 72
typedef struct _GtkPrintSettingsClass GtkPrintSettingsClass;
#define GTK_IS_PRINT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_SETTINGS))
#define GTK_PRINT_SETTINGS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_SETTINGS, GtkPrintSettingsClass))
#define GTK_PRINT_SETTINGS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_SETTINGS, GtkPrintSettingsClass))
struct _GtkPrintSettings
{
GObject parent_instance;
GHashTable *hash;
};
struct _GtkPrintSettingsClass
{
GObjectClass parent_class;
};
G_DEFINE_TYPE (GtkPrintSettings, gtk_print_settings, G_TYPE_OBJECT)
static double
to_mm (double len, GtkUnit unit)
{
switch (unit)
{
case GTK_UNIT_MM:
return len;
case GTK_UNIT_INCH:
return len * MM_PER_INCH;
default:
case GTK_UNIT_PIXEL:
g_warning ("Unsupported unit");
/* Fall through */
case GTK_UNIT_POINTS:
return len * (MM_PER_INCH / POINTS_PER_INCH);
break;
}
}
static double
from_mm (double len, GtkUnit unit)
{
switch (unit)
{
case GTK_UNIT_MM:
return len;
case GTK_UNIT_INCH:
return len / MM_PER_INCH;
default:
case GTK_UNIT_PIXEL:
g_warning ("Unsupported unit");
/* Fall through */
case GTK_UNIT_POINTS:
return len / (MM_PER_INCH / POINTS_PER_INCH);
break;
}
}
static void
gtk_print_settings_finalize (GObject *object)
{
GtkPrintSettings *settings = GTK_PRINT_SETTINGS (object);
g_hash_table_destroy (settings->hash);
G_OBJECT_CLASS (gtk_print_settings_parent_class)->finalize (object);
}
static void
gtk_print_settings_init (GtkPrintSettings *settings)
{
settings->hash = g_hash_table_new_full (g_str_hash, g_str_equal,
g_free, g_free);
}
static void
gtk_print_settings_class_init (GtkPrintSettingsClass *class)
{
GObjectClass *gobject_class = (GObjectClass *)class;
gobject_class->finalize = gtk_print_settings_finalize;
}
GtkPrintSettings *
gtk_print_settings_new (void)
{
return g_object_new (GTK_TYPE_PRINT_SETTINGS, NULL);
}
static void
copy_hash_entry (gpointer key,
gpointer value,
gpointer user_data)
{
GtkPrintSettings *settings = user_data;
g_hash_table_insert (settings->hash,
g_strdup (key),
g_strdup (value));
}
GtkPrintSettings *
gtk_print_settings_copy (GtkPrintSettings *other)
{
GtkPrintSettings *settings;
if (other == NULL)
return NULL;
g_return_val_if_fail (GTK_IS_PRINT_SETTINGS (other), NULL);
settings = gtk_print_settings_new ();
g_hash_table_foreach (other->hash,
copy_hash_entry,
settings);
return settings;
}
const char *
gtk_print_settings_get (GtkPrintSettings *settings,
const char *key)
{
return g_hash_table_lookup (settings->hash, key);
}
void
gtk_print_settings_set (GtkPrintSettings *settings,
const char *key,
const char *value)
{
if (value == NULL)
gtk_print_settings_unset (settings, key);
else
g_hash_table_insert (settings->hash,
g_strdup (key),
g_strdup (value));
}
void
gtk_print_settings_unset (GtkPrintSettings *settings,
const char *key)
{
g_hash_table_remove (settings->hash, key);
}
gboolean
gtk_print_settings_has_key (GtkPrintSettings *settings,
const char *key)
{
return gtk_print_settings_get (settings, key) != NULL;
}
gboolean
gtk_print_settings_get_bool (GtkPrintSettings *settings,
const char *key)
{
const char *val;
val = gtk_print_settings_get (settings, key);
if (val != NULL && strcmp (val, "true") == 0)
return TRUE;
return FALSE;
}
static gboolean
gtk_print_settings_get_bool_with_default (GtkPrintSettings *settings,
const char *key,
gboolean default_val)
{
const char *val;
val = gtk_print_settings_get (settings, key);
if (val != NULL && strcmp (val, "true") == 0)
return TRUE;
if (val != NULL && strcmp (val, "false") == 0)
return FALSE;
return default_val;
}
void
gtk_print_settings_set_bool (GtkPrintSettings *settings,
const char *key,
gboolean value)
{
if (value)
gtk_print_settings_set (settings, key, "true");
else
gtk_print_settings_set (settings, key, "false");
}
double
gtk_print_settings_get_double_with_default (GtkPrintSettings *settings,
const char *key,
double def)
{
const char *val;
val = gtk_print_settings_get (settings, key);
if (val == NULL)
return def;
return g_ascii_strtod (val, NULL);
}
double
gtk_print_settings_get_double (GtkPrintSettings *settings,
const char *key)
{
return gtk_print_settings_get_double_with_default (settings, key, 0.0);
}
void
gtk_print_settings_set_double (GtkPrintSettings *settings,
const char *key,
double value)
{
char buf[G_ASCII_DTOSTR_BUF_SIZE];
g_ascii_dtostr (buf, G_ASCII_DTOSTR_BUF_SIZE, value);
gtk_print_settings_set (settings, key, buf);
}
double
gtk_print_settings_get_length (GtkPrintSettings *settings,
const char *key,
GtkUnit unit)
{
double length = gtk_print_settings_get_double (settings, key);
return from_mm (length, unit);
}
void
gtk_print_settings_set_length (GtkPrintSettings *settings,
const char *key,
double length,
GtkUnit unit)
{
gtk_print_settings_set_double (settings, key,
to_mm (length, unit));
}
int
gtk_print_settings_get_int_with_default (GtkPrintSettings *settings,
const char *key,
int def)
{
const char *val;
val = gtk_print_settings_get (settings, key);
if (val == NULL)
return def;
return atoi (val);
}
int
gtk_print_settings_get_int (GtkPrintSettings *settings,
const char *key)
{
return gtk_print_settings_get_int_with_default (settings, key, 0);
}
void
gtk_print_settings_set_int (GtkPrintSettings *settings,
const char *key,
int value)
{
char buf[128];
g_sprintf(buf, "%d", value);
gtk_print_settings_set (settings, key, buf);
}
void
gtk_print_settings_foreach (GtkPrintSettings *settings,
GtkPrintSettingsFunc func,
gpointer user_data)
{
g_hash_table_foreach (settings->hash,
(GHFunc)func,
user_data);
}
const char *
gtk_print_settings_get_printer (GtkPrintSettings *settings)
{
return gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_PRINTER);
}
void
gtk_print_settings_set_printer (GtkPrintSettings *settings,
const char *printer)
{
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PRINTER, printer);
}
GtkPageOrientation
gtk_print_settings_get_orientation (GtkPrintSettings *settings)
{
const char *val;
val = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_ORIENTATION);
if (val == NULL || strcmp (val, "portrait") == 0)
return GTK_PAGE_ORIENTATION_PORTRAIT;
if (strcmp (val, "landscape") == 0)
return GTK_PAGE_ORIENTATION_LANDSCAPE;
if (strcmp (val, "reverse_portrait") == 0)
return GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT;
if (strcmp (val, "reverse_landscape") == 0)
return GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE;
return GTK_PAGE_ORIENTATION_PORTRAIT;
}
void
gtk_print_settings_set_orientation (GtkPrintSettings *settings,
GtkPageOrientation orientation)
{
const char *val;
switch (orientation)
{
case GTK_PAGE_ORIENTATION_LANDSCAPE:
val = "landscape";
break;
default:
case GTK_PAGE_ORIENTATION_PORTRAIT:
val = "portrait";
break;
case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
val = "reverse_landscape";
break;
case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
val = "reverse_portrait";
break;
}
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_ORIENTATION, val);
}
GtkPaperSize *
gtk_print_settings_get_paper_size (GtkPrintSettings *settings)
{
const char *val;
const char *name;
double w, h;
val = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_PAPER_FORMAT);
if (val == NULL)
return NULL;
if (g_str_has_prefix (val, "custom-"))
{
name = val + strlen ("custom-");
w = gtk_print_settings_get_paper_width (settings, GTK_UNIT_MM);
h = gtk_print_settings_get_paper_height (settings, GTK_UNIT_MM);
return gtk_paper_size_new_custom (name, name, w, h, GTK_UNIT_MM);
}
return gtk_paper_size_new (val);
}
void
gtk_print_settings_set_paper_size (GtkPrintSettings *settings,
GtkPaperSize *paper_size)
{
char *custom_name;
if (paper_size == NULL)
{
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PAPER_FORMAT, NULL);
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PAPER_WIDTH, NULL);
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PAPER_HEIGHT, NULL);
}
else if (gtk_paper_size_is_custom (paper_size))
{
custom_name = g_strdup_printf ("custom-%s",
gtk_paper_size_get_name (paper_size));
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PAPER_FORMAT, custom_name);
g_free (custom_name);
gtk_print_settings_set_paper_width (settings,
gtk_paper_size_get_width (paper_size,
GTK_UNIT_MM),
GTK_UNIT_MM);
gtk_print_settings_set_paper_height (settings,
gtk_paper_size_get_height (paper_size,
GTK_UNIT_MM),
GTK_UNIT_MM);
}
else
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PAPER_FORMAT,
gtk_paper_size_get_name (paper_size));
}
double
gtk_print_settings_get_paper_width (GtkPrintSettings *settings,
GtkUnit unit)
{
return gtk_print_settings_get_length (settings, GTK_PRINT_SETTINGS_PAPER_WIDTH, unit);
}
void
gtk_print_settings_set_paper_width (GtkPrintSettings *settings,
double width,
GtkUnit unit)
{
gtk_print_settings_set_length (settings, GTK_PRINT_SETTINGS_PAPER_WIDTH, width, unit);
}
double
gtk_print_settings_get_paper_height (GtkPrintSettings *settings,
GtkUnit unit)
{
return gtk_print_settings_get_length (settings,
GTK_PRINT_SETTINGS_PAPER_HEIGHT,
unit);
}
void
gtk_print_settings_set_paper_height (GtkPrintSettings *settings,
double height,
GtkUnit unit)
{
gtk_print_settings_set_length (settings,
GTK_PRINT_SETTINGS_PAPER_HEIGHT,
height, unit);
}
gboolean
gtk_print_settings_get_use_color (GtkPrintSettings *settings)
{
return gtk_print_settings_get_bool_with_default (settings,
GTK_PRINT_SETTINGS_USE_COLOR,
TRUE);
}
void
gtk_print_settings_set_use_color (GtkPrintSettings *settings,
gboolean use_color)
{
gtk_print_settings_set_bool (settings,
GTK_PRINT_SETTINGS_USE_COLOR,
use_color);
}
gboolean
gtk_print_settings_get_collate (GtkPrintSettings *settings)
{
return gtk_print_settings_get_bool (settings,
GTK_PRINT_SETTINGS_COLLATE);
}
void
gtk_print_settings_set_collate (GtkPrintSettings *settings,
gboolean collate)
{
gtk_print_settings_set_bool (settings,
GTK_PRINT_SETTINGS_COLLATE,
collate);
}
gboolean
gtk_print_settings_get_reverse (GtkPrintSettings *settings)
{
return gtk_print_settings_get_bool (settings,
GTK_PRINT_SETTINGS_REVERSE);
}
void
gtk_print_settings_set_reverse (GtkPrintSettings *settings,
gboolean reverse)
{
gtk_print_settings_set_bool (settings,
GTK_PRINT_SETTINGS_REVERSE,
reverse);
}
GtkPrintDuplex
gtk_print_settings_get_duplex (GtkPrintSettings *settings)
{
const char *val;
val = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_DUPLEX);
if (val == NULL || (strcmp (val, "simplex") == 0))
return GTK_PRINT_DUPLEX_SIMPLEX;
if (strcmp (val, "horizontal") == 0)
return GTK_PRINT_DUPLEX_HORIZONTAL;
if (strcmp (val, "vertical") == 0)
return GTK_PRINT_DUPLEX_HORIZONTAL;
return GTK_PRINT_DUPLEX_SIMPLEX;
}
void
gtk_print_settings_set_duplex (GtkPrintSettings *settings,
GtkPrintDuplex duplex)
{
const char *str;
switch (duplex)
{
default:
case GTK_PRINT_DUPLEX_SIMPLEX:
str = "simplex";
break;
case GTK_PRINT_DUPLEX_HORIZONTAL:
str = "horizontal";
break;
case GTK_PRINT_DUPLEX_VERTICAL:
str = "vertical";
break;
}
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_DUPLEX, str);
}
GtkPrintQuality
gtk_print_settings_get_quality (GtkPrintSettings *settings)
{
const char *val;
val = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_QUALITY);
if (val == NULL || (strcmp (val, "normal") == 0))
return GTK_PRINT_QUALITY_NORMAL;
if (strcmp (val, "high") == 0)
return GTK_PRINT_QUALITY_HIGH;
if (strcmp (val, "low") == 0)
return GTK_PRINT_QUALITY_LOW;
if (strcmp (val, "draft") == 0)
return GTK_PRINT_QUALITY_DRAFT;
return GTK_PRINT_QUALITY_NORMAL;
}
void
gtk_print_settings_set_quality (GtkPrintSettings *settings,
GtkPrintQuality quality)
{
const char *str;
switch (quality)
{
default:
case GTK_PRINT_QUALITY_NORMAL:
str = "normal";
break;
case GTK_PRINT_QUALITY_HIGH:
str = "high";
break;
case GTK_PRINT_QUALITY_LOW:
str = "low";
break;
case GTK_PRINT_QUALITY_DRAFT:
str = "draft";
break;
}
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_QUALITY, str);
}
GtkPageSet
gtk_print_settings_get_page_set (GtkPrintSettings *settings)
{
const char *val;
val = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_PAGE_SET);
if (val == NULL || (strcmp (val, "all") == 0))
return GTK_PAGE_SET_ALL;
if (strcmp (val, "even") == 0)
return GTK_PAGE_SET_EVEN;
if (strcmp (val, "odd") == 0)
return GTK_PAGE_SET_ODD;
return GTK_PAGE_SET_ALL;
}
void
gtk_print_settings_set_page_set (GtkPrintSettings *settings,
GtkPageSet page_set)
{
const char *str;
switch (page_set)
{
default:
case GTK_PAGE_SET_ALL:
str = "all";
break;
case GTK_PAGE_SET_EVEN:
str = "even";
break;
case GTK_PAGE_SET_ODD:
str = "odd";
break;
}
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PAGE_SET, str);
}
int
gtk_print_settings_get_num_copies (GtkPrintSettings *settings)
{
return gtk_print_settings_get_int_with_default (settings, GTK_PRINT_SETTINGS_NUM_COPIES, 1);
}
void
gtk_print_settings_set_num_copies (GtkPrintSettings *settings,
int num_copies)
{
gtk_print_settings_set_int (settings, GTK_PRINT_SETTINGS_NUM_COPIES,
num_copies);
}
int
gtk_print_settings_get_number_up (GtkPrintSettings *settings)
{
return gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_NUMBER_UP);
}
void
gtk_print_settings_set_number_up (GtkPrintSettings *settings,
int number_up)
{
gtk_print_settings_set_int (settings, GTK_PRINT_SETTINGS_NUMBER_UP,
number_up);
}
int
gtk_print_settings_get_resolution (GtkPrintSettings *settings)
{
return gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_RESOLUTION);
}
void
gtk_print_settings_set_resolution (GtkPrintSettings *settings,
int resolution)
{
gtk_print_settings_set_int (settings, GTK_PRINT_SETTINGS_RESOLUTION,
resolution);
}
double
gtk_print_settings_get_scale (GtkPrintSettings *settings)
{
return gtk_print_settings_get_double_with_default (settings,
GTK_PRINT_SETTINGS_SCALE,
100.0);
}
void
gtk_print_settings_set_scale (GtkPrintSettings *settings,
double scale)
{
gtk_print_settings_set_double (settings, GTK_PRINT_SETTINGS_SCALE,
scale);
}
gboolean
gtk_print_settings_get_print_to_file (GtkPrintSettings *settings)
{
return gtk_print_settings_get_bool (settings,
GTK_PRINT_SETTINGS_PRINT_TO_FILE);
}
void
gtk_print_settings_set_print_to_file (GtkPrintSettings *settings,
gboolean print_to_file)
{
gtk_print_settings_set_bool (settings,
GTK_PRINT_SETTINGS_PRINT_TO_FILE,
print_to_file);
}
GtkPrintPages
gtk_print_settings_get_print_pages (GtkPrintSettings *settings)
{
const char *val;
val = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_PRINT_PAGES);
if (val == NULL || (strcmp (val, "all") == 0))
return GTK_PRINT_PAGES_ALL;
if (strcmp (val, "current") == 0)
return GTK_PRINT_PAGES_CURRENT;
if (strcmp (val, "ranges") == 0)
return GTK_PRINT_PAGES_RANGES;
return GTK_PRINT_PAGES_ALL;
}
void
gtk_print_settings_set_print_pages (GtkPrintSettings *settings,
GtkPrintPages print_pages)
{
const char *str;
switch (print_pages)
{
default:
case GTK_PRINT_PAGES_ALL:
str = "all";
break;
case GTK_PRINT_PAGES_CURRENT:
str = "current";
break;
case GTK_PRINT_PAGES_RANGES:
str = "ranges";
break;
}
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PRINT_PAGES, str);
}
GtkPageRange *
gtk_print_settings_get_page_ranges (GtkPrintSettings *settings,
int *num_ranges)
{
const char *val;
gchar **range_strs;
GtkPageRange *ranges;
int i, n;
val = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_PAGE_RANGES);
if (val == NULL)
{
*num_ranges = 0;
return NULL;
}
range_strs = g_strsplit (val, ",", 0);
for (i = 0; range_strs[i] != NULL; i++)
;
n = i;
ranges = g_new0 (GtkPageRange, n);
for (i = 0; i < n; i++)
{
int start, end;
char *str;
start = (int)strtol (range_strs[i], &str, 10);
end = start;
if (*str == '-')
{
str++;
end = (int)strtol (str, NULL, 10);
if (end < start)
end = start;
}
ranges[i].start = start;
ranges[i].end = end;
}
*num_ranges = n;
return ranges;
}
void
gtk_print_settings_set_page_ranges (GtkPrintSettings *settings,
GtkPageRange *page_ranges,
int num_ranges)
{
GString *s;
int i;
s = g_string_new ("");
for (i = 0; i < num_ranges; i++)
{
if (page_ranges[i].start == page_ranges[i].end)
g_string_append_printf (s, "%d", page_ranges[i].start);
else
g_string_append_printf (s, "%d-%d",
page_ranges[i].start,
page_ranges[i].end);
if (i < num_ranges - 1)
g_string_append (s, ",");
}
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_PAGE_RANGES,
s->str);
g_string_free (s, TRUE);
}
const char *
gtk_print_settings_get_default_source (GtkPrintSettings *settings)
{
return gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE);
}
void
gtk_print_settings_set_default_source (GtkPrintSettings *settings,
const char *default_source)
{
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE, default_source);
}
const char *
gtk_print_settings_get_media_type (GtkPrintSettings *settings)
{
return gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_MEDIA_TYPE);
}
/* The set of media types is defined in PWG 5101.1-2002 PWG */
void
gtk_print_settings_set_media_type (GtkPrintSettings *settings,
const char *media_type)
{
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_MEDIA_TYPE, media_type);
}
const char *
gtk_print_settings_get_dither (GtkPrintSettings *settings)
{
return gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_DITHER);
}
void
gtk_print_settings_set_dither (GtkPrintSettings *settings,
const char *dither)
{
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_DITHER, dither);
}
const char *
gtk_print_settings_get_finishings (GtkPrintSettings *settings)
{
return gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_FINISHINGS);
}
void
gtk_print_settings_set_finishings (GtkPrintSettings *settings,
const char *finishings)
{
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_FINISHINGS, finishings);
}
const char *
gtk_print_settings_get_output_bin (GtkPrintSettings *settings)
{
return gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_OUTPUT_BIN);
}
void
gtk_print_settings_set_output_bin (GtkPrintSettings *settings,
const char *output_bin)
{
gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_OUTPUT_BIN, output_bin);
}

196
gtk/gtkprintsettings.h Normal file
View File

@@ -0,0 +1,196 @@
/* EGG - The GIMP Toolkit
* gtkprintsettings.h: Print Settings
* Copyright (C) 2006, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_SETTINGS_H__
#define __GTK_PRINT_SETTINGS_H__
#include <glib-object.h>
#include "gtkpapersize.h"
G_BEGIN_DECLS
typedef struct _GtkPrintSettings GtkPrintSettings;
#define GTK_TYPE_PRINT_SETTINGS (gtk_print_settings_get_type ())
#define GTK_PRINT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_SETTINGS, GtkPrintSettings))
#define GTK_IS_PRINT_SETTINGS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_SETTINGS))
typedef void (*GtkPrintSettingsFunc) (const char *key,
const char *value,
gpointer user_data);
typedef struct {
int start;
int end;
} GtkPageRange;
GType gtk_print_settings_get_type (void);
GtkPrintSettings *gtk_print_settings_new (void);
GtkPrintSettings *gtk_print_settings_copy (GtkPrintSettings *other);
gboolean gtk_print_settings_has_key (GtkPrintSettings *settings,
const char *key);
const char * gtk_print_settings_get (GtkPrintSettings *settings,
const char *key);
void gtk_print_settings_set (GtkPrintSettings *settings,
const char *key,
const char *value);
void gtk_print_settings_unset (GtkPrintSettings *settings,
const char *key);
void gtk_print_settings_foreach (GtkPrintSettings *settings,
GtkPrintSettingsFunc func,
gpointer user_data);
gboolean gtk_print_settings_get_bool (GtkPrintSettings *settings,
const char *key);
void gtk_print_settings_set_bool (GtkPrintSettings *settings,
const char *key,
gboolean value);
double gtk_print_settings_get_double (GtkPrintSettings *settings,
const char *key);
double gtk_print_settings_get_double_with_default (GtkPrintSettings *settings,
const char *key,
double def);
void gtk_print_settings_set_double (GtkPrintSettings *settings,
const char *key,
double value);
double gtk_print_settings_get_length (GtkPrintSettings *settings,
const char *key,
GtkUnit unit);
void gtk_print_settings_set_length (GtkPrintSettings *settings,
const char *key,
double value,
GtkUnit unit);
int gtk_print_settings_get_int (GtkPrintSettings *settings,
const char *key);
int gtk_print_settings_get_int_with_default (GtkPrintSettings *settings,
const char *key,
int def);
void gtk_print_settings_set_int (GtkPrintSettings *settings,
const char *key,
int value);
#define GTK_PRINT_SETTINGS_PRINTER "printer"
#define GTK_PRINT_SETTINGS_ORIENTATION "orientation"
#define GTK_PRINT_SETTINGS_PAPER_FORMAT "paper-format"
#define GTK_PRINT_SETTINGS_PAPER_WIDTH "paper-width"
#define GTK_PRINT_SETTINGS_PAPER_HEIGHT "paper-height"
#define GTK_PRINT_SETTINGS_NUM_COPIES "num-copies"
#define GTK_PRINT_SETTINGS_DEFAULT_SOURCE "default-source"
#define GTK_PRINT_SETTINGS_QUALITY "quality"
#define GTK_PRINT_SETTINGS_RESOLUTION "resolution"
#define GTK_PRINT_SETTINGS_USE_COLOR "use-color"
#define GTK_PRINT_SETTINGS_DUPLEX "duplex"
#define GTK_PRINT_SETTINGS_COLLATE "collate"
#define GTK_PRINT_SETTINGS_REVERSE "reverse"
#define GTK_PRINT_SETTINGS_MEDIA_TYPE "media-type"
#define GTK_PRINT_SETTINGS_DITHER "dither"
#define GTK_PRINT_SETTINGS_SCALE "scale"
#define GTK_PRINT_SETTINGS_PRINT_PAGES "print-pages"
#define GTK_PRINT_SETTINGS_PAGE_RANGES "page-ranges"
#define GTK_PRINT_SETTINGS_PAGE_SET "page-set"
#define GTK_PRINT_SETTINGS_PRINT_TO_FILE "print-to-file"
#define GTK_PRINT_SETTINGS_FINISHINGS "finishings"
#define GTK_PRINT_SETTINGS_NUMBER_UP "number-up"
#define GTK_PRINT_SETTINGS_OUTPUT_BIN "output-bin"
#define GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION "win32-driver-version"
#define GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA "win32-driver-extra"
/* Helpers: */
const char * gtk_print_settings_get_printer (GtkPrintSettings *settings);
void gtk_print_settings_set_printer (GtkPrintSettings *settings,
const char *printer);
GtkPageOrientation gtk_print_settings_get_orientation (GtkPrintSettings *settings);
void gtk_print_settings_set_orientation (GtkPrintSettings *settings,
GtkPageOrientation orientation);
GtkPaperSize * gtk_print_settings_get_paper_size (GtkPrintSettings *settings);
void gtk_print_settings_set_paper_size (GtkPrintSettings *settings,
GtkPaperSize *paper_size);
double gtk_print_settings_get_paper_width (GtkPrintSettings *settings,
GtkUnit unit);
void gtk_print_settings_set_paper_width (GtkPrintSettings *settings,
double width,
GtkUnit unit);
double gtk_print_settings_get_paper_height (GtkPrintSettings *settings,
GtkUnit unit);
void gtk_print_settings_set_paper_height (GtkPrintSettings *settings,
double width,
GtkUnit unit);
gboolean gtk_print_settings_get_use_color (GtkPrintSettings *settings);
void gtk_print_settings_set_use_color (GtkPrintSettings *settings,
gboolean use_color);
gboolean gtk_print_settings_get_collate (GtkPrintSettings *settings);
void gtk_print_settings_set_collate (GtkPrintSettings *settings,
gboolean collate);
gboolean gtk_print_settings_get_reverse (GtkPrintSettings *settings);
void gtk_print_settings_set_reverse (GtkPrintSettings *settings,
gboolean reverse);
GtkPrintDuplex gtk_print_settings_get_duplex (GtkPrintSettings *settings);
void gtk_print_settings_set_duplex (GtkPrintSettings *settings,
GtkPrintDuplex duplex);
GtkPrintQuality gtk_print_settings_get_quality (GtkPrintSettings *settings);
void gtk_print_settings_set_quality (GtkPrintSettings *settings,
GtkPrintQuality quality);
int gtk_print_settings_get_num_copies (GtkPrintSettings *settings);
void gtk_print_settings_set_num_copies (GtkPrintSettings *settings,
int num_copies);
int gtk_print_settings_get_number_up (GtkPrintSettings *settings);
void gtk_print_settings_set_number_up (GtkPrintSettings *settings,
int number_up);
int gtk_print_settings_get_resolution (GtkPrintSettings *settings);
void gtk_print_settings_set_resolution (GtkPrintSettings *settings,
int resolution);
double gtk_print_settings_get_scale (GtkPrintSettings *settings);
void gtk_print_settings_set_scale (GtkPrintSettings *settings,
double scale);
gboolean gtk_print_settings_get_print_to_file (GtkPrintSettings *settings);
void gtk_print_settings_set_print_to_file (GtkPrintSettings *settings,
gboolean print_to_file);
GtkPrintPages gtk_print_settings_get_print_pages (GtkPrintSettings *settings);
void gtk_print_settings_set_print_pages (GtkPrintSettings *settings,
GtkPrintPages pages);
GtkPageRange * gtk_print_settings_get_page_ranges (GtkPrintSettings *settings,
int *num_ranges);
void gtk_print_settings_set_page_ranges (GtkPrintSettings *settings,
GtkPageRange *page_ranges,
int num_ranges);
GtkPageSet gtk_print_settings_get_page_set (GtkPrintSettings *settings);
void gtk_print_settings_set_page_set (GtkPrintSettings *settings,
GtkPageSet page_set);
const char * gtk_print_settings_get_default_source (GtkPrintSettings *settings);
void gtk_print_settings_set_default_source (GtkPrintSettings *settings,
const char *default_source);
const char * gtk_print_settings_get_media_type (GtkPrintSettings *settings);
void gtk_print_settings_set_media_type (GtkPrintSettings *settings,
const char *media_type);
const char * gtk_print_settings_get_dither (GtkPrintSettings *settings);
void gtk_print_settings_set_dither (GtkPrintSettings *settings,
const char *dither);
const char * gtk_print_settings_get_finishings (GtkPrintSettings *settings);
void gtk_print_settings_set_finishings (GtkPrintSettings *settings,
const char *finishings);
const char * gtk_print_settings_get_output_bin (GtkPrintSettings *settings);
void gtk_print_settings_set_output_bin (GtkPrintSettings *settings,
const char *output_bin);
G_END_DECLS
#endif /* __GTK_PRINT_SETTINGS_H__ */

2256
gtk/gtkprintunixdialog.c Normal file

File diff suppressed because it is too large Load Diff

79
gtk/gtkprintunixdialog.h Normal file
View File

@@ -0,0 +1,79 @@
/* GtkPrintUnixDialog
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_UNIX_DIALOG_H__
#define __GTK_PRINT_UNIX_DIALOG_H__
#include "gtkprinter.h"
#include "gtkprintsettings.h"
#include "gtkpagesetup.h"
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define GTK_TYPE_PRINT_UNIX_DIALOG (gtk_print_unix_dialog_get_type ())
#define GTK_PRINT_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_UNIX_DIALOG, GtkPrintUnixDialog))
#define GTK_PRINT_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_UNIX_DIALOG, GtkPrintUnixDialogClass))
#define GTK_IS_PRINT_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_UNIX_DIALOG))
#define GTK_IS_PRINT_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_UNIX_DIALOG))
#define GTK_PRINT_UNIX_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_UNIX_DIALOG, GtkPrintUnixDialogClass))
typedef struct _GtkPrintUnixDialog GtkPrintUnixDialog;
typedef struct _GtkPrintUnixDialogClass GtkPrintUnixDialogClass;
typedef struct GtkPrintUnixDialogPrivate GtkPrintUnixDialogPrivate;
struct _GtkPrintUnixDialog
{
GtkDialog parent_instance;
GtkPrintUnixDialogPrivate *priv;
};
struct _GtkPrintUnixDialogClass
{
GtkDialogClass parent_class;
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
void (*_gtk_reserved3) (void);
void (*_gtk_reserved4) (void);
void (*_gtk_reserved5) (void);
void (*_gtk_reserved6) (void);
void (*_gtk_reserved7) (void);
};
GType gtk_print_unix_dialog_get_type (void) G_GNUC_CONST;
GtkWidget * gtk_print_unix_dialog_new (const gchar *title,
GtkWindow *parent);
void gtk_print_unix_dialog_set_page_setup (GtkPrintUnixDialog *dialog,
GtkPageSetup *page_setup);
void gtk_print_unix_dialog_set_current_page (GtkPrintUnixDialog *dialog,
int current_page);
void gtk_print_unix_dialog_set_settings (GtkPrintUnixDialog *dialog,
GtkPrintSettings *settings);
GtkPrintSettings *gtk_print_unix_dialog_get_settings (GtkPrintUnixDialog *dialog);
GtkPrinter * gtk_print_unix_dialog_get_selected_printer (GtkPrintUnixDialog *dialog);
G_END_DECLS
#endif /* __GTK_PRINT_UNIX_DIALOG_H__ */

192
gtk/paper_names.c Normal file
View File

@@ -0,0 +1,192 @@
#define N_(s) s
/* The paper size names are from:
* PWG 5101.1-2002 PWG: Standard for Media Standardized Names
*
* The PPD names come from the PPD specification.
*/
static const PaperInfo standard_names[] = {
/* sorted by name, remember to sort when changing */
{"asme_f", "28x40in", N_("asme_f")}, /* f 5 e1 */
{"iso_2a0", "1189x1682mm", N_("A0x2")},
{"iso_a0", "841x1189mm", N_("A0"), "A0"},
{"iso_a0x3", "1189x2523mm", N_("A0x3")},
{"iso_a1", "594x841mm", N_("A1"), "A1"},
{"iso_a10", "26x37mm", N_("A10"), "A10"},
{"iso_a1x3", "841x1783mm", N_("A1x3")},
{"iso_a1x4", "841x2378mm", N_("A1x4")},
{"iso_a2", "420x594mm", N_("A2"), "A2"},
{"iso_a2x3", "594x1261mm", N_("A2x3")},
{"iso_a2x4", "594x1682mm", N_("A2x4")},
{"iso_a2x5", "594x2102mm", N_("A2x5")},
{"iso_a3", "297x420mm", N_("A3"), "A3"},
{"iso_a3-extra", "322x445mm", N_("A3 Extra"), "A3Extra"},
{"iso_a3x3", "420x891mm", N_("A3x3")},
{"iso_a3x4", "420x1189mm", N_("A3x4")},
{"iso_a3x5", "420x1486mm", N_("A3x5")},
{"iso_a3x6", "420x1783mm", N_("A3x6")},
{"iso_a3x7", "420x2080mm", N_("A3x7")},
{"iso_a4", "210x297mm", N_("A4"), "A4"},
{"iso_a4-extra", "235.5x322.3mm", N_("A4 Extra"), "A4Extra"},
{"iso_a4-tab", "225x297mm", N_("A4 Tab")},
{"iso_a4x3", "297x630mm", N_("A4x3")},
{"iso_a4x4", "297x841mm", N_("A4x4")},
{"iso_a4x5", "297x1051mm", N_("A4x5")},
{"iso_a4x6", "297x1261mm", N_("A4x6")},
{"iso_a4x7", "297x1471mm", N_("A4x7")},
{"iso_a4x8", "297x1682mm", N_("A4x8")},
{"iso_a4x9", "297x1892mm", N_("A4x9")},
{"iso_a5", "148x210mm", N_("A5"), "A5"},
{"iso_a5-extra", "174x235mm", N_("A5 Extra"), "A5Extra"},
{"iso_a6", "105x148mm", N_("A6"), "A6"},
{"iso_a7", "74x105mm", N_("A7"), "A7"},
{"iso_a8", "52x74mm", N_("A8"), "A8"},
{"iso_a9", "37x52mm", N_("A9"), "A9"},
{"iso_b0", "1000x1414mm", N_("B0"), "ISOB0"},
{"iso_b1", "707x1000mm", N_("B1"), "ISOB1"},
{"iso_b10", "31x44mm", N_("B10"), "ISOB10"},
{"iso_b2", "500x707mm", N_("B2"), "ISOB2"},
{"iso_b3", "353x500mm", N_("B3"), "ISOB3"},
{"iso_b4", "250x353mm", N_("B4"), "ISOB4"},
{"iso_b5", "176x250mm", N_("B5"), "ISOB5"},
{"iso_b5-extra", "201x276mm", N_("B5 Extra"), "ISOB5Extra"},
{"iso_b6", "125x176mm", N_("B6"), "ISOB6"},
{"iso_b6c4", "125x324mm", N_("B6/C4")}, /* b6/c4 Envelope */
{"iso_b7", "88x125mm", N_("B7"), "ISOB7"},
{"iso_b8", "62x88mm", N_("B8"), "ISOB8"},
{"iso_b9", "44x62mm", N_("B9"), "ISOB9"},
{"iso_c0", "917x1297mm", N_("C0"), "EnvC0"},
{"iso_c1", "648x917mm", N_("C1"), "EnvC1"},
{"iso_c10", "28x40mm", N_("C10"), "EnvC10"},
{"iso_c2", "458x648mm", N_("C2"), "EnvC2"},
{"iso_c3", "324x458mm", N_("C3"), "EnvC3"},
{"iso_c4", "229x324mm", N_("C4"), "EnvC4"},
{"iso_c5", "162x229mm", N_("C5"), "EnvC5"},
{"iso_c6", "114x162mm", N_("C6"), "EnvC6"},
{"iso_c6c5", "114x229mm", N_("C6/C5"), "EnvC65"},
{"iso_c7", "81x114mm", N_("C7"), "EnvC7"},
{"iso_c7c6", "81x162mm", N_("C7/C6")}, /* c7/c6 Envelope */
{"iso_c8", "57x81mm", N_("C8"), "EnvC8"},
{"iso_c9", "40x57mm", N_("C9"), "EnvC9"},
{"iso_dl", "110x220mm", N_("DL Envelope"), "EnvDL"}, /* iso-designated 1, 2 designated-long, dl Envelope */
{"iso_ra0", "860x1220mm", N_("RA0")},
{"iso_ra1", "610x860mm", N_("RA1")},
{"iso_ra2", "430x610mm", N_("RA2")},
{"iso_sra0", "900x1280mm", N_("SRA0")},
{"iso_sra1", "640x900mm", N_("SRA1")},
{"iso_sra2", "450x640mm", N_("SRA2")},
{"jis_b0", "1030x1456mm", N_("JB0"), "B0"},
{"jis_b1", "728x1030mm", N_("JB1"), "B1"},
{"jis_b10", "32x45mm", N_("JB10"), "B10"},
{"jis_b2", "515x728mm", N_("JB2"), "B2"},
{"jis_b3", "364x515mm", N_("JB3"), "B3"},
{"jis_b4", "257x364mm", N_("JB4"), "B4"},
{"jis_b5", "182x257mm", N_("JB5"), "B5"},
{"jis_b6", "128x182mm", N_("JB6"), "B6"},
{"jis_b7", "91x128mm", N_("JB7"), "B7"},
{"jis_b8", "64x91mm", N_("JB8"), "B8"},
{"jis_b9", "45x64mm", N_("JB9"), "B9"},
{"jis_exec", "216x330mm", N_("jis exec")},
{"jpn_chou2", "111.1x146mm", N_("Choukei 2 Envelope")},
{"jpn_chou3", "120x235mm", N_("Choukei 3 Envelope"), "EnvChou3"},
{"jpn_chou4", "90x205mm", N_("Choukei 4 Envelope"), "EnvChou4"},
{"jpn_hagaki", "100x148mm", N_("hagaki (postcard)"), "Postcard"},
{"jpn_kahu", "240x322.1mm", N_("kahu Envelope")},
{"jpn_kaku2", "240x332mm", N_("kaku2 Envelope"), "EnvKaku2"},
{"jpn_oufuku", "148x200mm", N_("oufuku (reply postcard)"), "DoublePostcard"},
{"jpn_you4", "105x235mm", N_("you4 Envelope")},
{"na_10x11", "10x11in", N_("10x11"), "10x11"},
{"na_10x13", "10x13in", N_("10x13"), "10x13"},
{"na_10x14", "10x14in", N_("10x14"), "10x14"},
{"na_10x15", "10x15in", N_("10x15")},
{"na_10x15", "10x15in", N_("10x15")},
{"na_11x12", "11x12in", N_("11x12"), "12x11"},
{"na_11x15", "11x15in", N_("11x15"), "15x11"},
{"na_12x19", "12x19in", N_("12x19")},
{"na_5x7", "5x7in", N_("5x7")},
{"na_6x9", "6x9in", N_("6x9 Envelope")},
{"na_7x9", "7x9in", N_("7x9 Envelope"), "7x9"},
{"na_9x11", "9x11in", N_("9x11 Envelope"), "9x11"},
{"na_a2", "4.375x5.75in", N_("a2 Envelope")},
{"na_arch-a", "9x12in", N_("Arch A"), "ARCHA"},
{"na_arch-b", "12x18in", N_("Arch B"), "ARCHB"},
{"na_arch-c", "18x24in", N_("Arch C"), "ARCHC"},
{"na_arch-d", "24x36in", N_("Arch D"), "ARCHD"},
{"na_arch-e", "36x48in", N_("Arch E"), "ARCHE"},
{"na_b-plus", "12x19.17in", N_("b-plus")},
{"na_c", "17x22in", N_("c"), "AnsiC"},
{"na_c5", "6.5x9.5in", N_("c5 Envelope")},
{"na_d", "22x34in", N_("d"), "AnsiD"},
{"na_e", "34x44in", N_("e"), "AnsiE"},
{"na_edp", "11x14in", N_("edp")},
{"na_eur-edp", "12x14in", N_("European edp")},
{"na_executive", "7.25x10.5in", N_("Executive"), "Executive"},
{"na_f", "44x68in", N_("f")},
{"na_fanfold-eur", "8.5x12in", N_("FanFold European"), "FanFoldGerman"},
{"na_fanfold-us", "11x14.875in", N_("FanFold US"), "FanFoldUS"},
{"na_foolscap", "8.5x13in", N_("FanFold German Legal"), "FanFoldGermanLegal"}, /* foolscap, german-legal-fanfold */
{"na_govt-legal", "8x13in", N_("Government Legal")},
{"na_govt-letter", "8x10in", N_("Government Letter"), "8x10"},
{"na_index-3x5", "3x5in", N_("Index 3x5")},
{"na_index-4x6", "4x6in", N_("Index 4x6 (postcard)")},
{"na_index-4x6-ext", "6x8in", N_("Index 4x6 ext")},
{"na_index-5x8", "5x8in", N_("Index 5x8")},
{"na_invoice", "5.5x8.5in", N_("Invoice"), "Statement"}, /* invoice, statement, mini, half-letter */
{"na_ledger", "11x17in", N_("Tabloid"), "Ledger"}, /* tabloid, engineering-b */
{"na_legal", "8.5x14in", N_("US Legal"), "Legal"},
{"na_legal-extra", "9.5x15in", N_("US Legal Extra"), "LegalExtra"},
{"na_letter", "8.5x11in", N_("US Letter"), "Letter"},
{"na_letter-extra", "9.5x12in", N_("US Letter Extra"), "LetterExtra"},
{"na_letter-plus", "8.5x12.69in", N_("US Letter Plus"), "LetterPlus"},
{"na_monarch", "3.875x7.5in", N_("Monarch Envelope"), "EnvMonarch"},
{"na_number-10", "4.125x9.5in", N_("#10 Envelope"), "Env10"}, /* na-number-10-envelope 1, 2 comm-10 Envelope */
{"na_number-11", "4.5x10.375in", N_("#11 Eenvelope"), "Env11"}, /* number-11 Envelope */
{"na_number-12", "4.75x11in", N_("#12 Envelope"), "Env12"}, /* number-12 Envelope */
{"na_number-14", "5x11.5in", N_("#14 Envelope"), "Env14"}, /* number-14 Envelope */
{"na_number-9", "3.875x8.875in", N_("#9 Envelope"), "Env9"},
{"na_personal", "3.625x6.5in", N_("Personal Envelope"), "EnvPersonal"},
{"na_quarto", "8.5x10.83in", N_("Quarto"), "Quarto"},
{"na_super-a", "8.94x14in", N_("Super A"), "SuperA"},
{"na_super-b", "13x19in", N_("Super B"), "SuperB"},
{"na_wide-format", "30x42in", N_("Wide Format")},
{"om_dai-pa-kai", "275x395mm", N_("Dai-pa-kai")},
{"om_folio", "210x330mm", N_("Folio"), "Folio"},
{"om_folio-sp", "215x315mm", N_("Folio sp")},
{"om_invite", "220x220mm", N_("Invite Envelope"), "EnvInvite"},
{"om_italian", "110x230mm", N_("Italian Envelope"), "EnvItalian"},
{"om_juuro-ku-kai", "198x275mm", N_("juuro-ku-kai")},
{"om_pa-kai", "267x389mm", N_("pa-kai")},
{"om_postfix", "114x229mm", N_("Postfix Envelope")},
{"om_small-photo", "100x150mm", N_("Small Photo")},
{"prc_1", "102x165mm", N_("prc1 Envelope"), "EnvPRC1"},
{"prc_10", "324x458mm", N_("prc10 Envelope"), "EnvPRC10"},
{"prc_16k", "146x215mm", N_("prc 16k"), "PRC16K"},
{"prc_2", "102x176mm", N_("prc2 Envelope"), "EnvPRC2"},
{"prc_3", "125x176mm", N_("prc3 Envelope"), "EnvPRC3"},
{"prc_32k", "97x151mm", N_("prc 32k"), "PRC32K"},
{"prc_4", "110x208mm", N_("prc4 Envelope"), "EnvPRC4"},
{"prc_5", "110x220mm", N_("prc5 Envelope"), "EnvPRC5"},
{"prc_6", "120x320mm", N_("prc6 Envelope"), "EnvPRC6"},
{"prc_7", "160x230mm", N_("prc7 Envelope"), "EnvPRC7"},
{"prc_8", "120x309mm", N_("prc8 Envelope"), "EnvPRC8"},
{"roc_16k", "7.75x10.75in", N_("ROC 16k")},
{"roc_8k", "10.75x15.5in", N_("ROC 8k")},
};
/* Some page sizes have multiple PPD names in use.
* The array above only contails the prefered one,
* and this array fills out with the duplicates.
*/
const struct {
const char *ppd_name;
const char *standard_name;
} extra_ppd_names[] = {
/* sorted by ppd_name, remember to sort when changing */
{ "C4", "iso_c4"},
{ "C5", "iso_c5"},
{ "C6", "iso_c6"},
{ "Comm10", "na_number-10"},
{ "DL", "iso_dl"},
{ "Monarch", "na_monarch"},
};

View File

@@ -1 +1 @@
SUBDIRS=input engines
SUBDIRS=input engines printbackends

View File

@@ -0,0 +1,2 @@
SUBDIRS=cups
# pdf lpr

View File

@@ -0,0 +1,33 @@
if OS_WIN32
no_undefined = -no-undefined
endif
INCLUDES = \
-I$(top_srcdir) \
-I$(top_srcdir)/gtk \
-I$(top_builddir)/gtk \
-I$(top_srcdir)/gdk \
$(CUPS_CFLAGS) \
-DGTK_PRINT_BACKEND_ENABLE_UNSUPPORTED \
$(GTK_DEP_CFLAGS)
LDADDS = \
$(GTK_DEP_LIBS) \
$(top_builddir)/gtk/$(gtktargetlib)
backenddir = $(libdir)/gtk-2.0/$(GTK_BINARY_VERSION)/printbackends
backend_LTLIBRARIES = libcups.la
libcups_la_SOURCES = \
gtkprintbackendcups.c \
gtkprintercups.c \
gtkcupsutils.c
noinst_HEADERS = \
gtkprintbackendcups.h \
gtkprintercups.h \
gtkcupsutils.h
libcups_la_LDFLAGS = -avoid-version -module $(no_undefined)
libcups_la_LIBADD = $(LDADDS) $(CUPS_LIBS)

View File

@@ -0,0 +1,922 @@
/* GTK - The GIMP Toolkit
* gtkcupsutils.h: Statemachine implementation of POST and GET
* cup calls which can be used to create a non-blocking cups API
* Copyright (C) 2003, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "gtkcupsutils.h"
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <time.h>
typedef void (*GtkCupsRequestStateFunc) (GtkCupsRequest *request);
static void _connect (GtkCupsRequest *request);
static void _post_send (GtkCupsRequest *request);
static void _post_write_request (GtkCupsRequest *request);
static void _post_write_data (GtkCupsRequest *request);
static void _post_check (GtkCupsRequest *request);
static void _post_read_response (GtkCupsRequest *request);
static void _get_send (GtkCupsRequest *request);
static void _get_check (GtkCupsRequest *request);
static void _get_read_data (GtkCupsRequest *request);
struct _GtkCupsResult
{
gchar *error_msg;
ipp_t *ipp_response;
gint is_error : 1;
gint is_ipp_response : 1;
};
#define _GTK_CUPS_MAX_ATTEMPTS 10
#define _GTK_CUPS_MAX_CHUNK_SIZE 8192
GtkCupsRequestStateFunc post_states[] = {_connect,
_post_send,
_post_write_request,
_post_write_data,
_post_check,
_post_read_response};
GtkCupsRequestStateFunc get_states[] = {_connect,
_get_send,
_get_check,
_get_read_data};
static void
gtk_cups_result_set_error (GtkCupsResult *result,
const char *error_msg,
...)
{
va_list args;
result->is_ipp_response = FALSE;
result->is_error = TRUE;
va_start (args, error_msg);
result->error_msg = g_strdup_vprintf (error_msg, args);
va_end (args);
}
GtkCupsRequest *
gtk_cups_request_new (http_t *connection,
GtkCupsRequestType req_type,
gint operation_id,
gint data_fd,
const char *server,
const char *resource)
{
GtkCupsRequest *request;
cups_lang_t *language;
request = g_new0 (GtkCupsRequest, 1);
request->result = g_new0 (GtkCupsResult, 1);
request->result->error_msg = NULL;
request->result->ipp_response = NULL;
request->result->is_error = FALSE;
request->result->is_ipp_response = FALSE;
request->type = req_type;
request->state = GTK_CUPS_REQUEST_START;
if (server)
request->server = g_strdup (server);
else
request->server = g_strdup (cupsServer());
if (resource)
request->resource = g_strdup (resource);
else
request->resource = g_strdup ("/");
if (connection != NULL)
{
request->http = connection;
request->own_http = FALSE;
}
else
{
request->http = NULL;
request->http = httpConnectEncrypt (request->server, ippPort(), cupsEncryption());
if (request->http)
httpBlocking (request->http, 0);
request->own_http = TRUE;
}
request->last_status = HTTP_CONTINUE;
request->attempts = 0;
request->data_fd = data_fd;
request->ipp_request = ippNew();
request->ipp_request->request.op.operation_id = operation_id;
request->ipp_request->request.op.request_id = 1;
language = cupsLangDefault ();
gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset",
NULL, "utf-8");
gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language",
NULL, language->language);
cupsLangFree (language);
return request;
}
static void
gtk_cups_result_free (GtkCupsResult *result)
{
g_free (result->error_msg);
if (result->ipp_response)
ippDelete (result->ipp_response);
g_free (result);
}
void
gtk_cups_request_free (GtkCupsRequest *request)
{
if (request->own_http)
if (request->http)
httpClose (request->http);
if (request->ipp_request)
ippDelete (request->ipp_request);
g_free (request->server);
g_free (request->resource);
gtk_cups_result_free (request->result);
g_free (request);
}
gboolean
gtk_cups_request_read_write (GtkCupsRequest *request)
{
if (request->type == GTK_CUPS_POST)
post_states[request->state](request);
else if (request->type == GTK_CUPS_GET)
get_states[request->state](request);
if (request->attempts > _GTK_CUPS_MAX_ATTEMPTS &&
request->state != GTK_CUPS_REQUEST_DONE)
{
gtk_cups_result_set_error (request->result, "Too many failed attempts");
request->state = GTK_CUPS_REQUEST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
}
if (request->state == GTK_CUPS_REQUEST_DONE)
{
request->poll_state = GTK_CUPS_HTTP_IDLE;
return TRUE;
}
else
{
return FALSE;
}
}
GtkCupsPollState
gtk_cups_request_get_poll_state (GtkCupsRequest *request)
{
return request->poll_state;
}
GtkCupsResult *
gtk_cups_request_get_result (GtkCupsRequest *request)
{
return request->result;
}
void
gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
ipp_tag_t group,
ipp_tag_t tag,
const char *name,
const char *charset,
const char *value)
{
ippAddString (request->ipp_request,
group,
tag,
name,
charset,
value);
}
typedef struct
{
const char *name;
ipp_tag_t value_tag;
} ipp_option_t;
static const ipp_option_t ipp_options[] =
{
{ "blackplot", IPP_TAG_BOOLEAN },
{ "brightness", IPP_TAG_INTEGER },
{ "columns", IPP_TAG_INTEGER },
{ "copies", IPP_TAG_INTEGER },
{ "finishings", IPP_TAG_ENUM },
{ "fitplot", IPP_TAG_BOOLEAN },
{ "gamma", IPP_TAG_INTEGER },
{ "hue", IPP_TAG_INTEGER },
{ "job-k-limit", IPP_TAG_INTEGER },
{ "job-page-limit", IPP_TAG_INTEGER },
{ "job-priority", IPP_TAG_INTEGER },
{ "job-quota-period", IPP_TAG_INTEGER },
{ "landscape", IPP_TAG_BOOLEAN },
{ "media", IPP_TAG_KEYWORD },
{ "mirror", IPP_TAG_BOOLEAN },
{ "natural-scaling", IPP_TAG_INTEGER },
{ "number-up", IPP_TAG_INTEGER },
{ "orientation-requested", IPP_TAG_ENUM },
{ "page-bottom", IPP_TAG_INTEGER },
{ "page-left", IPP_TAG_INTEGER },
{ "page-ranges", IPP_TAG_RANGE },
{ "page-right", IPP_TAG_INTEGER },
{ "page-top", IPP_TAG_INTEGER },
{ "penwidth", IPP_TAG_INTEGER },
{ "ppi", IPP_TAG_INTEGER },
{ "prettyprint", IPP_TAG_BOOLEAN },
{ "printer-resolution", IPP_TAG_RESOLUTION },
{ "print-quality", IPP_TAG_ENUM },
{ "saturation", IPP_TAG_INTEGER },
{ "scaling", IPP_TAG_INTEGER },
{ "sides", IPP_TAG_KEYWORD },
{ "wrap", IPP_TAG_BOOLEAN }
};
static ipp_tag_t
_find_option_tag (const gchar *option)
{
int lower_bound, upper_bound, num_options;
int current_option;
ipp_tag_t result;
result = IPP_TAG_ZERO;
lower_bound = 0;
upper_bound = num_options = (int)(sizeof(ipp_options) / sizeof(ipp_options[0])) - 1;
while (1)
{
int match;
current_option = (int) (((upper_bound - lower_bound) / 2) + lower_bound);
match = strcasecmp(option, ipp_options[current_option].name);
if (match == 0)
{
result = ipp_options[current_option].value_tag;
return result;
}
else if (match < 0)
{
upper_bound = current_option - 1;
}
else
{
lower_bound = current_option + 1;
}
if (upper_bound == lower_bound && upper_bound == current_option)
return result;
if (upper_bound < 0)
return result;
if (lower_bound > num_options)
return result;
if (upper_bound < lower_bound)
return result;
}
}
void
gtk_cups_request_encode_option (GtkCupsRequest *request,
const gchar *option,
const gchar *value)
{
ipp_tag_t option_tag;
g_assert (option != NULL);
g_assert (value != NULL);
option_tag = _find_option_tag (option);
if (option_tag == IPP_TAG_ZERO)
{
option_tag = IPP_TAG_NAME;
if (strcasecmp (value, "true") == 0 ||
strcasecmp (value, "false") == 0)
{
option_tag = IPP_TAG_BOOLEAN;
}
}
switch (option_tag)
{
case IPP_TAG_INTEGER:
case IPP_TAG_ENUM:
ippAddInteger (request->ipp_request,
IPP_TAG_OPERATION,
option_tag,
option,
strtol (value, NULL, 0));
break;
case IPP_TAG_BOOLEAN:
{
char b;
b = 0;
if (!strcasecmp(value, "true") ||
!strcasecmp(value, "on") ||
!strcasecmp(value, "yes"))
b = 1;
ippAddBoolean(request->ipp_request,
IPP_TAG_OPERATION,
option,
b);
break;
}
case IPP_TAG_RANGE:
{
char *s;
int lower;
int upper;
if (*value == '-')
{
lower = 1;
s = (char *)value;
}
else
lower = strtol(value, &s, 0);
if (*s == '-')
{
if (s[1])
upper = strtol(s + 1, NULL, 0);
else
upper = 2147483647;
}
else
upper = lower;
ippAddRange (request->ipp_request,
IPP_TAG_OPERATION,
option,
lower,
upper);
break;
}
case IPP_TAG_RESOLUTION:
{
char *s;
int xres;
int yres;
ipp_res_t units;
xres = strtol(value, &s, 0);
if (*s == 'x')
yres = strtol(s + 1, &s, 0);
else
yres = xres;
if (strcasecmp(s, "dpc") == 0)
units = IPP_RES_PER_CM;
else
units = IPP_RES_PER_INCH;
ippAddResolution (request->ipp_request,
IPP_TAG_OPERATION,
option,
units,
xres,
yres);
break;
}
default:
ippAddString (request->ipp_request,
IPP_TAG_OPERATION,
option_tag,
option,
NULL,
value);
break;
}
}
static void
_connect (GtkCupsRequest *request)
{
request->poll_state = GTK_CUPS_HTTP_IDLE;
if (request->http == NULL)
{
request->http = httpConnectEncrypt (request->server, ippPort(), cupsEncryption());
if (request->http == NULL)
request->attempts++;
if (request->http)
httpBlocking (request->http, 0);
request->own_http = TRUE;
}
else
{
request->attempts = 0;
request->state++;
/* we always write to the socket after we get
the connection */
request->poll_state = GTK_CUPS_HTTP_WRITE;
}
}
static void
_post_send (GtkCupsRequest *request)
{
gchar length[255];
struct stat data_info;
request->poll_state = GTK_CUPS_HTTP_WRITE;
if (request->data_fd != 0)
{
fstat (request->data_fd, &data_info);
sprintf (length, "%lu", (unsigned long)ippLength(request->ipp_request) + data_info.st_size);
}
else
{
sprintf (length, "%lu", (unsigned long)ippLength(request->ipp_request));
}
httpClearFields(request->http);
httpSetField(request->http, HTTP_FIELD_CONTENT_LENGTH, length);
httpSetField(request->http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
httpSetField(request->http, HTTP_FIELD_AUTHORIZATION, request->http->authstring);
if (httpPost(request->http, request->resource))
{
if (httpReconnect(request->http))
{
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "Failed Post");
}
request->attempts++;
return;
}
request->attempts = 0;
request->state = GTK_CUPS_POST_WRITE_REQUEST;
request->ipp_request->state = IPP_IDLE;
}
static void
_post_write_request (GtkCupsRequest *request)
{
ipp_state_t ipp_status;
request->poll_state = GTK_CUPS_HTTP_WRITE;
ipp_status = ippWrite(request->http, request->ipp_request);
if (ipp_status == IPP_ERROR)
{
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "%s",ippErrorString (cupsLastError ()));
return;
}
if (ipp_status == IPP_DATA)
{
if (request->data_fd != 0)
request->state = GTK_CUPS_POST_WRITE_DATA;
else
{
request->state = GTK_CUPS_POST_CHECK;
request->poll_state = GTK_CUPS_HTTP_READ;
}
}
}
static void
_post_write_data (GtkCupsRequest *request)
{
ssize_t bytes;
char buffer[_GTK_CUPS_MAX_CHUNK_SIZE];
http_status_t http_status;
request->poll_state = GTK_CUPS_HTTP_WRITE;
if (httpCheck (request->http))
http_status = httpUpdate(request->http);
else
http_status = request->last_status;
request->last_status = http_status;
if (http_status == HTTP_CONTINUE || http_status == HTTP_OK)
{
/* send data */
bytes = read(request->data_fd, buffer, _GTK_CUPS_MAX_CHUNK_SIZE);
if (bytes == 0)
{
request->state = GTK_CUPS_POST_CHECK;
request->poll_state = GTK_CUPS_HTTP_READ;
request->attempts = 0;
return;
}
else if (bytes == -1)
{
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "Error reading from cache file: %s", strerror (errno));
return;
}
if (httpWrite(request->http, buffer, (int)bytes) < bytes)
{
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "Error writting to socket in Post %s", strerror (httpError (request->http)));
return;
}
}
else
{
request->attempts++;
}
}
static void
_post_check (GtkCupsRequest *request)
{
http_status_t http_status;
http_status = request->last_status;
request->poll_state = GTK_CUPS_HTTP_READ;
if (http_status == HTTP_CONTINUE)
{
goto again;
}
else if (http_status == HTTP_UNAUTHORIZED)
{
/* TODO: callout for auth */
g_warning ("NOT IMPLEMENTED: We need to prompt for authorization");
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "Can't prompt for authorization");
return;
}
else if (http_status == HTTP_ERROR)
{
#ifdef G_OS_WIN32
if (request->http->error != WSAENETDOWN &&
request->http->error != WSAENETUNREACH)
#else
if (request->http->error != ENETDOWN &&
request->http->error != ENETUNREACH)
#endif /* G_OS_WIN32 */
{
request->attempts++;
goto again;
}
else
{
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "Unknown HTTP error");
return;
}
}
/* TODO: detect ssl in configure.ac */
#if HAVE_SSL
else if (http_status == HTTP_UPGRADE_REQUIRED)
{
/* Flush any error message... */
httpFlush (request->http);
/* Reconnect... */
httpReconnect (request->http);
/* Upgrade with encryption... */
httpEncryption(request->http, HTTP_ENCRYPT_REQUIRED);
request->attempts++;
goto again;
}
#endif
else if (http_status != HTTP_OK)
{
int http_errno;
http_errno = httpError (request->http);
if (http_errno == EPIPE)
request->state = GTK_CUPS_POST_CONNECT;
else
{
request->state = GTK_CUPS_POST_DONE;
gtk_cups_result_set_error (request->result, "HTTP Error in POST %s", strerror (http_errno));
request->poll_state = GTK_CUPS_HTTP_IDLE;
httpFlush(request->http);
return;
}
request->poll_state = GTK_CUPS_HTTP_IDLE;
httpFlush(request->http);
request->last_status = HTTP_CONTINUE;
httpClose (request->http);
request->http = NULL;
return;
}
else
{
request->state = GTK_CUPS_POST_READ_RESPONSE;
return;
}
again:
http_status = HTTP_CONTINUE;
if (httpCheck (request->http))
http_status = httpUpdate (request->http);
request->last_status = http_status;
}
static void
_post_read_response (GtkCupsRequest *request)
{
ipp_state_t ipp_status;
request->poll_state = GTK_CUPS_HTTP_READ;
if (request->result->ipp_response == NULL)
request->result->ipp_response = ippNew();
ipp_status = ippRead (request->http,
request->result->ipp_response);
if (ipp_status == IPP_ERROR)
{
gtk_cups_result_set_error (request->result, "%s", ippErrorString (cupsLastError()));
ippDelete (request->result->ipp_response);
request->result->ipp_response = NULL;
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
}
else if (ipp_status == IPP_DATA)
{
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
}
}
static void
_get_send (GtkCupsRequest *request)
{
request->poll_state = GTK_CUPS_HTTP_WRITE;
if (request->data_fd == 0)
{
gtk_cups_result_set_error (request->result, "Get requires an open file descriptor");
request->state = GTK_CUPS_GET_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
return;
}
httpClearFields(request->http);
httpSetField(request->http, HTTP_FIELD_AUTHORIZATION, request->http->authstring);
if (httpGet(request->http, request->resource))
{
if (httpReconnect(request->http))
{
request->state = GTK_CUPS_GET_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "Failed Get");
}
request->attempts++;
return;
}
request->attempts = 0;
request->state = GTK_CUPS_GET_CHECK;
request->poll_state = GTK_CUPS_HTTP_READ;
request->ipp_request->state = IPP_IDLE;
}
static void
_get_check (GtkCupsRequest *request)
{
http_status_t http_status;
http_status = request->last_status;
request->poll_state = GTK_CUPS_HTTP_READ;
if (http_status == HTTP_CONTINUE)
{
goto again;
}
else if (http_status == HTTP_UNAUTHORIZED)
{
/* TODO: callout for auth */
g_warning ("NOT IMPLEMENTED: We need to prompt for authorization in a non blocking manner");
request->state = GTK_CUPS_GET_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
gtk_cups_result_set_error (request->result, "Can't prompt for authorization");
return;
}
/* TODO: detect ssl in configure.ac */
#if HAVE_SSL
else if (http_status == HTTP_UPGRADE_REQUIRED)
{
/* Flush any error message... */
httpFlush (request->http);
/* Reconnect... */
httpReconnect (request->http);
/* Upgrade with encryption... */
httpEncryption(request->http, HTTP_ENCRYPT_REQUIRED);
request->attempts++;
goto again;
}
#endif
else if (http_status != HTTP_OK)
{
int http_errno;
http_errno = httpError (request->http);
if (http_errno == EPIPE)
request->state = GTK_CUPS_GET_CONNECT;
else
{
request->state = GTK_CUPS_GET_DONE;
gtk_cups_result_set_error (request->result, "HTTP Error in GET %s", strerror (http_errno));
request->poll_state = GTK_CUPS_HTTP_IDLE;
httpFlush(request->http);
return;
}
request->poll_state = GTK_CUPS_HTTP_IDLE;
httpFlush (request->http);
httpClose (request->http);
request->last_status = HTTP_CONTINUE;
request->http = NULL;
return;
}
else
{
request->state = GTK_CUPS_GET_READ_DATA;
return;
}
again:
http_status = HTTP_CONTINUE;
if (httpCheck (request->http))
http_status = httpUpdate (request->http);
request->last_status = http_status;
}
static void
_get_read_data (GtkCupsRequest *request)
{
char buffer[_GTK_CUPS_MAX_CHUNK_SIZE];
int bytes;
request->poll_state = GTK_CUPS_HTTP_READ;
bytes = httpRead(request->http, buffer, sizeof(buffer));
if (bytes == 0)
{
request->state = GTK_CUPS_GET_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
return;
}
if (write (request->data_fd, buffer, bytes) == -1)
{
char *error_msg;
request->state = GTK_CUPS_POST_DONE;
request->poll_state = GTK_CUPS_HTTP_IDLE;
error_msg = strerror (errno);
gtk_cups_result_set_error (request->result, error_msg ? error_msg:"");
}
}
gboolean
gtk_cups_request_is_done (GtkCupsRequest *request)
{
return (request->state == GTK_CUPS_REQUEST_DONE);
}
gboolean
gtk_cups_result_is_error (GtkCupsResult *result)
{
return result->is_error;
}
ipp_t *
gtk_cups_result_get_response (GtkCupsResult *result)
{
return result->ipp_response;
}
const char *
gtk_cups_result_get_error_string (GtkCupsResult *result)
{
return result->error_msg;
}

View File

@@ -0,0 +1,125 @@
/* gtkcupsutils.h
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_CUPS_UTILS_H__
#define __GTK_CUPS_UTILS_H__
#include <glib.h>
#include <cups/cups.h>
#include <cups/language.h>
#include <cups/http.h>
#include <cups/ipp.h>
G_BEGIN_DECLS
typedef struct _GtkCupsRequest GtkCupsRequest;
typedef struct _GtkCupsResult GtkCupsResult;
typedef enum
{
GTK_CUPS_POST,
GTK_CUPS_GET
} GtkCupsRequestType;
/**
* Direction we should be polling the http socket on.
* We are either reading or writting at each state.
* This makes it easy for mainloops to connect to poll.
*/
typedef enum
{
GTK_CUPS_HTTP_IDLE,
GTK_CUPS_HTTP_READ,
GTK_CUPS_HTTP_WRITE
} GtkCupsPollState;
struct _GtkCupsRequest
{
GtkCupsRequestType type;
http_t *http;
http_status_t last_status;
ipp_t *ipp_request;
gchar *server;
gchar *resource;
gint data_fd;
gint attempts;
GtkCupsResult *result;
gint state;
GtkCupsPollState poll_state;
gint own_http : 1;
};
#define GTK_CUPS_REQUEST_START 0
#define GTK_CUPS_REQUEST_DONE 500
/* POST states */
enum
{
GTK_CUPS_POST_CONNECT = GTK_CUPS_REQUEST_START,
GTK_CUPS_POST_SEND,
GTK_CUPS_POST_WRITE_REQUEST,
GTK_CUPS_POST_WRITE_DATA,
GTK_CUPS_POST_CHECK,
GTK_CUPS_POST_READ_RESPONSE,
GTK_CUPS_POST_DONE = GTK_CUPS_REQUEST_DONE
};
/* GET states */
enum
{
GTK_CUPS_GET_CONNECT = GTK_CUPS_REQUEST_START,
GTK_CUPS_GET_SEND,
GTK_CUPS_GET_CHECK,
GTK_CUPS_GET_READ_DATA,
GTK_CUPS_GET_DONE = GTK_CUPS_REQUEST_DONE
};
GtkCupsRequest * gtk_cups_request_new (http_t *connection,
GtkCupsRequestType req_type,
gint operation_id,
gint data_fd,
const char *server,
const char *resource);
void gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
ipp_tag_t group,
ipp_tag_t tag,
const char *name,
const char *charset,
const char *value);
gboolean gtk_cups_request_read_write (GtkCupsRequest *request);
GtkCupsPollState gtk_cups_request_get_poll_state (GtkCupsRequest *request);
void gtk_cups_request_free (GtkCupsRequest *request);
GtkCupsResult * gtk_cups_request_get_result (GtkCupsRequest *request);
gboolean gtk_cups_request_is_done (GtkCupsRequest *request);
void gtk_cups_request_encode_option (GtkCupsRequest *request,
const gchar *option,
const gchar *value);
gboolean gtk_cups_result_is_error (GtkCupsResult *result);
ipp_t * gtk_cups_result_get_response (GtkCupsResult *result);
const char * gtk_cups_result_get_error_string (GtkCupsResult *result);
G_END_DECLS
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
/* GTK - The GIMP Toolkit
* gtkprintbackendcups.h: Default implementation of GtkPrintBackend for the Common Unix Print System (CUPS)
* Copyright (C) 2003, Red Hat, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINT_BACKEND_CUPS_H__
#define __GTK_PRINT_BACKEND_CUPS_H__
#include <glib-object.h>
#include "gtkprintbackend.h"
G_BEGIN_DECLS
#define GTK_TYPE_PRINT_BACKEND_CUPS (gtk_print_backend_cups_get_type ())
#define GTK_PRINT_BACKEND_CUPS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINT_BACKEND_CUPS, GtkPrintBackendCups))
#define GTK_IS_PRINT_BACKEND_CUPS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINT_BACKEND_CUPS))
typedef struct _GtkPrintBackendCups GtkPrintBackendCups;
GtkPrintBackend *gtk_print_backend_cups_new (void);
GType gtk_print_backend_cups_get_type (void) G_GNUC_CONST;
G_END_DECLS
#endif /* __GTK_PRINT_BACKEND_CUPS_H__ */

View File

@@ -0,0 +1,93 @@
/* GtkPrinterCupsCups
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include "config.h"
#include "gtkprintercups.h"
#define GTK_PRINTER_CUPS_GET_PRIVATE(o) \
(G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINTER_CUPS, GtkPrinterCupsPrivate))
static void gtk_printer_cups_finalize (GObject *object);
G_DEFINE_TYPE (GtkPrinterCups, gtk_printer_cups, GTK_TYPE_PRINTER);
static void
gtk_printer_cups_class_init (GtkPrinterCupsClass *class)
{
GObjectClass *object_class;
object_class = (GObjectClass *) class;
object_class->finalize = gtk_printer_cups_finalize;
}
static void
gtk_printer_cups_init (GtkPrinterCups *printer)
{
printer->device_uri = NULL;
printer->printer_uri = NULL;
printer->state = 0;
printer->hostname = NULL;
printer->port = 0;
printer->ppd_file = NULL;
}
static void
gtk_printer_cups_finalize (GObject *object)
{
g_return_if_fail (object != NULL);
GtkPrinterCups *printer = GTK_PRINTER_CUPS (object);
g_free (printer->device_uri);
g_free (printer->printer_uri);
g_free (printer->hostname);
if (printer->ppd_file)
ppdClose (printer->ppd_file);
if (G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize)
G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object);
}
/**
* gtk_printer_cups_new:
*
* Creates a new #GtkPrinterCups.
*
* Return value: a new #GtkPrinterCups
*
* Since: 2.10
**/
GtkPrinterCups *
gtk_printer_cups_new (void)
{
GObject *result;
result = g_object_new (GTK_TYPE_PRINTER_CUPS,
NULL);
return (GtkPrinterCups *) result;
}
ppd_file_t *
gtk_printer_cups_get_ppd (GtkPrinterCups *printer)
{
return printer->ppd_file;
}

View File

@@ -0,0 +1,68 @@
/* GtkPrinterCups
* Copyright (C) 2006 John (J5) Palmieri <johnp@redhat.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_PRINTER_CUPS_H__
#define __GTK_PRINTER_CUPS_H__
#include <glib.h>
#include <glib-object.h>
#include <cups/cups.h>
#include <cups/ppd.h>
#include "gtkprinter.h"
G_BEGIN_DECLS
#define GTK_TYPE_PRINTER_CUPS (gtk_printer_cups_get_type ())
#define GTK_PRINTER_CUPS(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_PRINTER_CUPS, GtkPrinterCups))
#define GTK_PRINTER_CUPS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINTER_CUPS, GtkPrinterCupsClass))
#define GTK_IS_PRINTER_CUPS(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_PRINTER_CUPS))
#define GTK_IS_PRINTER_CUPS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINTER_CUPS))
#define GTK_PRINTER_CUPS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINTER_CUPS, GtkPrinterCupsClass))
typedef struct _GtkPrinterCups GtkPrinterCups;
typedef struct _GtkPrinterCupsClass GtkPrinterCupsClass;
typedef struct _GtkPrinterCupsPrivate GtkPrinterCupsPrivate;
struct _GtkPrinterCups
{
GtkPrinter parent_instance;
gchar *device_uri;
gchar *printer_uri;
gchar *hostname;
gint port;
ipp_pstate_t state;
gboolean reading_ppd;
ppd_file_t *ppd_file;
};
struct _GtkPrinterCupsClass
{
GtkPrinterClass parent_class;
};
GType gtk_printer_cups_get_type (void) G_GNUC_CONST;
GtkPrinterCups *gtk_printer_cups_new (void);
ppd_file_t * gtk_printer_cups_get_ppd (GtkPrinterCups *printer);
G_END_DECLS
#endif /* __GTK_PRINTER_CUPS_H__ */

View File

@@ -57,3 +57,4 @@ testtreesort
testtreeview
testxinerama
treestoretest
print-editor

View File

@@ -30,6 +30,7 @@ noinst_PROGRAMS = \
autotestfilechooser \
floatingtest \
simple \
print-editor \
testaccel \
testassistant \
testcairo \
@@ -81,6 +82,7 @@ noinst_PROGRAMS = \
autotestfilechooser_DEPENDENCIES = $(TEST_DEPS)
simple_DEPENDENCIES = $(TEST_DEPS)
floatingtest_DEPENDENCIES = $(TEST_DEPS)
print_editor_DEPENDENCIES = $(TEST_DEPS)
testicontheme_DEPENDENCIES = $(TEST_DEPS)
testiconview_DEPENDENCIES = $(TEST_DEPS)
testaccel_DEPENDENCIES = $(TEST_DEPS)
@@ -126,6 +128,7 @@ testactions_DEPENDENCIES = $(TEST_DEPS)
autotestfilechooser_LDADD = $(LDADDS)
simple_LDADD = $(LDADDS)
floatingtest_LDADD = $(LDADDS)
print_editor_LDADD = $(LDADDS)
testaccel_LDADD = $(LDADDS)
testassistant_LDADD = $(LDADDS)
testcairo_LDADD = $(LDADDS)

646
tests/print-editor.c Normal file
View File

@@ -0,0 +1,646 @@
#include <pango/pangocairo.h>
#include <gtk/gtk.h>
#include <gtk/gtkprintoperation.h>
static GtkWidget *main_window;
static char *filename = NULL;
static GtkPageSetup *page_setup = NULL;
static GtkPrintSettings *settings = NULL;
static gboolean file_changed = FALSE;
static GtkTextBuffer *buffer;
static GtkWidget *statusbar;
static void
update_title (void)
{
char *basename;
char *title;
if (filename == NULL)
basename = g_strdup ("Untitled");
else
basename = g_path_get_basename (filename);
title = g_strdup_printf ("Simple Editor with printing - %s", basename);
g_free (basename);
gtk_window_set_title (GTK_WINDOW (main_window), title);
g_free (title);
}
static void
update_statusbar (void)
{
gchar *msg;
gint row, col;
GtkTextIter iter;
gtk_statusbar_pop (GTK_STATUSBAR (statusbar), 0);
gtk_text_buffer_get_iter_at_mark (buffer,
&iter,
gtk_text_buffer_get_insert (buffer));
row = gtk_text_iter_get_line (&iter);
col = gtk_text_iter_get_line_offset (&iter);
msg = g_strdup_printf ("%d, %d%s",
row, col, file_changed?" - Modified":"");
gtk_statusbar_push (GTK_STATUSBAR (statusbar), 0, msg);
g_free (msg);
}
static void
update_ui (void)
{
update_title ();
update_statusbar ();
}
static char *
get_text (void)
{
GtkTextIter start, end;
gtk_text_buffer_get_start_iter (buffer, &start);
gtk_text_buffer_get_end_iter (buffer, &end);
return gtk_text_buffer_get_text (buffer, &start, &end, FALSE);
}
static void
set_text (const char *text, gsize len)
{
gtk_text_buffer_set_text (buffer, text, len);
file_changed = FALSE;
update_ui ();
}
static void
do_new (GtkAction *action)
{
g_free (filename);
filename = NULL;
set_text ("", 0);
}
static void
load_file (const char *open_filename)
{
GtkWidget *error_dialog;
char *contents;
GError *error;
gsize len;
error_dialog = NULL;
error = NULL;
if (g_file_get_contents (open_filename, &contents, &len, &error))
{
if (g_utf8_validate (contents, len, NULL))
{
filename = g_strdup (open_filename);
set_text (contents, len);
g_free (contents);
}
else
{
error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Error loading file %s:\n%s",
open_filename,
"Not valid utf8");
}
}
else
{
error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Error loading file %s:\n%s",
open_filename,
error->message);
g_error_free (error);
}
if (error_dialog)
{
g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (error_dialog);
}
}
static void
do_open (GtkAction *action)
{
GtkWidget *dialog;
gint response;
char *open_filename;
dialog = gtk_file_chooser_dialog_new ("Select file",
GTK_WINDOW (main_window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response == GTK_RESPONSE_OK)
{
open_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
load_file (open_filename);
g_free (open_filename);
}
gtk_widget_destroy (dialog);
}
static void
save_file (const char *save_filename)
{
char *text = get_text ();
GtkWidget *error_dialog;
GError *error;
error = NULL;
if (g_file_set_contents (save_filename,
text, -1, &error))
{
if (save_filename != filename)
{
g_free (filename);
filename = g_strdup (save_filename);
}
file_changed = FALSE;
update_ui ();
}
else
{
error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Error saving to file %s:\n%s",
filename,
error->message);
g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (error_dialog);
g_error_free (error);
}
}
static void
do_save_as (GtkAction *action)
{
GtkWidget *dialog;
gint response;
char *save_filename;
dialog = gtk_file_chooser_dialog_new ("Select file",
GTK_WINDOW (main_window),
GTK_FILE_CHOOSER_ACTION_SAVE,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_SAVE, GTK_RESPONSE_OK,
NULL);
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
response = gtk_dialog_run (GTK_DIALOG (dialog));
if (response == GTK_RESPONSE_OK)
{
save_filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
save_file (save_filename);
g_free (save_filename);
}
gtk_widget_destroy (dialog);
}
static void
do_save (GtkAction *action)
{
if (filename == NULL)
do_save_as (action);
else
save_file (filename);
}
typedef struct {
char *text;
PangoLayout *layout;
GList *page_breaks;
} PrintData;
static void
begin_print (GtkPrintOperation *operation,
GtkPrintContext *context,
PrintData *print_data)
{
PangoFontDescription *desc;
PangoLayoutLine *layout_line;
double width, height;
double page_height;
GList *page_breaks;
int num_lines;
int line;
width = gtk_print_context_get_width (context);
height = gtk_print_context_get_height (context);
print_data->layout = gtk_print_context_create_layout (context);
desc = pango_font_description_from_string ("Sans 12");
pango_layout_set_font_description (print_data->layout, desc);
pango_font_description_free (desc);
pango_layout_set_width (print_data->layout, width * PANGO_SCALE);
pango_layout_set_text (print_data->layout, print_data->text, -1);
num_lines = pango_layout_get_line_count (print_data->layout);
page_breaks = NULL;
page_height = 0;
for (line = 0; line < num_lines; line++)
{
PangoRectangle ink_rect, logical_rect;
double line_height;
layout_line = pango_layout_get_line (print_data->layout, line);
pango_layout_line_get_extents (layout_line, &ink_rect, &logical_rect);
line_height = logical_rect.height / 1024.0;
if (page_height + line_height > height)
{
page_breaks = g_list_prepend (page_breaks, GINT_TO_POINTER (line));
page_height = 0;
}
page_height += line_height;
}
page_breaks = g_list_reverse (page_breaks);
gtk_print_operation_set_nr_of_pages (operation, g_list_length (page_breaks) + 1);
print_data->page_breaks = page_breaks;
}
static void
draw_page (GtkPrintOperation *operation,
GtkPrintContext *context,
int page_nr,
PrintData *print_data)
{
cairo_t *cr;
GList *pagebreak;
int start, end, i;
PangoLayoutIter *iter;
double start_pos;
if (page_nr == 0)
start = 0;
else
{
pagebreak = g_list_nth (print_data->page_breaks, page_nr - 1);
start = GPOINTER_TO_INT (pagebreak->data);
}
pagebreak = g_list_nth (print_data->page_breaks, page_nr);
if (pagebreak == NULL)
end = pango_layout_get_line_count (print_data->layout);
else
end = GPOINTER_TO_INT (pagebreak->data);
cr = gtk_print_context_get_cairo (context);
cairo_set_source_rgb (cr, 0, 0, 0);
i = 0;
start_pos = 0;
iter = pango_layout_get_iter (print_data->layout);
do
{
PangoRectangle logical_rect;
PangoLayoutLine *line;
int baseline;
if (i >= start)
{
line = pango_layout_iter_get_line (iter);
pango_layout_iter_get_line_extents (iter, NULL, &logical_rect);
baseline = pango_layout_iter_get_baseline (iter);
if (i == start)
start_pos = logical_rect.y / 1024.0;
cairo_move_to (cr, logical_rect.x / 1024.0, baseline / 1024.0 - start_pos);
pango_cairo_show_layout_line (cr, line);
}
i++;
}
while (i < end &&
pango_layout_iter_next_line (iter));
}
static void
do_page_setup (GtkAction *action)
{
GtkPageSetup *new_page_setup;
if (settings == NULL)
settings = gtk_print_settings_new ();
new_page_setup = gtk_print_run_page_setup_dialog (GTK_WINDOW (main_window),
page_setup, settings);
if (page_setup)
g_object_unref (page_setup);
page_setup = new_page_setup;
}
static void
do_print (GtkAction *action)
{
GtkWidget *error_dialog;
GtkPrintOperation *print;
PrintData print_data;
GtkPrintOperationResult res;
GError *error;
print_data.text = get_text ();
print = gtk_print_operation_new ();
if (settings != NULL)
gtk_print_operation_set_print_settings (print, settings);
if (page_setup != NULL)
gtk_print_operation_set_default_page_setup (print, page_setup);
g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), &print_data);
g_signal_connect (print, "draw_page", G_CALLBACK (draw_page), &print_data);
error = NULL;
res = gtk_print_operation_run (print, GTK_WINDOW (main_window), &error);
if (res == GTK_PRINT_OPERATION_RESULT_ERROR)
{
error_dialog = gtk_message_dialog_new (GTK_WINDOW (main_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
"Error printing file:\n%s",
error->message);
g_signal_connect (error_dialog, "response", G_CALLBACK (gtk_widget_destroy), NULL);
gtk_widget_show (error_dialog);
g_error_free (error);
}
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 (print));
}
}
static void
do_about (GtkAction *action)
{
const gchar *authors[] = {
"Alexander Larsson",
NULL
};
gtk_show_about_dialog (GTK_WINDOW (main_window),
"name", "print test editor",
"version", "0.1",
"copyright", "(C) Red Hat, Inc",
"comments", "Program to demonstrate GTK+ printing.",
"authors", authors,
NULL);
}
static void
do_quit (GtkAction *action)
{
gtk_main_quit ();
}
static GtkActionEntry entries[] = {
{ "FileMenu", NULL, "_File" }, /* name, stock id, label */
{ "HelpMenu", NULL, "_Help" }, /* name, stock id, label */
{ "New", GTK_STOCK_NEW, /* name, stock id */
"_New", "<control>N", /* label, accelerator */
"Create a new file", /* tooltip */
G_CALLBACK (do_new) },
{ "Open", GTK_STOCK_OPEN, /* name, stock id */
"_Open","<control>O", /* label, accelerator */
"Open a file", /* tooltip */
G_CALLBACK (do_open) },
{ "Save", GTK_STOCK_SAVE, /* name, stock id */
"_Save","<control>S", /* label, accelerator */
"Save current file", /* tooltip */
G_CALLBACK (do_save) },
{ "SaveAs", GTK_STOCK_SAVE, /* name, stock id */
"Save _As...", NULL, /* label, accelerator */
"Save to a file", /* tooltip */
G_CALLBACK (do_save_as) },
{ "Quit", GTK_STOCK_QUIT, /* name, stock id */
"_Quit", "<control>Q", /* label, accelerator */
"Quit", /* tooltip */
G_CALLBACK (do_quit) },
{ "About", NULL, /* name, stock id */
"_About", "<control>A", /* label, accelerator */
"About", /* tooltip */
G_CALLBACK (do_about) },
{ "PageSetup", NULL, /* name, stock id */
"Page _Setup", NULL, /* label, accelerator */
"Set up the page", /* tooltip */
G_CALLBACK (do_page_setup) },
{ "Print", GTK_STOCK_PRINT, /* name, stock id */
NULL, NULL, /* label, accelerator */
"Print the document", /* tooltip */
G_CALLBACK (do_print) },
};
static guint n_entries = G_N_ELEMENTS (entries);
static const gchar *ui_info =
"<ui>"
" <menubar name='MenuBar'>"
" <menu action='FileMenu'>"
" <menuitem action='New'/>"
" <menuitem action='Open'/>"
" <menuitem action='Save'/>"
" <menuitem action='SaveAs'/>"
" <menuitem action='PageSetup'/>"
" <menuitem action='Print'/>"
" <separator/>"
" <menuitem action='Quit'/>"
" </menu>"
" <menu action='HelpMenu'>"
" <menuitem action='About'/>"
" </menu>"
" </menubar>"
"</ui>";
static void
buffer_changed_callback (GtkTextBuffer *buffer)
{
file_changed = TRUE;
update_statusbar ();
}
static void
mark_set_callback (GtkTextBuffer *buffer,
const GtkTextIter *new_location,
GtkTextMark *mark,
gpointer data)
{
update_statusbar ();
}
static void
update_resize_grip (GtkWidget *widget,
GdkEventWindowState *event,
GtkStatusbar *statusbar)
{
if (event->changed_mask & (GDK_WINDOW_STATE_MAXIMIZED |
GDK_WINDOW_STATE_FULLSCREEN))
{
gboolean maximized;
maximized = event->new_window_state & (GDK_WINDOW_STATE_MAXIMIZED |
GDK_WINDOW_STATE_FULLSCREEN);
gtk_statusbar_set_has_resize_grip (statusbar, !maximized);
}
}
static void
create_window (void)
{
GtkWidget *bar;
GtkWidget *table;
GtkWidget *contents;
GtkUIManager *ui;
GtkWidget *sw;
GtkActionGroup *actions;
GError *error;
main_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size (GTK_WINDOW (main_window),
400, 600);
g_signal_connect (main_window, "delete-event",
G_CALLBACK (gtk_main_quit), NULL);
actions = gtk_action_group_new ("Actions");
gtk_action_group_add_actions (actions, entries, n_entries, NULL);
ui = gtk_ui_manager_new ();
gtk_ui_manager_insert_action_group (ui, actions, 0);
gtk_window_add_accel_group (GTK_WINDOW (main_window),
gtk_ui_manager_get_accel_group (ui));
gtk_container_set_border_width (GTK_CONTAINER (main_window), 0);
error = NULL;
if (!gtk_ui_manager_add_ui_from_string (ui, ui_info, -1, &error))
{
g_message ("building menus failed: %s", error->message);
g_error_free (error);
}
table = gtk_table_new (1, 3, FALSE);
gtk_container_add (GTK_CONTAINER (main_window), table);
bar = gtk_ui_manager_get_widget (ui, "/MenuBar");
gtk_widget_show (bar);
gtk_table_attach (GTK_TABLE (table),
bar,
/* X direction */ /* Y direction */
0, 1, 0, 1,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
/* Create document */
sw = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),
GTK_SHADOW_IN);
gtk_table_attach (GTK_TABLE (table),
sw,
/* X direction */ /* Y direction */
0, 1, 1, 2,
GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
0, 0);
contents = gtk_text_view_new ();
gtk_widget_grab_focus (contents);
gtk_container_add (GTK_CONTAINER (sw),
contents);
/* Create statusbar */
statusbar = gtk_statusbar_new ();
gtk_table_attach (GTK_TABLE (table),
statusbar,
/* X direction */ /* Y direction */
0, 1, 2, 3,
GTK_EXPAND | GTK_FILL, 0,
0, 0);
/* Show text widget info in the statusbar */
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));
g_signal_connect_object (buffer,
"changed",
G_CALLBACK (buffer_changed_callback),
NULL,
0);
g_signal_connect_object (buffer,
"mark_set", /* cursor moved */
G_CALLBACK (mark_set_callback),
NULL,
0);
g_signal_connect_object (main_window,
"window_state_event",
G_CALLBACK (update_resize_grip),
statusbar,
0);
update_ui ();
gtk_widget_show_all (main_window);
}
int
main (int argc, char **argv)
{
gtk_init (&argc, &argv);
create_window ();
if (argc == 2)
load_file (argv[1]);
gtk_main ();
return 0;
}