+
+ if (item->item->type == OUTPUT_ITEM_TABLE)
+ gtk_widget_set_tooltip_text (item->drawing_area,
+ item->item->table->notes);
+
+ {
+ gint minw;
+ gint minh;
+ /* This code probably doesn't bring us anthing, but Gtk
+ shows warnings if get_preferred_width/height is not
+ called before the size_allocate below is called. */
+ gtk_widget_get_preferred_width (item->drawing_area, &minw, NULL);
+ gtk_widget_get_preferred_height (item->drawing_area, &minh, NULL);
+ if (th > minh) th = minh;
+ if (tw > minw) tw = minw;
+ }
+ alloc.x = xpos;
+ alloc.y = view->y;
+ alloc.width = tw;
+ alloc.height = th;
+
+ gtk_widget_size_allocate (item->drawing_area, &alloc);
+
+ if (view->max_width < tw)
+ view->max_width = tw;
+ view->y += th;
+ }
+
+ gtk_layout_set_size (view->output,
+ view->max_width + view->object_spacing,
+ view->y + view->object_spacing);
+
+ gdk_window_end_draw_frame (win, ctx);
+ cairo_region_destroy (region);
+}
+
+static bool
+init_output_view_item (struct output_view_item *view_item,
+ struct psppire_output_view *view,
+ const struct output_item *item,
+ int nesting_depth)
+{
+ *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)
+ {
+ if (!view->style)
+ view->style = get_xr_fsm_style (view);
+
+ cairo_region_t *region = gdk_window_get_visible_region (win);
+ GdkDrawingContext *ctx = gdk_window_begin_draw_frame (win, region);
+ cairo_t *cr = gdk_drawing_context_get_cairo_context (ctx);
+
+ if (view->y > 0)
+ view->y += view->object_spacing;
+
+ struct xr_fsm *r = xr_fsm_create_for_scrolling (item, view->style, cr);
+ if (r == NULL)
+ {
+ gdk_window_end_draw_frame (win, ctx);
+ cairo_region_destroy (region);
+
+ output_item_unref (view_item->item);
+ return false;
+ }
+
+ xr_fsm_measure (r, cr, &view_item->width, &view_item->height);
+ view_item->drawing_area = gtk_drawing_area_new ();
+ create_drawing_area (view, view_item->drawing_area, r, view_item->width,
+ view_item->height, item);
+ gdk_window_end_draw_frame (win, ctx);
+ cairo_region_destroy (region);
+ }
+
+ return true;
+}
+
+static void
+psppire_output_view_put__ (struct psppire_output_view *view,
+ const struct output_item *item,
+ GtkTreePath *parent_path)
+{
+ if (item->type == OUTPUT_ITEM_TEXT)
+ {
+ char *text = text_item_get_plain_text (item);
+ bool text_is_empty = text[0] == '\0';
+ free (text);
+ if (text_is_empty)
+ return;
+ }
+
+ if (view->n_items >= view->allocated_items)
+ 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,
+ parent_path ? gtk_tree_path_get_depth (parent_path) : 0))
+ return;
+ view->n_items++;
+
+ GtkTreePath *path = NULL;
+ if (view->overview)
+ {
+ GtkTreeStore *store = GTK_TREE_STORE (
+ gtk_tree_view_get_model (view->overview));
+
+ /* Create a new node in the tree and puts a reference to it in 'iter'. */
+ GtkTreeIter iter;
+ GtkTreeIter parent;
+ if (parent_path
+ && gtk_tree_path_get_depth (parent_path) > 0
+ && gtk_tree_model_get_iter (GTK_TREE_MODEL (store),
+ &parent, parent_path))
+ gtk_tree_store_append (store, &iter, &parent);
+ else
+ gtk_tree_store_append (store, &iter, NULL);
+