798 lines
27 KiB
C
798 lines
27 KiB
C
/*
|
|
* xed-print.c
|
|
* This file is part of xed
|
|
*
|
|
* Copyright (C) 2000-2001 Chema Celorio, Paolo Maggi
|
|
* Copyright (C) 2002-2008 Paolo Maggi
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
/*
|
|
* Modified by the xed Team, 1998-2005. See the AUTHORS file for a
|
|
* list of people on the xed Team.
|
|
* See the ChangeLog files for a list of changes.
|
|
*
|
|
* $Id: xed-print.c 6022 2007-12-09 14:38:57Z pborelli $
|
|
*/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include <config.h>
|
|
#endif
|
|
|
|
#include <glib/gi18n.h>
|
|
#include <gtksourceview/gtksource.h>
|
|
|
|
#include "xed-print-job.h"
|
|
#include "xed-debug.h"
|
|
#include "xed-print-preview.h"
|
|
#include "xed-marshal.h"
|
|
#include "xed-utils.h"
|
|
#include "xed-dirs.h"
|
|
#include "xed-settings.h"
|
|
|
|
|
|
#define XED_PRINT_JOB_GET_PRIVATE(object)(G_TYPE_INSTANCE_GET_PRIVATE ((object), \
|
|
XED_TYPE_PRINT_JOB, \
|
|
XedPrintJobPrivate))
|
|
|
|
struct _XedPrintJobPrivate
|
|
{
|
|
GSettings *print_settings;
|
|
|
|
XedView *view;
|
|
XedDocument *doc;
|
|
|
|
GtkPrintOperation *operation;
|
|
GtkSourcePrintCompositor *compositor;
|
|
|
|
GtkPrintSettings *settings;
|
|
|
|
GtkWidget *preview;
|
|
|
|
XedPrintJobStatus status;
|
|
|
|
gchar *status_string;
|
|
|
|
gdouble progress;
|
|
|
|
gboolean is_preview;
|
|
|
|
/* widgets part of the custom print preferences widget.
|
|
* These pointers are valid just when the dialog is displayed */
|
|
GtkWidget *syntax_checkbutton;
|
|
GtkWidget *page_header_checkbutton;
|
|
GtkWidget *line_numbers_checkbutton;
|
|
GtkWidget *line_numbers_hbox;
|
|
GtkWidget *line_numbers_spinbutton;
|
|
GtkWidget *text_wrapping_checkbutton;
|
|
GtkWidget *do_not_split_checkbutton;
|
|
GtkWidget *fonts_table;
|
|
GtkWidget *body_font_label;
|
|
GtkWidget *headers_font_label;
|
|
GtkWidget *numbers_font_label;
|
|
GtkWidget *body_fontbutton;
|
|
GtkWidget *headers_fontbutton;
|
|
GtkWidget *numbers_fontbutton;
|
|
GtkWidget *restore_button;
|
|
};
|
|
|
|
enum
|
|
{
|
|
PROP_0,
|
|
PROP_VIEW
|
|
};
|
|
|
|
enum
|
|
{
|
|
PRINTING,
|
|
SHOW_PREVIEW,
|
|
DONE,
|
|
LAST_SIGNAL
|
|
};
|
|
|
|
static guint print_job_signals[LAST_SIGNAL] = { 0 };
|
|
|
|
G_DEFINE_TYPE (XedPrintJob, xed_print_job, G_TYPE_OBJECT)
|
|
|
|
static void
|
|
set_view (XedPrintJob *job,
|
|
XedView *view)
|
|
{
|
|
job->priv->view = view;
|
|
job->priv->doc = XED_DOCUMENT (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));
|
|
}
|
|
|
|
static void
|
|
xed_print_job_get_property (GObject *object,
|
|
guint prop_id,
|
|
GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
XedPrintJob *job = XED_PRINT_JOB (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_VIEW:
|
|
g_value_set_object (value, job->priv->view);
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
xed_print_job_set_property (GObject *object,
|
|
guint prop_id,
|
|
const GValue *value,
|
|
GParamSpec *pspec)
|
|
{
|
|
XedPrintJob *job = XED_PRINT_JOB (object);
|
|
|
|
switch (prop_id)
|
|
{
|
|
case PROP_VIEW:
|
|
set_view (job, g_value_get_object (value));
|
|
break;
|
|
default:
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void
|
|
xed_print_job_finalize (GObject *object)
|
|
{
|
|
XedPrintJob *job = XED_PRINT_JOB (object);
|
|
|
|
g_free (job->priv->status_string);
|
|
|
|
if (job->priv->compositor != NULL)
|
|
{
|
|
g_object_unref (job->priv->compositor);
|
|
}
|
|
|
|
if (job->priv->operation != NULL)
|
|
{
|
|
g_object_unref (job->priv->operation);
|
|
}
|
|
|
|
G_OBJECT_CLASS (xed_print_job_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
xed_print_job_dispose (GObject *object)
|
|
{
|
|
XedPrintJob *job = XED_PRINT_JOB (object);
|
|
|
|
g_clear_object (&job->priv->print_settings);
|
|
|
|
G_OBJECT_CLASS (xed_print_job_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
xed_print_job_class_init (XedPrintJobClass *klass)
|
|
{
|
|
GObjectClass *object_class;
|
|
|
|
object_class = G_OBJECT_CLASS (klass);
|
|
|
|
object_class->get_property = xed_print_job_get_property;
|
|
object_class->set_property = xed_print_job_set_property;
|
|
object_class->finalize = xed_print_job_finalize;
|
|
object_class->dispose = xed_print_job_dispose;
|
|
|
|
g_object_class_install_property (object_class,
|
|
PROP_VIEW,
|
|
g_param_spec_object ("view",
|
|
"Xed View",
|
|
"Xed View to print",
|
|
XED_TYPE_VIEW,
|
|
G_PARAM_READWRITE |
|
|
G_PARAM_STATIC_STRINGS |
|
|
G_PARAM_CONSTRUCT_ONLY));
|
|
|
|
print_job_signals[PRINTING] =
|
|
g_signal_new ("printing",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (XedPrintJobClass, printing),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__UINT,
|
|
G_TYPE_NONE,
|
|
1,
|
|
G_TYPE_UINT);
|
|
|
|
print_job_signals[SHOW_PREVIEW] =
|
|
g_signal_new ("show-preview",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (XedPrintJobClass, show_preview),
|
|
NULL, NULL,
|
|
g_cclosure_marshal_VOID__OBJECT,
|
|
G_TYPE_NONE,
|
|
1,
|
|
GTK_TYPE_WIDGET);
|
|
|
|
print_job_signals[DONE] =
|
|
g_signal_new ("done",
|
|
G_OBJECT_CLASS_TYPE (object_class),
|
|
G_SIGNAL_RUN_LAST,
|
|
G_STRUCT_OFFSET (XedPrintJobClass, done),
|
|
NULL, NULL,
|
|
xed_marshal_VOID__UINT_POINTER,
|
|
G_TYPE_NONE,
|
|
2,
|
|
G_TYPE_UINT,
|
|
G_TYPE_POINTER);
|
|
|
|
g_type_class_add_private (object_class, sizeof (XedPrintJobPrivate));
|
|
}
|
|
|
|
static void
|
|
line_numbers_checkbutton_toggled (GtkToggleButton *button,
|
|
XedPrintJob *job)
|
|
{
|
|
gtk_widget_set_sensitive (job->priv->line_numbers_hbox, gtk_toggle_button_get_active (button));
|
|
}
|
|
|
|
static void
|
|
wrap_mode_checkbutton_toggled (GtkToggleButton *button,
|
|
XedPrintJob *job)
|
|
{
|
|
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton)))
|
|
{
|
|
gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, FALSE);
|
|
gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE);
|
|
}
|
|
else
|
|
{
|
|
gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, TRUE);
|
|
gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), FALSE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
restore_button_clicked (GtkButton *button,
|
|
XedPrintJob *job)
|
|
|
|
{
|
|
gchar *body;
|
|
gchar *header;
|
|
gchar *numbers;
|
|
|
|
body = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO);
|
|
header = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO);
|
|
numbers = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO);
|
|
|
|
gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton), body);
|
|
gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton), header);
|
|
gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton), numbers);
|
|
|
|
g_free (body);
|
|
g_free (header);
|
|
g_free (numbers);
|
|
}
|
|
|
|
static GObject *
|
|
create_custom_widget_cb (GtkPrintOperation *operation,
|
|
XedPrintJob *job)
|
|
{
|
|
GtkBuilder *builder;
|
|
GtkWidget *contents;
|
|
guint line_numbers;
|
|
GtkWrapMode wrap_mode;
|
|
gboolean syntax_hl;
|
|
gboolean print_header;
|
|
gchar *font_body, *font_header, *font_numbers;
|
|
gchar *root_objects[] = {
|
|
"adjustment1",
|
|
"contents",
|
|
NULL
|
|
};
|
|
|
|
builder = gtk_builder_new ();
|
|
gtk_builder_add_objects_from_resource (builder, "/org/x/editor/ui/xed-print-preferences.ui", root_objects, NULL);
|
|
contents = GTK_WIDGET (gtk_builder_get_object (builder, "contents"));
|
|
g_object_ref (contents);
|
|
job->priv->syntax_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "syntax_checkbutton"));
|
|
job->priv->line_numbers_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "line_numbers_checkbutton"));
|
|
job->priv->line_numbers_hbox = GTK_WIDGET (gtk_builder_get_object (builder, "line_numbers_hbox"));
|
|
job->priv->line_numbers_spinbutton = GTK_WIDGET (gtk_builder_get_object (builder, "line_numbers_spinbutton"));
|
|
job->priv->page_header_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "page_header_checkbutton"));
|
|
job->priv->text_wrapping_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "text_wrapping_checkbutton"));
|
|
job->priv->do_not_split_checkbutton = GTK_WIDGET (gtk_builder_get_object (builder, "do_not_split_checkbutton"));
|
|
job->priv->fonts_table = GTK_WIDGET (gtk_builder_get_object (builder, "fonts_table"));
|
|
job->priv->body_font_label = GTK_WIDGET (gtk_builder_get_object (builder, "body_font_label"));
|
|
job->priv->body_fontbutton = GTK_WIDGET (gtk_builder_get_object (builder, "body_fontbutton"));
|
|
job->priv->headers_font_label = GTK_WIDGET (gtk_builder_get_object (builder, "headers_font_label"));
|
|
job->priv->headers_fontbutton = GTK_WIDGET (gtk_builder_get_object (builder, "headers_fontbutton"));
|
|
job->priv->numbers_font_label = GTK_WIDGET (gtk_builder_get_object (builder, "numbers_font_label"));
|
|
job->priv->numbers_fontbutton = GTK_WIDGET (gtk_builder_get_object (builder, "numbers_fontbutton"));
|
|
job->priv->restore_button = GTK_WIDGET (gtk_builder_get_object (builder, "restore_button"));
|
|
g_object_unref (builder);
|
|
|
|
/* Get all settings values */
|
|
syntax_hl = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING);
|
|
print_header = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_HEADER);
|
|
line_numbers = g_settings_get_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS);
|
|
font_body = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO);
|
|
font_header = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO);
|
|
font_numbers = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO);
|
|
|
|
/* Print syntax */
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->syntax_checkbutton), syntax_hl);
|
|
|
|
/* Print page headers */
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->page_header_checkbutton), print_header);
|
|
|
|
/* Line numbers */
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->line_numbers_checkbutton), line_numbers > 0);
|
|
|
|
if (line_numbers > 0)
|
|
{
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton), (guint) line_numbers);
|
|
gtk_widget_set_sensitive (job->priv->line_numbers_hbox, TRUE);
|
|
}
|
|
else
|
|
{
|
|
gtk_spin_button_set_value (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton), 1);
|
|
gtk_widget_set_sensitive (job->priv->line_numbers_hbox, FALSE);
|
|
}
|
|
|
|
/* Text wrapping */
|
|
wrap_mode = g_settings_get_enum (job->priv->print_settings, XED_SETTINGS_PRINT_WRAP_MODE);
|
|
|
|
switch (wrap_mode)
|
|
{
|
|
case GTK_WRAP_WORD:
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), TRUE);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE);
|
|
break;
|
|
case GTK_WRAP_CHAR:
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), TRUE);
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), FALSE);
|
|
break;
|
|
default:
|
|
gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton), FALSE);
|
|
gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton), TRUE);
|
|
}
|
|
|
|
gtk_widget_set_sensitive (job->priv->do_not_split_checkbutton, wrap_mode != GTK_WRAP_NONE);
|
|
|
|
/* Set initial values */
|
|
gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton), font_body);
|
|
g_free (font_body);
|
|
|
|
gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton), font_header);
|
|
g_free (font_header);
|
|
|
|
gtk_font_button_set_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton), font_numbers);
|
|
g_free (font_numbers);
|
|
|
|
g_signal_connect (job->priv->line_numbers_checkbutton, "toggled",
|
|
G_CALLBACK (line_numbers_checkbutton_toggled), job);
|
|
g_signal_connect (job->priv->text_wrapping_checkbutton, "toggled",
|
|
G_CALLBACK (wrap_mode_checkbutton_toggled), job);
|
|
g_signal_connect (job->priv->do_not_split_checkbutton, "toggled",
|
|
G_CALLBACK (wrap_mode_checkbutton_toggled), job);
|
|
g_signal_connect (job->priv->restore_button, "clicked",
|
|
G_CALLBACK (restore_button_clicked), job);
|
|
|
|
return G_OBJECT (contents);
|
|
}
|
|
|
|
static void
|
|
custom_widget_apply_cb (GtkPrintOperation *operation,
|
|
GtkWidget *widget,
|
|
XedPrintJob *job)
|
|
{
|
|
gboolean syntax, page_header;
|
|
const gchar *body, *header, *numbers;
|
|
GtkWrapMode wrap_mode;
|
|
|
|
syntax = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->syntax_checkbutton));
|
|
page_header = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->page_header_checkbutton));
|
|
body = gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->body_fontbutton));
|
|
header = gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->headers_fontbutton));
|
|
numbers = gtk_font_button_get_font_name (GTK_FONT_BUTTON (job->priv->numbers_fontbutton));
|
|
|
|
g_settings_set_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING, syntax);
|
|
g_settings_set_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_HEADER, page_header);
|
|
g_settings_set_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO, body);
|
|
g_settings_set_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO, header);
|
|
g_settings_set_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO, numbers);
|
|
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->line_numbers_checkbutton)))
|
|
{
|
|
g_settings_set_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS,
|
|
MAX (1, gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (job->priv->line_numbers_spinbutton))));
|
|
}
|
|
else
|
|
{
|
|
g_settings_set_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS, 0);
|
|
}
|
|
|
|
if (!gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->text_wrapping_checkbutton)))
|
|
{
|
|
wrap_mode = GTK_WRAP_NONE;
|
|
}
|
|
else
|
|
{
|
|
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (job->priv->do_not_split_checkbutton)))
|
|
{
|
|
wrap_mode = GTK_WRAP_WORD;
|
|
}
|
|
else
|
|
{
|
|
wrap_mode = GTK_WRAP_CHAR;
|
|
}
|
|
}
|
|
|
|
g_settings_set_enum (job->priv->print_settings, XED_SETTINGS_PRINT_WRAP_MODE, wrap_mode);
|
|
}
|
|
|
|
static void
|
|
create_compositor (XedPrintJob *job)
|
|
{
|
|
gchar *print_font_body;
|
|
gchar *print_font_header;
|
|
gchar *print_font_numbers;
|
|
gboolean syntax_hl;
|
|
GtkWrapMode wrap_mode;
|
|
guint print_line_numbers;
|
|
gboolean print_header;
|
|
|
|
/* Create and initialize print compositor */
|
|
print_font_body = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_BODY_PANGO);
|
|
print_font_header = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_HEADER_PANGO);
|
|
print_font_numbers = g_settings_get_string (job->priv->print_settings, XED_SETTINGS_PRINT_FONT_NUMBERS_PANGO);
|
|
syntax_hl = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_SYNTAX_HIGHLIGHTING);
|
|
print_line_numbers = g_settings_get_uint (job->priv->print_settings, XED_SETTINGS_PRINT_LINE_NUMBERS);
|
|
print_header = g_settings_get_boolean (job->priv->print_settings, XED_SETTINGS_PRINT_HEADER);
|
|
wrap_mode = g_settings_get_enum (job->priv->print_settings, XED_SETTINGS_PRINT_WRAP_MODE);
|
|
|
|
job->priv->compositor = GTK_SOURCE_PRINT_COMPOSITOR (
|
|
g_object_new (GTK_SOURCE_TYPE_PRINT_COMPOSITOR,
|
|
"buffer", GTK_SOURCE_BUFFER (job->priv->doc),
|
|
"tab-width", gtk_source_view_get_tab_width (GTK_SOURCE_VIEW (job->priv->view)),
|
|
"highlight-syntax", gtk_source_buffer_get_highlight_syntax (GTK_SOURCE_BUFFER (job->priv->doc)) &&
|
|
syntax_hl,
|
|
"wrap-mode", wrap_mode,
|
|
"print-line-numbers", print_line_numbers,
|
|
"print-header", print_header,
|
|
"print-footer", FALSE,
|
|
"body-font-name", print_font_body,
|
|
"line-numbers-font-name", print_font_numbers,
|
|
"header-font-name", print_font_header,
|
|
NULL));
|
|
|
|
g_free (print_font_body);
|
|
g_free (print_font_header);
|
|
g_free (print_font_numbers);
|
|
|
|
if (print_header)
|
|
{
|
|
gchar *doc_name;
|
|
gchar *name_to_display;
|
|
gchar *left;
|
|
|
|
doc_name = xed_document_get_uri_for_display (job->priv->doc);
|
|
name_to_display = xed_utils_str_middle_truncate (doc_name, 60);
|
|
|
|
left = g_strdup_printf (_("File: %s"), name_to_display);
|
|
|
|
/* Translators: %N is the current page number, %Q is the total
|
|
* number of pages (ex. Page 2 of 10)
|
|
*/
|
|
gtk_source_print_compositor_set_header_format (job->priv->compositor,
|
|
TRUE,
|
|
left,
|
|
NULL,
|
|
_("Page %N of %Q"));
|
|
|
|
g_free (doc_name);
|
|
g_free (name_to_display);
|
|
g_free (left);
|
|
}
|
|
}
|
|
|
|
static void
|
|
begin_print_cb (GtkPrintOperation *operation,
|
|
GtkPrintContext *context,
|
|
XedPrintJob *job)
|
|
{
|
|
create_compositor (job);
|
|
|
|
job->priv->status = XED_PRINT_JOB_STATUS_PAGINATING;
|
|
|
|
job->priv->progress = 0.0;
|
|
|
|
g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status);
|
|
}
|
|
|
|
static void
|
|
preview_ready (GtkPrintOperationPreview *gtk_preview,
|
|
GtkPrintContext *context,
|
|
XedPrintJob *job)
|
|
{
|
|
job->priv->is_preview = TRUE;
|
|
|
|
g_signal_emit (job, print_job_signals[SHOW_PREVIEW], 0, job->priv->preview);
|
|
}
|
|
|
|
static void
|
|
preview_destroyed (GtkWidget *preview,
|
|
GtkPrintOperationPreview *gtk_preview)
|
|
{
|
|
gtk_print_operation_preview_end_preview (gtk_preview);
|
|
}
|
|
|
|
static gboolean
|
|
preview_cb (GtkPrintOperation *op,
|
|
GtkPrintOperationPreview *gtk_preview,
|
|
GtkPrintContext *context,
|
|
GtkWindow *parent,
|
|
XedPrintJob *job)
|
|
{
|
|
job->priv->preview = xed_print_preview_new (op, gtk_preview, context);
|
|
|
|
g_signal_connect_after (gtk_preview, "ready",
|
|
G_CALLBACK (preview_ready), job);
|
|
|
|
/* FIXME: should this go in the preview widget itself? */
|
|
g_signal_connect (job->priv->preview, "destroy",
|
|
G_CALLBACK (preview_destroyed), gtk_preview);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
paginate_cb (GtkPrintOperation *operation,
|
|
GtkPrintContext *context,
|
|
XedPrintJob *job)
|
|
{
|
|
gboolean res;
|
|
|
|
job->priv->status = XED_PRINT_JOB_STATUS_PAGINATING;
|
|
|
|
res = gtk_source_print_compositor_paginate (job->priv->compositor, context);
|
|
|
|
if (res)
|
|
{
|
|
gint n_pages;
|
|
|
|
n_pages = gtk_source_print_compositor_get_n_pages (job->priv->compositor);
|
|
gtk_print_operation_set_n_pages (job->priv->operation, n_pages);
|
|
}
|
|
|
|
job->priv->progress = gtk_source_print_compositor_get_pagination_progress (job->priv->compositor);
|
|
|
|
/* When previewing, the progress is just for pagination, when printing
|
|
* it's split between pagination and rendering */
|
|
if (!job->priv->is_preview)
|
|
{
|
|
job->priv->progress /= 2.0;
|
|
}
|
|
|
|
g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status);
|
|
|
|
return res;
|
|
}
|
|
|
|
static void
|
|
draw_page_cb (GtkPrintOperation *operation,
|
|
GtkPrintContext *context,
|
|
gint page_nr,
|
|
XedPrintJob *job)
|
|
{
|
|
gint n_pages;
|
|
|
|
/* In preview, pages are drawn on the fly, so rendering is
|
|
* not part of the progress */
|
|
if (!job->priv->is_preview)
|
|
{
|
|
g_free (job->priv->status_string);
|
|
|
|
n_pages = gtk_source_print_compositor_get_n_pages (job->priv->compositor);
|
|
|
|
job->priv->status = XED_PRINT_JOB_STATUS_DRAWING;
|
|
|
|
job->priv->status_string = g_strdup_printf ("Rendering page %d of %d...", page_nr + 1, n_pages);
|
|
|
|
job->priv->progress = page_nr / (2.0 * n_pages) + 0.5;
|
|
|
|
g_signal_emit (job, print_job_signals[PRINTING], 0, job->priv->status);
|
|
}
|
|
|
|
gtk_source_print_compositor_draw_page (job->priv->compositor, context, page_nr);
|
|
}
|
|
|
|
static void
|
|
end_print_cb (GtkPrintOperation *operation,
|
|
GtkPrintContext *context,
|
|
XedPrintJob *job)
|
|
{
|
|
g_object_unref (job->priv->compositor);
|
|
job->priv->compositor = NULL;
|
|
}
|
|
|
|
static void
|
|
done_cb (GtkPrintOperation *operation,
|
|
GtkPrintOperationResult result,
|
|
XedPrintJob *job)
|
|
{
|
|
GError *error = NULL;
|
|
XedPrintJobResult print_result;
|
|
|
|
switch (result)
|
|
{
|
|
case GTK_PRINT_OPERATION_RESULT_CANCEL:
|
|
print_result = XED_PRINT_JOB_RESULT_CANCEL;
|
|
break;
|
|
|
|
case GTK_PRINT_OPERATION_RESULT_APPLY:
|
|
print_result = XED_PRINT_JOB_RESULT_OK;
|
|
break;
|
|
|
|
case GTK_PRINT_OPERATION_RESULT_ERROR:
|
|
print_result = XED_PRINT_JOB_RESULT_ERROR;
|
|
gtk_print_operation_get_error (operation, &error);
|
|
break;
|
|
|
|
default:
|
|
g_return_if_reached ();
|
|
}
|
|
|
|
/* Avoid job is destroyed in the handler of the "done" message */
|
|
g_object_ref (job);
|
|
|
|
g_signal_emit (job, print_job_signals[DONE], 0, print_result, error);
|
|
|
|
g_object_unref (operation);
|
|
job->priv->operation = NULL;
|
|
|
|
g_object_unref (job);
|
|
}
|
|
|
|
/* Note that xed_print_job_print can can only be called once on a given XedPrintJob */
|
|
GtkPrintOperationResult
|
|
xed_print_job_print (XedPrintJob *job,
|
|
GtkPrintOperationAction action,
|
|
GtkPageSetup *page_setup,
|
|
GtkPrintSettings *settings,
|
|
GtkWindow *parent,
|
|
GError **error)
|
|
{
|
|
XedPrintJobPrivate *priv;
|
|
gchar *job_name;
|
|
|
|
g_return_val_if_fail (job->priv->compositor == NULL, GTK_PRINT_OPERATION_RESULT_ERROR);
|
|
|
|
priv = job->priv;
|
|
|
|
/* Check if we are previewing */
|
|
priv->is_preview = (action == GTK_PRINT_OPERATION_ACTION_PREVIEW);
|
|
|
|
/* Create print operation */
|
|
job->priv->operation = gtk_print_operation_new ();
|
|
|
|
if (settings)
|
|
{
|
|
gtk_print_operation_set_print_settings (priv->operation, settings);
|
|
}
|
|
|
|
if (page_setup != NULL)
|
|
{
|
|
gtk_print_operation_set_default_page_setup (priv->operation, page_setup);
|
|
}
|
|
|
|
job_name = xed_document_get_short_name_for_display (priv->doc);
|
|
gtk_print_operation_set_job_name (priv->operation, job_name);
|
|
g_free (job_name);
|
|
|
|
gtk_print_operation_set_embed_page_setup (priv->operation, TRUE);
|
|
|
|
gtk_print_operation_set_custom_tab_label (priv->operation, _("Text Editor"));
|
|
|
|
gtk_print_operation_set_allow_async (priv->operation, TRUE);
|
|
|
|
g_signal_connect (priv->operation, "create-custom-widget",
|
|
G_CALLBACK (create_custom_widget_cb), job);
|
|
g_signal_connect (priv->operation, "custom-widget-apply",
|
|
G_CALLBACK (custom_widget_apply_cb), job);
|
|
g_signal_connect (priv->operation, "begin-print",
|
|
G_CALLBACK (begin_print_cb), job);
|
|
g_signal_connect (priv->operation, "preview",
|
|
G_CALLBACK (preview_cb), job);
|
|
g_signal_connect (priv->operation, "paginate",
|
|
G_CALLBACK (paginate_cb), job);
|
|
g_signal_connect (priv->operation, "draw-page",
|
|
G_CALLBACK (draw_page_cb), job);
|
|
g_signal_connect (priv->operation, "end-print",
|
|
G_CALLBACK (end_print_cb), job);
|
|
g_signal_connect (priv->operation, "done",
|
|
G_CALLBACK (done_cb), job);
|
|
|
|
return gtk_print_operation_run (priv->operation, action, parent, error);
|
|
}
|
|
|
|
static void
|
|
xed_print_job_init (XedPrintJob *job)
|
|
{
|
|
job->priv = XED_PRINT_JOB_GET_PRIVATE (job);
|
|
|
|
job->priv->print_settings = g_settings_new ("org.x.editor.preferences.print");
|
|
|
|
job->priv->status = XED_PRINT_JOB_STATUS_INIT;
|
|
|
|
job->priv->status_string = g_strdup (_("Preparing..."));
|
|
}
|
|
|
|
XedPrintJob *
|
|
xed_print_job_new (XedView *view)
|
|
{
|
|
XedPrintJob *job;
|
|
|
|
g_return_val_if_fail (XED_IS_VIEW (view), NULL);
|
|
|
|
job = XED_PRINT_JOB (g_object_new (XED_TYPE_PRINT_JOB, "view", view, NULL));
|
|
|
|
return job;
|
|
}
|
|
|
|
void
|
|
xed_print_job_cancel (XedPrintJob *job)
|
|
{
|
|
g_return_if_fail (XED_IS_PRINT_JOB (job));
|
|
|
|
gtk_print_operation_cancel (job->priv->operation);
|
|
}
|
|
|
|
const gchar *
|
|
xed_print_job_get_status_string (XedPrintJob *job)
|
|
{
|
|
g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL);
|
|
g_return_val_if_fail (job->priv->status_string != NULL, NULL);
|
|
|
|
return job->priv->status_string;
|
|
}
|
|
|
|
gdouble
|
|
xed_print_job_get_progress (XedPrintJob *job)
|
|
{
|
|
g_return_val_if_fail (XED_IS_PRINT_JOB (job), 0.0);
|
|
|
|
return job->priv->progress;
|
|
}
|
|
|
|
GtkPrintSettings *
|
|
xed_print_job_get_print_settings (XedPrintJob *job)
|
|
{
|
|
g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL);
|
|
|
|
return gtk_print_operation_get_print_settings (job->priv->operation);
|
|
}
|
|
|
|
GtkPageSetup *
|
|
xed_print_job_get_page_setup (XedPrintJob *job)
|
|
{
|
|
g_return_val_if_fail (XED_IS_PRINT_JOB (job), NULL);
|
|
|
|
return gtk_print_operation_get_default_page_setup (job->priv->operation);
|
|
}
|