Code

relocated unix print dialog outside of extension call path
[inkscape.git] / src / print.cpp
1 #define __SP_PRINT_C__
3 /** \file
4  * Frontend to printing
5  */
6 /*
7  * Author:
8  *   Lauris Kaplinski <lauris@kaplinski.com>
9  *
10  * This code is in public domain
11  */
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
19 #include "sp-item.h"
20 #include "extension/print.h"
21 #include "extension/system.h"
22 #include "print.h"
24 #ifdef HAVE_GTK_UNIX_PRINT
25 #include <gtk/gtk.h>
26 #include <glibmm/i18n.h>
27 #include <gtk/gtkprintunixdialog.h>
28 #endif
30 #if 0
31 # include <extension/internal/ps.h>
33 # ifdef WIN32
34 #  include <extension/internal/win32.h>
35 # endif
37 # ifdef WITH_GNOME_PRINT
38 #  include <extension/internal/gnome.h>
39 # endif
40 #endif
42 /* Identity typedef */
44 unsigned int sp_print_bind(SPPrintContext *ctx, NR::Matrix const &transform, float opacity)
45 {
46     NRMatrix const ntransform(transform);
47     return sp_print_bind(ctx, &ntransform, opacity);
48 }
50 unsigned int
51 sp_print_bind(SPPrintContext *ctx, NRMatrix const *transform, float opacity)
52 {
53     return ctx->module->bind(transform, opacity);
54 }
56 unsigned int
57 sp_print_release(SPPrintContext *ctx)
58 {
59     return ctx->module->release();
60 }
62 unsigned int
63 sp_print_comment(SPPrintContext *ctx, char const *comment)
64 {
65     return ctx->module->comment(comment);
66 }
68 unsigned int
69 sp_print_fill(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
70               NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
71 {
72     return ctx->module->fill(bpath, ctm, style, pbox, dbox, bbox);
73 }
75 unsigned int
76 sp_print_stroke(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
77                 NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
78 {
79     return ctx->module->stroke(bpath, ctm, style, pbox, dbox, bbox);
80 }
82 unsigned int
83 sp_print_image_R8G8B8A8_N(SPPrintContext *ctx,
84                           guchar *px, unsigned int w, unsigned int h, unsigned int rs,
85                           NRMatrix const *transform, SPStyle const *style)
86 {
87     return ctx->module->image(px, w, h, rs, transform, style);
88 }
90 unsigned int sp_print_text(SPPrintContext *ctx, char const *text, NR::Point p,
91                            SPStyle const *style)
92 {
93     return ctx->module->text(text, p, style);
94 }
96 #include "display/nr-arena.h"
97 #include "display/nr-arena-item.h"
99 /* UI */
101 void
102 sp_print_preview_document(SPDocument *doc)
104     Inkscape::Extension::Print *mod;
105     unsigned int ret;
107     sp_document_ensure_up_to_date(doc);
109     mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
111     ret = mod->set_preview();
113     if (ret) {
114         SPPrintContext context;
115         context.module = mod;
117         /* fixme: This has to go into module constructor somehow */
118         /* Create new arena */
119         mod->base = SP_ITEM(sp_document_root(doc));
120         mod->arena = NRArena::create();
121         mod->dkey = sp_item_display_key_new(1);
122         mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
123         /* Print document */
124         ret = mod->begin(doc);
125         sp_item_invoke_print(mod->base, &context);
126         ret = mod->finish();
127         /* Release arena */
128         sp_item_invoke_hide(mod->base, mod->dkey);
129         mod->base = NULL;
130         nr_arena_item_unref(mod->root);
131         mod->root = NULL;
132         nr_object_unref((NRObject *) mod->arena);
133         mod->arena = NULL;
134     }
136     return;
139 #ifdef HAVE_GTK_UNIX_PRINT
140 static void
141 unix_print_complete (GtkPrintJob *print_job,
142                      gpointer user_data,
143                      GError *error)
145     fprintf(stderr,"print job finished: %s\n",error ? error->message : "no error");
148 static void
149 unix_print_dialog (const gchar * ps_file, const gchar * jobname)
151     Glib::ustring title = _("Print");
152     title += " ";
153     title += jobname;
154     GtkWidget* dlg = gtk_print_unix_dialog_new(title.c_str(), NULL);
156     // force output system to only handle our pre-generated PS output
157     gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG(dlg),
158                                                    GTK_PRINT_CAPABILITY_GENERATE_PS);
160 /*
161  * It would be nice to merge the PrintPS::setup routine with a custom
162  * configuration dialog:
163    
164     gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog,
165                                           GtkWidget *child,
166                                           GtkWidget *tab_label);
167 */
169     int const response = gtk_dialog_run(GTK_DIALOG(dlg));
171     if (response == GTK_RESPONSE_OK) {
172         GtkPrinter* printer = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(dlg));
174         if (gtk_printer_accepts_ps (printer)) {
175             GtkPrintJob* job = gtk_print_job_new  (jobname, printer,
176               gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dlg)),
177               gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dlg)));
180             GError * error = NULL;
181             if ( gtk_print_job_set_source_file (job, ps_file, &error)) {
182                 gtk_print_job_send (job, unix_print_complete, NULL, NULL);
183             }
184             else {
185                 g_warning(_("Could not set print source: %s"),error ? error->message : _("unknown error"));
186             }
187             if (error) g_error_free(error);
188         }
189         else {
190             g_warning(_("Printer '%s' does not support PS output"), gtk_printer_get_name (printer));
191         }
192     }
193     else if (response == GTK_RESPONSE_APPLY) {
194         // since we didn't include the Preview capability,
195         // this should never happen.
196         g_warning(_("Print Preview not available"));
197     }
199     gtk_widget_destroy(dlg);
201 #endif // HAVE_GTK_UNIX_PRINT
204 void
205 sp_print_document(SPDocument *doc, unsigned int direct)
207     Inkscape::Extension::Print *mod;
208     unsigned int ret;
209 #ifdef HAVE_GTK_UNIX_PRINT
210     Glib::ustring tmpfile = "";
211 #endif
213     sp_document_ensure_up_to_date(doc);
215     if (direct) {
216         mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
217     } else {
218         mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
220 #ifdef HAVE_GTK_UNIX_PRINT
221         // unix print dialog reads from the exported tempfile
222         gchar  *filename = NULL;
223         GError *error    = NULL;
224         gint tmpfd = g_file_open_tmp("inkscape-ps-XXXXXX",
225                                      &filename,
226                                      &error);
227         if (tmpfd<0) {
228             g_warning(_("Failed to create tempfile for printing: %s"),
229                       error ? error->message : _("unknown error"));
230             if (error) g_error_free(error);
231             return;
232         }
233         tmpfile = filename;
234         g_free(filename);
235         close(tmpfd);
237         Glib::ustring destination = ">" + tmpfile;
238         mod->set_param_string("destination", destination.c_str());
239 #endif
240     }
242     ret = mod->setup();
244     if (ret) {
245         SPPrintContext context;
246         context.module = mod;
248         /* fixme: This has to go into module constructor somehow */
249         /* Create new arena */
250         mod->base = SP_ITEM(sp_document_root(doc));
251         mod->arena = NRArena::create();
252         mod->dkey = sp_item_display_key_new(1);
253         mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
254         /* Print document */
255         ret = mod->begin(doc);
256         sp_item_invoke_print(mod->base, &context);
257         ret = mod->finish();
258         /* Release arena */
259         sp_item_invoke_hide(mod->base, mod->dkey);
260         mod->base = NULL;
261         nr_arena_item_unref(mod->root);
262         mod->root = NULL;
263         nr_object_unref((NRObject *) mod->arena);
264         mod->arena = NULL;
266 #ifdef HAVE_GTK_UNIX_PRINT
267         // redirect output to new print dialog
268         unix_print_dialog(tmpfile.c_str(),doc->name ? doc->name : _("SVG Document"));
269         unlink(tmpfile.c_str());
270         // end redirected new print dialog
271 #endif
272     }
274     return;
277 void
278 sp_print_document_to_file(SPDocument *doc, gchar const *filename)
280     Inkscape::Extension::Print *mod;
281     SPPrintContext context;
282     gchar const *oldconst;
283     gchar *oldoutput;
284     unsigned int ret;
286     sp_document_ensure_up_to_date(doc);
288     mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
289     oldconst = mod->get_param_string("destination");
290     oldoutput = g_strdup(oldconst);
291     mod->set_param_string("destination", (gchar *)filename);
293 /* Start */
294     context.module = mod;
295     /* fixme: This has to go into module constructor somehow */
296     /* Create new arena */
297     mod->base = SP_ITEM(sp_document_root(doc));
298     mod->arena = NRArena::create();
299     mod->dkey = sp_item_display_key_new(1);
300     mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
301     /* Print document */
302     ret = mod->begin(doc);
303     sp_item_invoke_print(mod->base, &context);
304     ret = mod->finish();
305     /* Release arena */
306     sp_item_invoke_hide(mod->base, mod->dkey);
307     mod->base = NULL;
308     nr_arena_item_unref(mod->root);
309     mod->root = NULL;
310     nr_object_unref((NRObject *) mod->arena);
311     mod->arena = NULL;
312 /* end */
314     mod->set_param_string("destination", oldoutput);
315     g_free(oldoutput);
317     return;
321 /*
322   Local Variables:
323   mode:c++
324   c-file-style:"stroustrup"
325   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
326   indent-tabs-mode:nil
327   fill-column:99
328   End:
329 */
330 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :