Code

Node tool: special case node duplication for endnodes - select new endnode
[inkscape.git] / src / print.cpp
index 4252298a4731c928d4d00be7efdb5b46ce452fc1..e0601aa339eb930a9568868011416e79f08e9533 100644 (file)
@@ -1,11 +1,12 @@
-#define __SP_PRINT_C__
-
 /** \file
  * Frontend to printing
  */
 /*
  * Author:
  *   Lauris Kaplinski <lauris@kaplinski.com>
+ *   Kees Cook <kees@outflux.net>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * This code is in public domain
  */
 # include "config.h"
 #endif
 
-
-
+#include "inkscape.h"
+#include "desktop.h"
 #include "sp-item.h"
 #include "extension/print.h"
 #include "extension/system.h"
 #include "print.h"
 
-#include <unit-constants.h>
-
-#ifdef HAVE_GTK_UNIX_PRINT
-# include <gtk/gtk.h>
-# include <glibmm/i18n.h>
-# include <gtk/gtkprintunixdialog.h>
-# include <unistd.h>   // close, unlink
-# include <cstdio>
-using std::fprintf;
-#endif
-
-#if 0
-# include <extension/internal/ps.h>
+#include "ui/dialog/print.h"
 
-# ifdef WIN32
-#  include <extension/internal/win32.h>
-# endif
-#endif
 
 /* Identity typedef */
 
-unsigned int sp_print_bind(SPPrintContext *ctx, NR::Matrix const &transform, float opacity)
+unsigned int sp_print_bind(SPPrintContext *ctx, Geom::Matrix const &transform, float opacity)
 {
-    NRMatrix const ntransform(transform);
+    Geom::Matrix const ntransform(transform);
     return sp_print_bind(ctx, &ntransform, opacity);
 }
 
 unsigned int
-sp_print_bind(SPPrintContext *ctx, NRMatrix const *transform, float opacity)
+sp_print_bind(SPPrintContext *ctx, Geom::Matrix const *transform, float opacity)
 {
     return ctx->module->bind(transform, opacity);
 }
@@ -67,28 +52,28 @@ sp_print_comment(SPPrintContext *ctx, char const *comment)
 }
 
 unsigned int
-sp_print_fill(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
+sp_print_fill(SPPrintContext *ctx, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *style,
               NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
 {
-    return ctx->module->fill(bpath, ctm, style, pbox, dbox, bbox);
+    return ctx->module->fill(pathv, ctm, style, pbox, dbox, bbox);
 }
 
 unsigned int
-sp_print_stroke(SPPrintContext *ctx, NRBPath const *bpath, NRMatrix const *ctm, SPStyle const *style,
+sp_print_stroke(SPPrintContext *ctx, Geom::PathVector const &pathv, Geom::Matrix const *ctm, SPStyle const *style,
                 NRRect const *pbox, NRRect const *dbox, NRRect const *bbox)
 {
-    return ctx->module->stroke(bpath, ctm, style, pbox, dbox, bbox);
+    return ctx->module->stroke(pathv, ctm, style, pbox, dbox, bbox);
 }
 
 unsigned int
 sp_print_image_R8G8B8A8_N(SPPrintContext *ctx,
                           guchar *px, unsigned int w, unsigned int h, unsigned int rs,
-                          NRMatrix const *transform, SPStyle const *style)
+                          Geom::Matrix const *transform, SPStyle const *style)
 {
     return ctx->module->image(px, w, h, rs, transform, style);
 }
 
-unsigned int sp_print_text(SPPrintContext *ctx, char const *text, NR::Point p,
+unsigned int sp_print_text(SPPrintContext *ctx, char const *text, Geom::Point p,
                            SPStyle const *style)
 {
     return ctx->module->text(text, p, style);
@@ -105,7 +90,7 @@ sp_print_preview_document(SPDocument *doc)
     Inkscape::Extension::Print *mod;
     unsigned int ret;
 
-    sp_document_ensure_up_to_date(doc);
+    doc->ensureUpToDate();
 
     mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
 
@@ -117,18 +102,17 @@ sp_print_preview_document(SPDocument *doc)
 
         /* fixme: This has to go into module constructor somehow */
         /* Create new arena */
-        mod->base = SP_ITEM(sp_document_root(doc));
+        mod->base = SP_ITEM(doc->getRoot());
         mod->arena = NRArena::create();
-        mod->dkey = sp_item_display_key_new(1);
-        mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
+        mod->dkey = SPItem::display_key_new(1);
+        mod->root = (mod->base)->invoke_show(mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
         /* Print document */
         ret = mod->begin(doc);
-        sp_item_invoke_print(mod->base, &context);
+        (mod->base)->invoke_print(&context);
         ret = mod->finish();
         /* Release arena */
-        sp_item_invoke_hide(mod->base, mod->dkey);
+        (mod->base)->invoke_hide(mod->dkey);
         mod->base = NULL;
-        nr_arena_item_unref(mod->root);
         mod->root = NULL;
         nr_object_unref((NRObject *) mod->arena);
         mod->arena = NULL;
@@ -137,164 +121,26 @@ sp_print_preview_document(SPDocument *doc)
     return;
 }
 
-#ifdef HAVE_GTK_UNIX_PRINT
-static void
-unix_print_complete (GtkPrintJob */*print_job*/,
-                     gpointer /*user_data*/,
-                     GError *error)
-{
-    fprintf(stderr,"print job finished: %s\n",error ? error->message : "no error");
-}
-
-static void
-unix_print_dialog (const gchar * ps_file, const gchar * jobname, gdouble doc_width, gdouble doc_height)
-{
-    Glib::ustring title = _("Print");
-    title += " ";
-    title += jobname;
-    GtkWidget* dlg = gtk_print_unix_dialog_new(title.c_str(), NULL);
-
-    // force output system to only handle our pre-generated PS output
-    gtk_print_unix_dialog_set_manual_capabilities (GTK_PRINT_UNIX_DIALOG(dlg),
-                                                   GTK_PRINT_CAPABILITY_GENERATE_PS);
-
-/*
- * It would be nice to merge the PrintPS::setup routine with a custom
- * configuration dialog:
-
-    gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog,
-                                          GtkWidget *child,
-                                          GtkWidget *tab_label);
-*/
-
-    int const response = gtk_dialog_run(GTK_DIALOG(dlg));
-
-    if (response == GTK_RESPONSE_OK) {
-        GtkPrinter* printer = gtk_print_unix_dialog_get_selected_printer(GTK_PRINT_UNIX_DIALOG(dlg));
-
-        if (gtk_printer_accepts_ps (printer)) {
-            GtkPageSetup *page_setup = gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dlg));
-
-            //It's important to set the right paper size here, otherwise it will
-            //default to letter; if for example an A4 is printed as a letter, then
-            //part of it will be truncated even when printing on A4 paper
-
-            //TODO: let the user decide upon the paper size, by enabling
-            //the drop down widget in the printing dialog. For now, we'll simply
-            //take the document's dimensions and communicate these to the printer
-            //driver
-
-            GtkPaperSize *page_size = gtk_paper_size_new_custom("custom", "custom", doc_width, doc_height, GTK_UNIT_POINTS);
-
-            gtk_page_setup_set_paper_size (page_setup, page_size);
-
-            GtkPrintJob* job = gtk_print_job_new  (jobname, printer,
-                                                   gtk_print_unix_dialog_get_settings(GTK_PRINT_UNIX_DIALOG(dlg)),
-                                                   page_setup);
-
-            GtkPaperSize* tmp = gtk_page_setup_get_paper_size(gtk_print_unix_dialog_get_page_setup(GTK_PRINT_UNIX_DIALOG(dlg)));
-            (void)tmp;
-
-            GError * error = NULL;
-            if ( gtk_print_job_set_source_file (job, ps_file, &error)) {
-                gtk_print_job_send (job, unix_print_complete, NULL, NULL);
-            }
-            else {
-                g_warning(_("Could not set print source: %s"),error ? error->message : _("unknown error"));
-            }
-            if (error) g_error_free(error);
-        }
-        else {
-            g_warning(_("Printer '%s' does not support PS output"), gtk_printer_get_name (printer));
-        }
-    }
-    else if (response == GTK_RESPONSE_APPLY) {
-        // since we didn't include the Preview capability,
-        // this should never happen.
-        g_warning(_("Print Preview not available"));
-    }
-
-    gtk_widget_destroy(dlg);
-}
-#endif // HAVE_GTK_UNIX_PRINT
-
-
 void
-sp_print_document(SPDocument *doc, unsigned int direct)
+sp_print_document(Gtk::Window& parentWindow, SPDocument *doc)
 {
-    Inkscape::Extension::Print *mod;
-    unsigned int ret;
-#ifdef HAVE_GTK_UNIX_PRINT
-    Glib::ustring tmpfile = "";
-#endif
-
-    sp_document_ensure_up_to_date(doc);
-
-    if (direct) {
-        mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
-    } else {
-        mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_DEFAULT);
-
-#ifdef HAVE_GTK_UNIX_PRINT
-        // unix print dialog reads from the exported tempfile
-        gchar  *filename = NULL;
-        GError *error    = NULL;
-        gint tmpfd = g_file_open_tmp("inkscape-ps-XXXXXX",
-                                     &filename,
-                                     &error);
-        if (tmpfd<0) {
-            g_warning(_("Failed to create tempfile for printing: %s"),
-                      error ? error->message : _("unknown error"));
-            if (error) g_error_free(error);
-            return;
-        }
-        tmpfile = filename;
-        g_free(filename);
-        close(tmpfd);
-
-        Glib::ustring destination = ">" + tmpfile;
-        mod->set_param_string("destination", destination.c_str());
-#endif
-    }
-
-    ret = mod->setup();
-
-    if (ret) {
-        SPPrintContext context;
-        context.module = mod;
-
-        /* fixme: This has to go into module constructor somehow */
-        /* Create new arena */
-        mod->base = SP_ITEM(sp_document_root(doc));
-        mod->arena = NRArena::create();
-        mod->dkey = sp_item_display_key_new(1);
-        mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
-        /* Print document */
-        ret = mod->begin(doc);
-        sp_item_invoke_print(mod->base, &context);
-        ret = mod->finish();
-        /* Release arena */
-        sp_item_invoke_hide(mod->base, mod->dkey);
-        mod->base = NULL;
-        nr_arena_item_unref(mod->root);
-        mod->root = NULL;
-        nr_object_unref((NRObject *) mod->arena);
-        mod->arena = NULL;
-
-#ifdef HAVE_GTK_UNIX_PRINT
-        // redirect output to new print dialog
-
-        // width and height in pt
-       gdouble width = sp_document_width(doc) * PT_PER_PX;
-       gdouble height = sp_document_height(doc) * PT_PER_PX;
-
-        unix_print_dialog(tmpfile.c_str(),doc->name ? doc->name : _("SVG Document"), width, height);
-        unlink(tmpfile.c_str());
-        // end redirected new print dialog
-#endif
-    }
-
-    return;
+    doc->ensureUpToDate();
+
+    // Build arena
+    SPItem      *base = SP_ITEM(doc->getRoot());
+    NRArena    *arena = NRArena::create();
+    unsigned int dkey = SPItem::display_key_new(1);
+    // TODO investigate why we are grabbing root and then ignoring it.
+    NRArenaItem *root = base->invoke_show(arena, dkey, SP_ITEM_SHOW_DISPLAY);
+
+    // Run print dialog
+    Inkscape::UI::Dialog::Print printop(doc,base);
+    Gtk::PrintOperationResult res = printop.run(Gtk::PRINT_OPERATION_ACTION_PRINT_DIALOG, parentWindow);
+    (void)res; // TODO handle this
+
+    // Release arena
+    base->invoke_hide(dkey);
+    nr_object_unref((NRObject *) arena);
 }
 
 void
@@ -306,7 +152,7 @@ sp_print_document_to_file(SPDocument *doc, gchar const *filename)
     gchar *oldoutput;
     unsigned int ret;
 
-    sp_document_ensure_up_to_date(doc);
+    doc->ensureUpToDate();
 
     mod = Inkscape::Extension::get_print(SP_MODULE_KEY_PRINT_PS);
     oldconst = mod->get_param_string("destination");
@@ -317,18 +163,17 @@ sp_print_document_to_file(SPDocument *doc, gchar const *filename)
     context.module = mod;
     /* fixme: This has to go into module constructor somehow */
     /* Create new arena */
-    mod->base = SP_ITEM(sp_document_root(doc));
+    mod->base = SP_ITEM(doc->getRoot());
     mod->arena = NRArena::create();
-    mod->dkey = sp_item_display_key_new(1);
-    mod->root = sp_item_invoke_show(mod->base, mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
+    mod->dkey = SPItem::display_key_new(1);
+    mod->root = (mod->base)->invoke_show(mod->arena, mod->dkey, SP_ITEM_SHOW_DISPLAY);
     /* Print document */
     ret = mod->begin(doc);
-    sp_item_invoke_print(mod->base, &context);
+    (mod->base)->invoke_print(&context);
     ret = mod->finish();
     /* Release arena */
-    sp_item_invoke_hide(mod->base, mod->dkey);
+    (mod->base)->invoke_hide(mod->dkey);
     mod->base = NULL;
-    nr_arena_item_unref(mod->root);
     mod->root = NULL;
     nr_object_unref((NRObject *) mod->arena);
     mod->arena = NULL;
@@ -350,4 +195,4 @@ sp_print_document_to_file(SPDocument *doc, gchar const *filename)
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :