psppire-output-view: Export correctly to drivers that don't handle groups.
[pspp] / src / ui / gui / psppire-output-view.c
index 2d4a873535f62e73b928f1382636f20c4b72dde3..07dbd646161dbf5dc56ee1bdd0aee541bc880040 100644 (file)
@@ -44,6 +44,7 @@ struct output_view_item
     struct output_item *item;
     GtkWidget *drawing_area;
     int width, height;
+    int nesting_depth;
   };
 
 struct psppire_output_view
@@ -390,9 +391,13 @@ rerender (struct psppire_output_view *view)
 static bool
 init_output_view_item (struct output_view_item *view_item,
                        struct psppire_output_view *view,
-                       const struct output_item *item)
+                       const struct output_item *item,
+                       int nesting_depth)
 {
-  *view_item = (struct output_view_item) { .item = output_item_ref (item) };
+  *view_item = (struct output_view_item) {
+    .item = output_item_ref (item),
+    .nesting_depth = nesting_depth
+  };
 
   GdkWindow *win = gtk_widget_get_window (GTK_WIDGET (view->output));
   if (win && item->type != OUTPUT_ITEM_GROUP)
@@ -446,7 +451,8 @@ psppire_output_view_put__ (struct psppire_output_view *view,
     view->items = x2nrealloc (view->items, &view->allocated_items,
                               sizeof *view->items);
   struct output_view_item *view_item = &view->items[view->n_items];
-  if (!init_output_view_item (view_item, view, item))
+  if (!init_output_view_item (view_item, view, item,
+                              parent_path ? gtk_tree_path_get_depth (parent_path) : 0))
     return;
   view->n_items++;
 
@@ -797,10 +803,6 @@ struct psppire_output_view *
 psppire_output_view_new (GtkLayout *output, GtkTreeView *overview)
 {
   struct psppire_output_view *view;
-  GtkTreeViewColumn *column;
-  GtkCellRenderer *renderer;
-
-  GtkTreeModel *model;
 
   view = xmalloc (sizeof *view);
   *view = (struct psppire_output_view) {
@@ -827,7 +829,7 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview)
     {
       g_signal_connect (overview, "realize", G_CALLBACK (on_realize), view);
 
-      model = GTK_TREE_MODEL (gtk_tree_store_new (
+      GtkTreeModel *model = GTK_TREE_MODEL (gtk_tree_store_new (
                                 N_COLS,
                                 G_TYPE_STRING,  /* COL_LABEL */
                                 G_TYPE_POINTER, /* COL_ADDR */
@@ -835,9 +837,9 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview)
       gtk_tree_view_set_model (overview, model);
       g_object_unref (model);
 
-      column = gtk_tree_view_column_new ();
+      GtkTreeViewColumn *column = gtk_tree_view_column_new ();
       gtk_tree_view_append_column (GTK_TREE_VIEW (overview), column);
-      renderer = gtk_cell_renderer_text_new ();
+      GtkCellRenderer * renderer = gtk_cell_renderer_text_new ();
       gtk_tree_view_column_pack_start (column, renderer, TRUE);
       gtk_tree_view_column_add_attribute (column, renderer, "text", COL_LABEL);
 
@@ -873,27 +875,21 @@ psppire_output_view_destroy (struct psppire_output_view *view)
   free (view);
 }
 
-void
-psppire_output_view_clear (struct psppire_output_view *view)
-{
-  size_t i;
-
-  view->max_width = 0;
-  view->y = 0;
+/* Export. */
 
-  for (i = 0; i < view->n_items; i++)
+static void
+psppire_output_view_export__ (struct output_driver *driver,
+                              const struct output_item *item)
+{
+  if (item->type == OUTPUT_ITEM_GROUP && !driver->class->handles_groups)
     {
-      gtk_container_remove (GTK_CONTAINER (view->output),
-                            view->items[i].drawing_area);
-      output_item_unref (view->items[i].item);
+      for (size_t i = 0; i < item->group.n_children; i++)
+        psppire_output_view_export__ (driver, item->group.children[i]);
     }
-  free (view->items);
-  view->items = NULL;
-  view->n_items = view->allocated_items = 0;
+  else
+    driver->class->submit (driver, item);
 }
 
-/* Export. */
-
 void
 psppire_output_view_export (struct psppire_output_view *view,
                             struct string_map *options)
@@ -906,7 +902,8 @@ psppire_output_view_export (struct psppire_output_view *view,
       size_t i;
 
       for (i = 0; i < view->n_items; i++)
-        driver->class->submit (driver, view->items[i].item);
+        if (view->items[i].nesting_depth == 0)
+          psppire_output_view_export__ (driver, view->items[i].item);
       output_driver_destroy (driver);
     }
 }
@@ -982,29 +979,32 @@ paginate (GtkPrintOperation *operation,
          complete.  Don't let that screw up printing. */
       return TRUE;
     }
-  else if (view->print_item < view->n_items)
+
+  while (view->print_item < view->n_items)
     {
-      xr_pager_add_item (view->pager, view->items[view->print_item++].item);
-      while (xr_pager_needs_new_page (view->pager))
-       {
-         xr_pager_add_page (view->pager,
-                             get_cairo_context_from_print_context (context));
-         view->print_n_pages ++;
-       }
-      return FALSE;
+      const struct output_view_item *item = &view->items[view->print_item++];
+      if (item->nesting_depth == 0)
+        {
+          xr_pager_add_item (view->pager, item->item);
+          while (xr_pager_needs_new_page (view->pager))
+            {
+              xr_pager_add_page (view->pager,
+                                 get_cairo_context_from_print_context (context));
+              view->print_n_pages ++;
+            }
+          return FALSE;
+        }
     }
-  else
-    {
-      gtk_print_operation_set_n_pages (operation, MAX (1, view->print_n_pages));
 
-      /* Re-create the driver to do the real printing. */
-      xr_pager_destroy (view->pager);
-      view->pager = xr_pager_create (view->page_style, view->fsm_style);
-      view->print_item = 0;
-      view->paginated = TRUE;
+  gtk_print_operation_set_n_pages (operation, MAX (1, view->print_n_pages));
 
-      return TRUE;
-    }
+  /* Re-create the driver to do the real printing. */
+  xr_pager_destroy (view->pager);
+  view->pager = xr_pager_create (view->page_style, view->fsm_style);
+  view->print_item = 0;
+  view->paginated = TRUE;
+
+  return TRUE;
 }
 
 static void
@@ -1039,7 +1039,11 @@ draw_page (GtkPrintOperation *operation,
                      get_cairo_context_from_print_context (context));
   while (!xr_pager_needs_new_page (view->pager)
          && view->print_item < view->n_items)
-    xr_pager_add_item (view->pager, view->items [view->print_item++].item);
+    {
+      const struct output_view_item *item = &view->items [view->print_item++];
+      if (item->nesting_depth == 0)
+        xr_pager_add_item (view->pager, item->item);
+    }
 }