Re: g_signal_emit_by_name + Evince + GtkPrintUnixDialog



Excerpts from Peter Senna Tschudin's message of jue may 20 01:04:54 +0200 2010:
> Dear list members,
> This is my first post.
> 
> I'm working on a simple modification of Evince. I want that when user choose
> "Print" Evince prints the file directly instead of showing the print screen.
> 
> See part of the source code:
> 
> #vi evince-2.22.2/shell/ev-window.c

evince 2.22 is too old, printing code has changed a lot. Since Evince
2.28 we use GtkPrintOperation to print pdf files which already
supports printing without showing the print dialog. You only need to
use GTK_PRINT_OPERATION_ACTION_PRINT as second argument of
gtk_print_operation_run(). 

> void
> ev_window_print_range (EvWindow *ev_window, int first_page, int last_page)
> {
>         GtkWidget           *dialog;
>         EvPageCache         *page_cache;
>         gint                 current_page;
>         gint                 document_last_page;
>         GtkPrintCapabilities capabilities;
> 
>         g_return_if_fail (EV_IS_WINDOW (ev_window));
>         g_return_if_fail (ev_window->priv->document != NULL);
> 
>         if (ev_window->priv->print_dialog) {
>                 gtk_window_present (GTK_WINDOW
> (ev_window->priv->print_dialog));
>                 return;
>         }
> 
>         page_cache = ev_page_cache_get (ev_window->priv->document);
>         current_page = ev_page_cache_get_current_page (page_cache);
>         document_last_page = ev_page_cache_get_n_pages (page_cache);
> 
>         if (!ev_window->priv->print_settings) {
>                 ev_window->priv->print_settings = gtk_print_settings_copy (
>                         ev_application_get_print_settings (EV_APP));
>                 ev_window_load_print_settings_from_metadata (ev_window);
>         }
> 
>         if (first_page != 1 || last_page != document_last_page) {
>                 GtkPageRange range;
> 
>                 /* Ranges in GtkPrint are 0 - N */
>                 range.start = first_page - 1;
>                 range.end = last_page - 1;
> 
>                 gtk_print_settings_set_print_pages
> (ev_window->priv->print_settings,
>                                                     GTK_PRINT_PAGES_RANGES);
>                 gtk_print_settings_set_page_ranges
> (ev_window->priv->print_settings,
>                                                     &range, 1);
>         }
> 
>         dialog = gtk_print_unix_dialog_new (_("Print"), GTK_WINDOW
> (ev_window));
>         ev_window->priv->print_dialog = dialog;
> 
>         capabilities = GTK_PRINT_CAPABILITY_PREVIEW |
>                 ev_file_exporter_get_capabilities (EV_FILE_EXPORTER
> (ev_window->priv->document));
>         gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG
> (dialog),
>                                                        capabilities);
> 
>         gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG
> (dialog),
>                                                 current_page);
> 
>         gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (dialog),
> 
>  ev_window->priv->print_settings);
>          if (ev_window->priv->print_page_setup)
>                 gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG
> (dialog),
> 
>  ev_window->priv->print_page_setup);
> 
>         g_signal_connect (G_OBJECT (dialog), "response",
>                           G_CALLBACK (ev_window_print_dialog_response_cb),
>                           ev_window);
> 
>         gtk_widget_show (dialog);
> 
>         // **********************************************
>         // I ADDED THE LINE BELOW
>         // **********************************************
> 
>         g_signal_emit_by_name (G_OBJECT (dialog), "response",
> GTK_RESPONSE_OK);
> 
> }
> 
> What am I doing wrong? :-/
> 
> After my change, when "Ctrl-P", Evince outputs:
> 
> (evince:28399): GLib-GObject-CRITICAL **: g_object_ref: assertion
> `G_IS_OBJECT (object)' failed
> 
> (evince:28399): Gtk-CRITICAL **: gtk_printer_accepts_ps: assertion
> `GTK_IS_PRINTER (printer)' failed
> 
> (evince:28399): Gtk-CRITICAL **: gtk_printer_get_backend: assertion
> `GTK_IS_PRINTER (printer)' failed
> 
> (evince:28399): GLib-GObject-CRITICAL **: g_object_ref: assertion
> `G_IS_OBJECT (object)' failed
> Segmentation fault
> 
> 
> But if I change GTK_RESPONSE_OK to GTK_RESPONSE_CANCEL then it works as
> expected. The print dialog is not shown, and it does not print because
> the GTK_RESPONSE_CANCEL means the cancel button.
> 
> I think that the error is related to the callback
> function ev_window_print_dialog_response_cb. Here goes its untouched  code:
> 
>  static gboolean
> ev_window_print_dialog_response_cb (GtkDialog *dialog,
>                                     gint       response,
>                                     EvWindow  *window)
> {
>         EvPrintRange  *ranges = NULL;
>         EvPrintPageSet page_set;
>         gint           n_ranges = 0;
>         gint           copies;
>         gint           pages_per_sheet;
>         gboolean       collate;
>         gboolean       reverse;
>         gdouble        scale;
>         gint           current_page;
>         gdouble        width;
>         gdouble        height;
>         GtkPrintPages  print_pages;
>         const gchar   *file_format;
> 
>         if (response != GTK_RESPONSE_OK &&
>             response != GTK_RESPONSE_APPLY) {
>                 gtk_widget_destroy (GTK_WIDGET (dialog));
>                 window->priv->print_dialog = NULL;
> 
>                 return FALSE;
>         }
> 
>         window->priv->print_preview = (response == GTK_RESPONSE_APPLY);
> 
>         if (window->priv->printer)
>                 g_object_unref (window->priv->printer);
>         if (window->priv->print_settings)
>                 g_object_unref (window->priv->print_settings);
>         if (window->priv->print_page_setup)
>                 g_object_unref (window->priv->print_page_setup);
> 
>         window->priv->printer = g_object_ref (
>                 gtk_print_unix_dialog_get_selected_printer
> (GTK_PRINT_UNIX_DIALOG (dialog)));
>         window->priv->print_settings = g_object_ref (
>                 gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG
> (dialog)));
>         window->priv->print_page_setup = g_object_ref (
>                 gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG
> (dialog)));
> 
>         file_format = gtk_print_settings_get (window->priv->print_settings,
> 
>  GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
> 
>         if (!gtk_printer_accepts_ps (window->priv->printer)) {
>                 GtkWidget *msgdialog;
>                  msgdialog = gtk_message_dialog_new (GTK_WINDOW (dialog),
>                                                     GTK_DIALOG_MODAL,
>                                                     GTK_MESSAGE_ERROR,
>                                                     GTK_BUTTONS_OK,
>                                                     _("Printing is not
> supported on this printer."));
> 
>                 gtk_dialog_run (GTK_DIALOG (msgdialog));
>                 gtk_widget_destroy (msgdialog);
> 
>                 return FALSE;
>         }
> 
>         ev_window_clear_print_job (window);
> 
>         current_page = gtk_print_unix_dialog_get_current_page
> (GTK_PRINT_UNIX_DIALOG (dialog));
>         print_pages = gtk_print_settings_get_print_pages
> (window->priv->print_settings);
> 
>         switch (print_pages) {
>         case GTK_PRINT_PAGES_CURRENT:
>                 ranges = g_new0 (EvPrintRange, 1);
> 
>                 ranges->start = current_page;
>                 ranges->end = current_page;
>                 n_ranges = 1;
> 
>                 break;
>         case GTK_PRINT_PAGES_RANGES: {
>                 GtkPageRange *page_range;
> 
>                 page_range = gtk_print_settings_get_page_ranges
> (window->priv->print_settings,
>                                                                  &n_ranges);
>                 if (n_ranges > 0)
>                         ranges = g_memdup (page_range, n_ranges * sizeof
> (GtkPageRange));
>         }
>                 break;
>         case GTK_PRINT_PAGES_ALL: {
>                 gint n_pages;
> 
>                 n_pages = ev_page_cache_get_n_pages (ev_page_cache_get
> (window->priv->document));
> 
>                 ranges = g_new0 (EvPrintRange, 1);
> 
>                 ranges->start = 0;
>                 ranges->end = n_pages - 1;
>                 n_ranges = 1;
>         }
>                 break;
>         }
> 
>         page_set = (EvPrintPageSet)gtk_print_settings_get_page_set
> (window->priv->print_settings);
> 
>         scale = gtk_print_settings_get_scale (window->priv->print_settings)
> * 0.01;
> 
>          width = gtk_page_setup_get_paper_width
> (window->priv->print_page_setup,
>                                                 GTK_UNIT_POINTS);
>         height = gtk_page_setup_get_paper_height
> (window->priv->print_page_setup,
>                                                   GTK_UNIT_POINTS);
> 
>         if (scale != 1.0) {
>                 width *= scale;
>                 height *= scale;
>         }
> 
>         pages_per_sheet = gtk_print_settings_get_number_up
> (window->priv->print_settings);
> 
>         copies = gtk_print_settings_get_n_copies
> (window->priv->print_settings);
>         collate = gtk_print_settings_get_collate
> (window->priv->print_settings);
>         reverse = gtk_print_settings_get_reverse
> (window->priv->print_settings);
> 
>         window->priv->print_job = ev_job_print_new (window->priv->document,
>                                                     file_format ?
> file_format : "ps",
>                                                     width, height,
>                                                     ranges, n_ranges,
>                                                     page_set,
>                                                     pages_per_sheet,
>                                                     copies, collate,
>                                                     reverse);
> 
>         g_signal_connect (window->priv->print_job, "finished",
>                           G_CALLBACK (ev_window_print_job_cb),
>                           window);
>         /* The priority doesn't matter for this job */
>         ev_job_queue_add_job (window->priv->print_job, EV_JOB_PRIORITY_LOW);
> 
>         gtk_widget_destroy (GTK_WIDGET (dialog));
>         window->priv->print_dialog = NULL;
> 
>         return TRUE;
> }
> 
> 
> Can you help me?
> 
> Thanks,
> 
> Peter
> 
-- 
Carlos Garcia Campos
PGP key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x523E6462

Attachment: signature.asc
Description: PGP signature



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