Merge "paginate" branch into "master".
[pspp-builds.git] / src / ui / gui / psppire-output-window.c
index ebf29c01a3ca41c3a58f9d456fee644fb8679919..5c5610a0e8cd398551a6d8b292b9df64f9898758 100644 (file)
@@ -32,7 +32,7 @@
 #include <output/tab.h>
 #include <stdlib.h>
 
-#include "about.h"
+#include "help-menu.h"
 
 #include "psppire-output-window.h"
 
@@ -110,6 +110,8 @@ psppire_output_window_dispose (GObject *obj)
   viewer->items = NULL;
   viewer->n_items = viewer->allocated_items = 0;
 
+  g_object_unref (viewer->print_settings);
+
   /* Chain up to the parent class */
   G_OBJECT_CLASS (parent_class)->dispose (obj);
 }
@@ -216,7 +218,41 @@ psppire_output_submit (struct output_driver *this,
 
   cr = gdk_cairo_create (GTK_WIDGET (pod->viewer)->window);
   if (pod->xr == NULL)
-    pod->xr = xr_create_driver (cr);
+    {
+      const GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (viewer));
+      struct string_map options = STRING_MAP_INITIALIZER (options);
+      PangoFontDescription *font_desc;
+      char *font_name;
+
+      /* Use GTK+ default font as proportional font. */
+      font_name = pango_font_description_to_string (style->font_desc);
+      string_map_insert (&options, "prop-font", font_name);
+      g_free (font_name);
+
+      /* Derived emphasized font from proportional font. */
+      font_desc = pango_font_description_copy (style->font_desc);
+      pango_font_description_set_style (font_desc, PANGO_STYLE_ITALIC);
+      font_name = pango_font_description_to_string (font_desc);
+      string_map_insert (&options, "emph-font", font_name);
+      g_free (font_name);
+      pango_font_description_free (font_desc);
+
+      /* Pretend that the "page" has a reasonable width and a very big length,
+         so that most tables can be conveniently viewed on-screen with vertical
+         scrolling only.  (The length should not be increased very much because
+         it is already close enough to INT_MAX when expressed as thousands of a
+         point.) */
+      string_map_insert (&options, "paper-size", "300x200000mm");
+      string_map_insert (&options, "headers", "off");
+      string_map_insert (&options, "left-margin", "0");
+      string_map_insert (&options, "right-margin", "0");
+      string_map_insert (&options, "top-margin", "0");
+      string_map_insert (&options, "bottom-margin", "0");
+
+      pod->xr = xr_driver_create (cr, &options);
+
+      string_map_destroy (&options);
+    }
 
   r = xr_rendering_create (pod->xr, item, cr);
   if (r == NULL)
@@ -374,6 +410,9 @@ on_row_activate (GtkTreeView *overview,
   gtk_adjustment_set_value (vadj, y);
 }
 
+static void psppire_output_window_print (PsppireOutputWindow *window);
+
+
 static GtkFileFilter *
 add_filter (GtkFileChooser *chooser, const char *name, const char *pattern)
 {
@@ -450,29 +489,25 @@ psppire_output_window_export (PsppireOutputWindow *window)
       string_map_insert (&options, "output-file", filename);
       if (filter == pdf_filter)
         {
-          string_map_insert (&options, "output-type", "pdf");
-          export_output (window, &options, "cairo");
+          export_output (window, &options, "pdf");
         }
       else if (filter == html_filter)
         export_output (window, &options, "html");
       else if (filter == odt_filter)
-        export_output (window, &options, "odf");
+        export_output (window, &options, "odt");
       else if (filter == txt_filter)
         {
           string_map_insert (&options, "headers", "false");
           string_map_insert (&options, "paginate", "false");
           string_map_insert (&options, "squeeze", "true");
           string_map_insert (&options, "emphasis", "none");
-          string_map_insert (&options, "chart-type", "none");
+          string_map_insert (&options, "charts", "none");
           string_map_insert (&options, "top-margin", "0");
           string_map_insert (&options, "bottom-margin", "0");
-          export_output (window, &options, "ascii");
+          export_output (window, &options, "txt");
         }
       else if (filter == ps_filter)
-        {
-          string_map_insert (&options, "output-type", "ps");
-          export_output (window, &options, "cairo");
-        }
+        export_output (window, &options, "ps");
       else if (filter == csv_filter)
         export_output (window, &options, "csv");
       else
@@ -535,16 +570,6 @@ psppire_output_window_init (PsppireOutputWindow *window)
                    G_CALLBACK (cancel_urgency),
                    NULL);
 
-  g_signal_connect (get_action_assert (xml,"help_about"),
-                   "activate",
-                   G_CALLBACK (about_new),
-                   window);
-
-  g_signal_connect (get_action_assert (xml,"help_reference"),
-                   "activate",
-                   G_CALLBACK (reference_manual),
-                   NULL);
-
   g_signal_connect (get_action_assert (xml,"windows_minimise-all"),
                    "activate",
                    G_CALLBACK (psppire_window_minimise_all),
@@ -552,14 +577,19 @@ psppire_output_window_init (PsppireOutputWindow *window)
 
   {
     GtkUIManager *uim = GTK_UI_MANAGER (get_object_assert (xml, "uimanager1", GTK_TYPE_UI_MANAGER));
+    merge_help_menu (uim);
 
     PSPPIRE_WINDOW (window)->menu =
-      GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar1/windows_menuitem/windows_minimise-all")->parent);
+      GTK_MENU_SHELL (gtk_ui_manager_get_widget (uim,"/ui/menubar/windows_menuitem/windows_minimise-all")->parent);
   }
 
   g_signal_connect_swapped (get_action_assert (xml, "file_export"), "activate",
                             G_CALLBACK (psppire_output_window_export), window);
 
+
+  g_signal_connect_swapped (get_action_assert (xml, "file_print"), "activate",
+                            G_CALLBACK (psppire_output_window_print), window);
+
   g_object_unref (xml);
 
   g_signal_connect (window, "delete-event",
@@ -575,3 +605,153 @@ psppire_output_window_new (void)
                                   "description", _("Output Viewer"),
                                   NULL));
 }
+
+
+\f
+static void
+create_xr_print_driver (GtkPrintContext *context, PsppireOutputWindow *window)
+{
+  struct string_map options;
+  GtkPageSetup *page_setup;
+  double width, height;
+  double left_margin;
+  double right_margin;
+  double top_margin;
+  double bottom_margin;
+
+  page_setup = gtk_print_context_get_page_setup (context);
+  width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM);
+  height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM);
+  left_margin = gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM);
+  right_margin = gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM);
+  top_margin = gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM);
+  bottom_margin = gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM);
+
+  string_map_init (&options);
+  string_map_insert_nocopy (&options, xstrdup ("paper-size"),
+                            xasprintf("%.2fx%.2fmm", width, height));
+  string_map_insert_nocopy (&options, xstrdup ("left-margin"),
+                            xasprintf ("%.2fmm", left_margin));
+  string_map_insert_nocopy (&options, xstrdup ("right-margin"),
+                            xasprintf ("%.2fmm", right_margin));
+  string_map_insert_nocopy (&options, xstrdup ("top-margin"),
+                            xasprintf ("%.2fmm", top_margin));
+  string_map_insert_nocopy (&options, xstrdup ("bottom-margin"),
+                            xasprintf ("%.2fmm", bottom_margin));
+
+  window->print_xrd =
+    xr_driver_create (gtk_print_context_get_cairo_context (context), &options);
+
+  string_map_destroy (&options);
+}
+
+static gboolean
+paginate (GtkPrintOperation *operation,
+         GtkPrintContext   *context,
+         PsppireOutputWindow *window)
+{
+  g_print ("%s\n", __FUNCTION__);
+
+  if ( window->print_item < window->n_items )
+    {
+      g_print ("Passing item %d\n", window->print_item);
+      xr_driver_output_item (window->print_xrd, window->items[window->print_item++]);
+      bool x = xr_driver_need_new_page (window->print_xrd);
+      if ( x )
+       {
+         g_print ("Need new page: %d\n", x);
+         xr_driver_next_page (window->print_xrd, NULL);
+         window->print_n_pages ++;
+       }
+      return FALSE;
+    }
+  else
+    {
+      g_print ("Number of pages is %d\n", window->print_n_pages);
+      gtk_print_operation_set_n_pages (operation, window->print_n_pages);
+      window->print_item = 0;
+
+      create_xr_print_driver (context, window);
+
+      return TRUE;
+    }
+}
+
+static void
+begin_print (GtkPrintOperation *operation,
+            GtkPrintContext   *context,
+            PsppireOutputWindow *window)
+{
+  g_print ("%s\n", __FUNCTION__);
+
+  create_xr_print_driver (context, window);
+
+  window->print_item = 0;
+  window->print_n_pages = 1;
+}
+
+static void
+end_print (GtkPrintOperation *operation,
+          GtkPrintContext   *context,
+          PsppireOutputWindow *window)
+{
+  g_print ("%s\n", __FUNCTION__);
+  //  xr_driver_destroy (window->print_xrd);
+}
+
+static void
+done (GtkPrintOperation *operation,
+      GtkPrintOperationResult   result,
+      gpointer           user_data)    
+{
+  g_print ("%s %d\n", __FUNCTION__, result);
+}
+
+
+static void
+draw_page (GtkPrintOperation *operation,
+          GtkPrintContext   *context,
+          gint               page_number,
+          PsppireOutputWindow *window)
+{
+  g_print ("%s: %d\n", __FUNCTION__, page_number);
+
+  xr_driver_next_page (window->print_xrd, gtk_print_context_get_cairo_context (context));
+  while ( window->print_item < window->n_items)
+    {
+      xr_driver_output_item (window->print_xrd, window->items [window->print_item++]);
+      if ( xr_driver_need_new_page (window->print_xrd) )
+         break;          
+    }
+}
+
+
+static void
+psppire_output_window_print (PsppireOutputWindow *window)
+{
+  GtkPrintOperationResult res;
+
+  GtkPrintOperation *print = gtk_print_operation_new ();
+
+  if (window->print_settings != NULL) 
+    gtk_print_operation_set_print_settings (print, window->print_settings);
+
+  g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), window);
+  g_signal_connect (print, "end_print", G_CALLBACK (end_print),     window);
+  g_signal_connect (print, "paginate", G_CALLBACK (paginate),       window);
+  g_signal_connect (print, "draw_page", G_CALLBACK (draw_page),     window);
+  g_signal_connect (print, "done", G_CALLBACK (done),               window);
+
+  res = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+                                 GTK_WINDOW (window), NULL);
+
+  if (res == GTK_PRINT_OPERATION_RESULT_APPLY)
+    {
+      if (window->print_settings != NULL)
+        g_object_unref (window->print_settings);
+      window->print_settings = g_object_ref (gtk_print_operation_get_print_settings (print));
+      
+    }
+
+  g_object_unref (print);
+}