output-item: Collapse the inheritance hierarchy into a single struct.
[pspp] / src / ui / gui / psppire-output-view.c
index 3e9151f6089944eedc733f6c10623417a1ce2f6d..6d704ae1bccf1bba19eaa468cbddaf6eacbca03f 100644 (file)
 #include "output/cairo-pager.h"
 #include "output/driver-provider.h"
 #include "output/driver.h"
-#include "output/chart-item.h"
-#include "output/group-item.h"
-#include "output/message-item.h"
 #include "output/output-item.h"
-#include "output/output-item-provider.h"
-#include "output/table-item.h"
-#include "output/text-item.h"
+#include "output/pivot-table.h"
 
 #include "gl/c-xvasprintf.h"
 #include "gl/minmax.h"
@@ -84,9 +79,9 @@ struct psppire_output_view
 
 enum
   {
-    COL_NAME,                   /* Table name. */
+    COL_LABEL,                  /* Output item label. */
     COL_ADDR,                   /* Pointer to the table */
-    COL_Y,                      /* Y position of top of name. */
+    COL_Y,                      /* Y position of top of object. */
     N_COLS
   };
 
@@ -151,19 +146,15 @@ get_xr_fsm_style (struct psppire_output_view *view)
 
   PangoFontDescription *pf;
   gtk_style_context_get (context, state, "font", &pf, NULL);
-  PangoFontDescription *ff = pango_font_description_from_string ("Monospace");
-  pango_font_description_set_size (ff, pango_font_description_get_size (pf));
 
   struct xr_fsm_style *style = xmalloc (sizeof *style);
   *style = (struct xr_fsm_style) {
     .ref_cnt = 1,
     .size = { [TABLE_HORZ] = xr_width, [TABLE_VERT] = INT_MAX },
     .min_break = { [TABLE_HORZ] = xr_width / 2, [TABLE_VERT] = 0 },
-    .fonts = {
-      [XR_FONT_PROPORTIONAL] = pf,
-      [XR_FONT_FIXED] = ff,
-    },
+    .font = pf,
     .use_system_colors = true,
+    .object_spacing = XR_POINT * 12,
     .font_resolution = 96.0,
   };
 
@@ -334,10 +325,10 @@ rerender (struct psppire_output_view *view)
       if (view->y > 0)
         view->y += view->object_spacing;
 
-      if (is_group_open_item (item->item))
+      if (item->item->type == OUTPUT_ITEM_GROUP_OPEN)
         continue;
 
-      r = xr_fsm_create (item->item, view->style, cr);
+      r = xr_fsm_create_for_scrolling (item->item, view->style, cr);
       if (r == NULL)
         {
           g_warn_if_reached ();
@@ -361,11 +352,9 @@ rerender (struct psppire_output_view *view)
           gtk_layout_move (view->output, item->drawing_area, xpos, view->y);
         }
 
-      if (is_table_item (item->item))
-        {
-          const struct table_item *ti = to_table_item (item->item);
-          gtk_widget_set_tooltip_text (item->drawing_area, ti->notes);
-        }
+      if (item->item->type == OUTPUT_ITEM_TABLE)
+        gtk_widget_set_tooltip_text (item->drawing_area,
+                                     item->item->table->notes);
 
       {
        gint minw;
@@ -405,10 +394,9 @@ psppire_output_view_put (struct psppire_output_view *view,
 {
   struct output_view_item *view_item;
   GtkWidget *drawing_area;
-  struct string name;
   int tw, th;
 
-  if (is_group_close_item (item))
+  if (item->type == OUTPUT_ITEM_GROUP_CLOSE)
     {
       if (view->cur_group)
         {
@@ -420,11 +408,12 @@ psppire_output_view_put (struct psppire_output_view *view,
         }
       return;
     }
-  else if (is_text_item (item))
+  else if (item->type == OUTPUT_ITEM_TEXT)
     {
-      const struct text_item *text_item = to_text_item (item);
-      const char *text = text_item_get_text (text_item);
-      if (text[0] == '\0')
+      char *text = text_item_get_plain_text (item);
+      bool text_is_empty = text[0] == '\0';
+      free (text);
+      if (text_is_empty)
         return;
     }
 
@@ -436,7 +425,7 @@ psppire_output_view_put (struct psppire_output_view *view,
   view_item->drawing_area = NULL;
 
   GdkWindow *win = gtk_widget_get_window (GTK_WIDGET (view->output));
-  if (is_group_open_item (item))
+  if (item->type == OUTPUT_ITEM_GROUP_OPEN)
     tw = th = 0;
   else if (win)
     {
@@ -452,7 +441,7 @@ psppire_output_view_put (struct psppire_output_view *view,
       if (view->y > 0)
         view->y += view->object_spacing;
 
-      struct xr_fsm *r = xr_fsm_create (item, view->style, cr);
+      struct xr_fsm *r = xr_fsm_create_for_scrolling (item, view->style, cr);
       if (r == NULL)
        {
          gdk_window_end_draw_frame (win, ctx);
@@ -473,8 +462,6 @@ psppire_output_view_put (struct psppire_output_view *view,
       GtkTreeStore *store = GTK_TREE_STORE (
         gtk_tree_view_get_model (view->overview));
 
-      ds_init_empty (&name);
-
       /* Create a new node in the tree and puts a reference to it in 'iter'. */
       GtkTreeIter iter;
       GtkTreeIter parent;
@@ -486,52 +473,18 @@ psppire_output_view_put (struct psppire_output_view *view,
       else
         gtk_tree_store_append (store, &iter, NULL);
 
-      if (is_group_open_item (item))
+      if (item->type == OUTPUT_ITEM_GROUP_OPEN)
         {
           gtk_tree_path_free (view->cur_group);
           view->cur_group = gtk_tree_model_get_path (GTK_TREE_MODEL (store),
                                                      &iter);
         }
 
-      ds_clear (&name);
-      if (is_text_item (item))
-        {
-          const struct text_item *text_item = to_text_item (item);
-          ds_put_cstr (&name, text_item_type_to_string (
-                         text_item_get_type (text_item)));
-        }
-      else if (is_message_item (item))
-        {
-          const struct message_item *msg_item = to_message_item (item);
-          const struct msg *msg = message_item_get_msg (msg_item);
-          ds_put_format (&name, "%s: %s", _("Message"),
-                         msg_severity_to_string (msg->severity));
-        }
-      else if (is_table_item (item))
-        {
-          const struct table_item_text *title
-            = table_item_get_title (to_table_item (item));
-          if (title != NULL)
-            ds_put_format (&name, "Table: %s", title->content);
-          else
-            ds_put_cstr (&name, "Table");
-        }
-      else if (is_chart_item (item))
-        {
-          const char *s = chart_item_get_title (to_chart_item (item));
-          if (s != NULL)
-            ds_put_format (&name, "Chart: %s", s);
-          else
-            ds_put_cstr (&name, "Chart");
-        }
-      else if (is_group_open_item (item))
-        ds_put_cstr (&name, to_group_open_item (item)->command_name);
       gtk_tree_store_set (store, &iter,
-                          COL_NAME, ds_cstr (&name),
+                          COL_LABEL, output_item_get_label (item),
                          COL_ADDR, item,
-                          COL_Y, (view->y),
+                          COL_Y, view->y,
                           -1);
-      ds_destroy (&name);
 
       GtkTreePath *path = gtk_tree_model_get_path (
         GTK_TREE_MODEL (store), &iter);
@@ -783,8 +736,7 @@ build_target_list (const struct output_item *item)
 {
   GtkTargetList *tl = gtk_target_list_new (targets, G_N_ELEMENTS (targets));
   g_return_val_if_fail (tl, NULL);
-  if (is_table_item (item) ||
-      is_chart_item (item))
+  if (item->type == OUTPUT_ITEM_TABLE || item->type == OUTPUT_ITEM_CHART)
     gtk_target_list_add_image_targets (tl, SELECT_FMT_IMG, TRUE);
   return tl;
 }
@@ -877,7 +829,7 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview)
 
       model = GTK_TREE_MODEL (gtk_tree_store_new (
                                 N_COLS,
-                                G_TYPE_STRING,  /* COL_NAME */
+                                G_TYPE_STRING,  /* COL_LABEL */
                                 G_TYPE_POINTER, /* COL_ADDR */
                                 G_TYPE_LONG));  /* COL_Y */
       gtk_tree_view_set_model (overview, model);
@@ -887,7 +839,7 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview)
       gtk_tree_view_append_column (GTK_TREE_VIEW (overview), column);
       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_NAME);
+      gtk_tree_view_column_add_attribute (column, renderer, "text", COL_LABEL);
 
       g_signal_connect (GTK_TREE_VIEW (overview),
                         "row-activated", G_CALLBACK (on_row_activate), view);
@@ -995,11 +947,6 @@ create_xr_print_driver (GtkPrintContext *context, struct psppire_output_view *vi
   for (int a = 0; a < TABLE_N_AXES; a++)
     size[a] = paper[a] - margins[a][0] - margins[a][1];
 
-  PangoFontDescription *proportional_font
-    = pango_font_description_from_string ("Sans Serif 10");
-  PangoFontDescription *fixed_font
-    = pango_font_description_from_string ("Monospace 10");
-
   view->page_style = xmalloc (sizeof *view->page_style);
   *view->page_style = (struct xr_page_style) {
     .ref_cnt = 1,
@@ -1009,7 +956,6 @@ create_xr_print_driver (GtkPrintContext *context, struct psppire_output_view *vi
       [V] = { margins[V][0], margins[V][1] },
     },
     .initial_page_number = 1,
-    .object_spacing = 12 * XR_POINT,
   };
 
   view->fsm_style = xmalloc (sizeof *view->fsm_style);
@@ -1018,12 +964,10 @@ create_xr_print_driver (GtkPrintContext *context, struct psppire_output_view *vi
 
     .size = { [H] = size[H], [V] = size[V] },
     .min_break = { [H] = size[H] / 2, [V] = size[V] / 2 },
-    .fonts = {
-      [XR_FONT_PROPORTIONAL] = proportional_font,
-      [XR_FONT_FIXED] = fixed_font,
-    },
+    .font = pango_font_description_from_string ("Sans Serif 10"),
     .fg = CELL_COLOR_BLACK,
     .use_system_colors = false,
+    .object_spacing = 12 * XR_POINT,
     .font_resolution = 72.0
   };
 
@@ -1152,7 +1096,7 @@ psppire_output_view_submit (struct output_driver *this,
 {
   struct psppire_output_view_driver *povd = psppire_output_view_driver_cast (this);
 
-  if (is_table_item (item))
+  if (item->type == OUTPUT_ITEM_TABLE)
     psppire_output_view_put (povd->view, item);
 }