X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkprintoperation-unix.c;h=6b24217987798535f9636196d08673ac633f97e6;hb=0ba92bc26d1b716f2f9c0543593f13cd5a92c521;hp=6ec4ebdd8cf76d523cd294021c51621c66caa0cf;hpb=67d8ed9ed331faf9de20555b158cbba8cb4ff2da;p=~andy%2Fgtk diff --git a/gtk/gtkprintoperation-unix.c b/gtk/gtkprintoperation-unix.c index 6ec4ebdd8..6b2421798 100644 --- a/gtk/gtkprintoperation-unix.c +++ b/gtk/gtkprintoperation-unix.c @@ -14,9 +14,7 @@ * 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. + * License along with this library. If not, see . */ #include "config.h" @@ -41,11 +39,10 @@ #include "gtkpagesetupunixdialog.h" #include "gtkprintbackend.h" #include "gtkprinter.h" -#include "gtkprinter-private.h" #include "gtkprintjob.h" #include "gtklabel.h" #include "gtkintl.h" -#include "gtkalias.h" + typedef struct { @@ -87,10 +84,36 @@ unix_start_page (GtkPrintOperation *op, type = cairo_surface_get_type (op_unix->surface); - if (type == CAIRO_SURFACE_TYPE_PS) - cairo_ps_surface_set_size (op_unix->surface, w, h); - else if (type == CAIRO_SURFACE_TYPE_PDF) - cairo_pdf_surface_set_size (op_unix->surface, w, h); + if ((op->priv->manual_number_up < 2) || + (op->priv->page_position % op->priv->manual_number_up == 0)) + { + if (type == CAIRO_SURFACE_TYPE_PS) + { + cairo_ps_surface_set_size (op_unix->surface, w, h); + cairo_ps_surface_dsc_begin_page_setup (op_unix->surface); + switch (gtk_page_setup_get_orientation (page_setup)) + { + case GTK_PAGE_ORIENTATION_PORTRAIT: + case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT: + cairo_ps_surface_dsc_comment (op_unix->surface, "%%PageOrientation: Portrait"); + break; + + case GTK_PAGE_ORIENTATION_LANDSCAPE: + case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE: + cairo_ps_surface_dsc_comment (op_unix->surface, "%%PageOrientation: Landscape"); + break; + } + } + else if (type == CAIRO_SURFACE_TYPE_PDF) + { + if (!op->priv->manual_orientation) + { + w = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS); + h = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS); + } + cairo_pdf_surface_set_size (op_unix->surface, w, h); + } + } } static void @@ -100,7 +123,11 @@ unix_end_page (GtkPrintOperation *op, cairo_t *cr; cr = gtk_print_context_get_cairo_context (print_context); - cairo_show_page (cr); + + if ((op->priv->manual_number_up < 2) || + ((op->priv->page_position + 1) % op->priv->manual_number_up == 0) || + (op->priv->page_position == op->priv->nr_of_pages_to_print - 1)) + cairo_show_page (cr); } static void @@ -177,12 +204,12 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op, GtkWindow *parent, const gchar *filename) { - gint argc; - gchar **argv; + GAppInfo *appinfo; + GdkAppLaunchContext *context; gchar *cmd; gchar *preview_cmd; GtkSettings *settings; - GtkPrintSettings *print_settings; + GtkPrintSettings *print_settings = NULL; GtkPageSetup *page_setup; GKeyFile *key_file = NULL; gchar *data = NULL; @@ -210,8 +237,28 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op, key_file = g_key_file_new (); - print_settings = gtk_print_operation_get_print_settings (op); - gtk_print_settings_to_key_file (print_settings, key_file, NULL); + print_settings = gtk_print_settings_copy (gtk_print_operation_get_print_settings (op)); + + if (print_settings != NULL) + { + gtk_print_settings_set_reverse (print_settings, FALSE); + gtk_print_settings_set_page_set (print_settings, GTK_PAGE_SET_ALL); + gtk_print_settings_set_scale (print_settings, 1.0); + gtk_print_settings_set_number_up (print_settings, 1); + gtk_print_settings_set_number_up_layout (print_settings, GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM); + + /* These removals are neccessary because cups-* settings have higher priority + * than normal settings. + */ + gtk_print_settings_unset (print_settings, "cups-reverse"); + gtk_print_settings_unset (print_settings, "cups-page-set"); + gtk_print_settings_unset (print_settings, "cups-scale"); + gtk_print_settings_unset (print_settings, "cups-number-up"); + gtk_print_settings_unset (print_settings, "cups-number-up-layout"); + + gtk_print_settings_to_key_file (print_settings, key_file, NULL); + g_object_unref (print_settings); + } page_setup = gtk_print_context_get_page_setup (op->priv->print_context); gtk_page_setup_to_key_file (page_setup, key_file, NULL); @@ -232,7 +279,11 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op, quoted_filename = g_shell_quote (filename); quoted_settings_filename = g_shell_quote (settings_filename); cmd = shell_command_substitute_file (preview_cmd, quoted_filename, quoted_settings_filename, &filename_used, &settings_used); - g_shell_parse_argv (cmd, &argc, &argv, &error); + + appinfo = g_app_info_create_from_commandline (cmd, + "Print Preview", + G_APP_INFO_CREATE_NONE, + &error); g_free (preview_cmd); g_free (quoted_filename); @@ -242,31 +293,37 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op, if (error != NULL) goto out; - gdk_spawn_on_screen (screen, NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, &error); + context = gdk_display_get_app_launch_context (gdk_screen_get_display (screen)); + gdk_app_launch_context_set_screen (context, screen); + g_app_info_launch (appinfo, NULL, G_APP_LAUNCH_CONTEXT (context), &error); - g_strfreev (argv); + g_object_unref (context); + g_object_unref (appinfo); - out: if (error != NULL) { - GtkWidget *edialog; - edialog = gtk_message_dialog_new (parent, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("Error launching preview") /* FIXME better text */); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog), - "%s", error->message); - g_signal_connect (edialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - - gtk_window_present (GTK_WINDOW (edialog)); + gchar* uri; + + g_warning ("%s %s", _("Error launching preview"), error->message); g_error_free (error); + error = NULL; + uri = g_filename_to_uri (filename, NULL, NULL); + gtk_show_uri (screen, uri, GDK_CURRENT_TIME, &error); + g_free (uri); + } + + out: + if (error != NULL) + { + if (op->priv->error == NULL) + op->priv->error = error; + else + g_error_free (error); - filename_used = FALSE; + filename_used = FALSE; settings_used = FALSE; - } + } if (!filename_used) g_unlink (filename); @@ -276,7 +333,7 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op, if (fd > 0) close (fd); - + if (key_file) g_key_file_free (key_file); g_free (data); @@ -284,29 +341,15 @@ _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op, } static void -unix_finish_send (GtkPrintJob *job, - gpointer user_data, - GError *error) +unix_finish_send (GtkPrintJob *job, + gpointer user_data, + const GError *error) { GtkPrintOperation *op = (GtkPrintOperation *) user_data; GtkPrintOperationUnix *op_unix = op->priv->platform_data; - if (error != NULL) - { - GtkWidget *edialog; - edialog = gtk_message_dialog_new (op_unix->parent, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_ERROR, - GTK_BUTTONS_CLOSE, - _("Error printing") /* FIXME better text */); - gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog), - "%s", error->message); - gtk_window_set_modal (GTK_WINDOW (edialog), TRUE); - g_signal_connect (edialog, "response", - G_CALLBACK (gtk_widget_destroy), NULL); - - gtk_window_present (GTK_WINDOW (edialog)); - } + if (error != NULL && op->priv->error == NULL) + op->priv->error = g_error_copy (error); op_unix->data_sent = TRUE; @@ -345,9 +388,9 @@ unix_end_run (GtkPrintOperation *op, g_object_ref (op); if (!op_unix->data_sent) { - GDK_THREADS_LEAVE (); + gdk_threads_leave (); g_main_loop_run (op_unix->loop); - GDK_THREADS_ENTER (); + gdk_threads_enter (); } g_main_loop_unref (op_unix->loop); op_unix->loop = NULL; @@ -363,6 +406,26 @@ job_status_changed_cb (GtkPrintJob *job, } +static void +print_setup_changed_cb (GtkPrintUnixDialog *print_dialog, + GParamSpec *pspec, + gpointer user_data) +{ + GtkPageSetup *page_setup; + GtkPrintSettings *print_settings; + GtkPrintOperation *op = user_data; + GtkPrintOperationPrivate *priv = op->priv; + + page_setup = gtk_print_unix_dialog_get_page_setup (print_dialog); + print_settings = gtk_print_unix_dialog_get_settings (print_dialog); + + g_signal_emit_by_name (op, + "update-custom-widget", + priv->custom_widget, + page_setup, + print_settings); +} + static GtkWidget * get_print_dialog (GtkPrintOperation *op, GtkWindow *parent) @@ -379,18 +442,30 @@ get_print_dialog (GtkPrintOperation *op, GTK_PRINT_CAPABILITY_COLLATE | GTK_PRINT_CAPABILITY_REVERSE | GTK_PRINT_CAPABILITY_SCALE | - GTK_PRINT_CAPABILITY_PREVIEW); + GTK_PRINT_CAPABILITY_PREVIEW | + GTK_PRINT_CAPABILITY_NUMBER_UP | + GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT); if (priv->print_settings) gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (pd), priv->print_settings); + if (priv->default_page_setup) gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (pd), priv->default_page_setup); + gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (pd), + priv->embed_page_setup); + gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (pd), priv->current_page); + gtk_print_unix_dialog_set_support_selection (GTK_PRINT_UNIX_DIALOG (pd), + priv->support_selection); + + gtk_print_unix_dialog_set_has_selection (GTK_PRINT_UNIX_DIALOG (pd), + priv->has_selection); + g_signal_emit_by_name (op, "create-custom-widget", &priv->custom_widget); @@ -409,6 +484,9 @@ get_print_dialog (GtkPrintOperation *op, gtk_print_unix_dialog_add_custom_tab (GTK_PRINT_UNIX_DIALOG (pd), priv->custom_widget, label); + + g_signal_connect (pd, "notify::selected-printer", (GCallback) print_setup_changed_cb, op); + g_signal_connect (pd, "notify::page-setup", (GCallback) print_setup_changed_cb, op); } return pd; @@ -439,18 +517,36 @@ static void finish_print (PrintResponseData *rdata, GtkPrinter *printer, GtkPageSetup *page_setup, - GtkPrintSettings *settings) + GtkPrintSettings *settings, + gboolean page_setup_set) { GtkPrintOperation *op = rdata->op; GtkPrintOperationPrivate *priv = op->priv; GtkPrintJob *job; + gdouble top, bottom, left, right; if (rdata->do_print) { gtk_print_operation_set_print_settings (op, settings); priv->print_context = _gtk_print_context_new (op); - if ( (page_setup != NULL) && (gtk_print_operation_get_default_page_setup (op) == NULL)) + if (gtk_print_settings_get_number_up (settings) < 2) + { + if (printer && gtk_printer_get_hard_margins (printer, &top, &bottom, &left, &right)) + _gtk_print_context_set_hard_margins (priv->print_context, top, bottom, left, right); + } + else + { + /* Pages do not have any unprintable area when printing n-up as each page on the + * sheet has been scaled down and translated to a position within the printable + * area of the sheet. + */ + _gtk_print_context_set_hard_margins (priv->print_context, 0, 0, 0, 0); + } + + if (page_setup != NULL && + (gtk_print_operation_get_default_page_setup (op) == NULL || + page_setup_set)) gtk_print_operation_set_default_page_setup (op, page_setup); _gtk_print_context_set_page_setup (priv->print_context, page_setup); @@ -491,16 +587,16 @@ finish_print (PrintResponseData *rdata, g_signal_connect (job, "status-changed", G_CALLBACK (job_status_changed_cb), op); - priv->print_pages = job->print_pages; - priv->page_ranges = job->page_ranges; - priv->num_page_ranges = job->num_page_ranges; - - priv->manual_num_copies = job->num_copies; - priv->manual_collation = job->collate; - priv->manual_reverse = job->reverse; - priv->manual_page_set = job->page_set; - priv->manual_scale = job->scale; - priv->manual_orientation = job->rotate_to_orientation; + priv->print_pages = gtk_print_job_get_pages (job); + priv->page_ranges = gtk_print_job_get_page_ranges (job, &priv->num_page_ranges); + priv->manual_num_copies = gtk_print_job_get_num_copies (job); + priv->manual_collation = gtk_print_job_get_collate (job); + priv->manual_reverse = gtk_print_job_get_reverse (job); + priv->manual_page_set = gtk_print_job_get_page_set (job); + priv->manual_scale = gtk_print_job_get_scale (job); + priv->manual_orientation = gtk_print_job_get_rotate (job); + priv->manual_number_up = gtk_print_job_get_n_up (job); + priv->manual_number_up_layout = gtk_print_job_get_n_up_layout (job); } } out: @@ -521,6 +617,7 @@ handle_print_response (GtkWidget *dialog, GtkPrintSettings *settings = NULL; GtkPageSetup *page_setup = NULL; GtkPrinter *printer = NULL; + gboolean page_setup_set = FALSE; if (response == GTK_RESPONSE_OK) { @@ -545,11 +642,16 @@ handle_print_response (GtkWidget *dialog, { settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd)); page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (pd)); - + page_setup_set = gtk_print_unix_dialog_get_page_setup_set (GTK_PRINT_UNIX_DIALOG (pd)); + + /* Set new print settings now so that custom-widget options + * can be added to the settings in the callback + */ + gtk_print_operation_set_print_settings (rdata->op, settings); g_signal_emit_by_name (rdata->op, "custom-widget-apply", rdata->op->priv->custom_widget); } - finish_print (rdata, printer, page_setup, settings); + finish_print (rdata, printer, page_setup, settings, page_setup_set); if (settings) g_object_unref (settings); @@ -591,7 +693,7 @@ found_printer (GtkPrinter *printer, page_setup = gtk_page_setup_new (); } - finish_print (rdata, printer, page_setup, settings); + finish_print (rdata, printer, page_setup, settings, FALSE); if (settings) g_object_unref (settings); @@ -732,12 +834,10 @@ _gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation GtkPageSetup *page_setup, cairo_surface_t *surface) { - GtkPaperSize *paper_size; gdouble w, h; - paper_size = gtk_page_setup_get_paper_size (page_setup); - w = gtk_paper_size_get_width (paper_size, GTK_UNIT_POINTS); - h = gtk_paper_size_get_height (paper_size, GTK_UNIT_POINTS); + w = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_POINTS); + h = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_POINTS); cairo_pdf_surface_set_size (surface, w, h); } @@ -779,9 +879,9 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, find_printer (printer_name, (GFunc) found_printer, &rdata); - GDK_THREADS_LEAVE (); + gdk_threads_leave (); g_main_loop_run (rdata.loop); - GDK_THREADS_ENTER (); + gdk_threads_enter (); g_main_loop_unref (rdata.loop); rdata.loop = NULL; @@ -852,12 +952,12 @@ get_page_setup_dialog (GtkWindow *parent, /** * gtk_print_run_page_setup_dialog: - * @parent: transient parent, or %NULL - * @page_setup: an existing #GtkPageSetup, or %NULL + * @parent: (allow-none): transient parent + * @page_setup: (allow-none): an existing #GtkPageSetup * @settings: a #GtkPrintSettings - * - * Runs a page setup dialog, letting the user modify the values from - * @page_setup. If the user cancels the dialog, the returned #GtkPageSetup + * + * Runs a page setup dialog, letting the user modify the values from + * @page_setup. If the user cancels the dialog, the returned #GtkPageSetup * is identical to the passed in @page_setup, otherwise it contains the * modifications done in the dialog. * @@ -865,7 +965,7 @@ get_page_setup_dialog (GtkWindow *parent, * setup dialog. See gtk_print_run_page_setup_dialog_async() if this is * a problem. * - * Return value: a new #GtkPageSetup + * Return value: (transfer full): a new #GtkPageSetup * * Since: 2.10 */ @@ -897,10 +997,11 @@ gtk_print_run_page_setup_dialog (GtkWindow *parent, /** * gtk_print_run_page_setup_dialog_async: - * @parent: transient parent, or %NULL - * @page_setup: an existing #GtkPageSetup, or %NULL + * @parent: (allow-none): transient parent, or %NULL + * @page_setup: (allow-none): an existing #GtkPageSetup, or %NULL * @settings: a #GtkPrintSettings - * @done_cb: a function to call when the user saves the modified page setup + * @done_cb: (scope async): a function to call when the user saves + * the modified page setup * @data: user data to pass to @done_cb * * Runs a page setup dialog, letting the user modify the values from @page_setup. @@ -968,7 +1069,7 @@ find_printer_idle (gpointer data) printer_finder_free (finder); - return FALSE; + return G_SOURCE_REMOVE; } static void @@ -1116,6 +1217,3 @@ find_printer (const gchar *printer, if (finder->backends == NULL && !finder->found_printer) g_idle_add (find_printer_idle, finder); } - -#define __GTK_PRINT_OPERATION_UNIX_C__ -#include "gtkaliasdef.c"