X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-output-view.c;h=2ac85a52ada2e3418963a86fbab8cb6718fd5865;hb=e94442a3b00c1f22952586cc26b7be60617b93e1;hp=93afbd6035d7be38183a74fd9497c75d31bcf932;hpb=68a0247ad78ed77de1f4b3a96a734fd6c2994984;p=pspp diff --git a/src/ui/gui/psppire-output-view.c b/src/ui/gui/psppire-output-view.c index 93afbd6035..2ac85a52ad 100644 --- a/src/ui/gui/psppire-output-view.c +++ b/src/ui/gui/psppire-output-view.c @@ -1,5 +1,5 @@ /* PSPPIRE - a graphical user interface for PSPP. - Copyright (C) 2008-2015 Free Software Foundation. + Copyright (C) 2008-2015, 2016 Free Software Foundation. This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,8 +27,10 @@ #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" @@ -58,8 +60,7 @@ struct psppire_output_view struct string_map render_opts; GtkTreeView *overview; - GtkTreeIter cur_command; - bool in_command; + GtkTreePath *cur_group; GtkWidget *toplevel; @@ -82,46 +83,34 @@ enum N_COLS }; -static void on_dwgarea_realize (GtkWidget *widget, gpointer data); - +/* Draws a white background on the GtkLayout to match the white background of + each of the output items. */ static gboolean -expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data) +layout_draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) { - struct psppire_output_view *view = data; - struct xr_rendering *r = g_object_get_data (G_OBJECT (widget), "rendering"); - cairo_t *cr = gdk_cairo_create (widget->window); - - const GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (view->output)); - - PangoFontDescription *font_desc; - char *font_name; - - gchar *fgc = - gdk_color_to_string (&style->text[gtk_widget_get_state (GTK_WIDGET (view->output))]); + cairo_save (cr); - string_map_replace (&view->render_opts, "foreground-color", fgc); + int width = gtk_widget_get_allocated_width (widget); + int height = gtk_widget_get_allocated_height (widget); + cairo_rectangle (cr, 0, 0, width, height); + cairo_set_source_rgb (cr, 1.0, 1.0, 1.0); + cairo_fill (cr); - free (fgc); + cairo_restore (cr); - /* Use GTK+ default font as proportional font. */ - font_name = pango_font_description_to_string (style->font_desc); - string_map_replace (&view->render_opts, "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_replace (&view->render_opts, "emph-font", font_name); - g_free (font_name); - pango_font_description_free (font_desc); - - xr_rendering_apply_options (r, &view->render_opts); + return FALSE; /* Continue drawing the GtkDrawingAreas. */ +} - xr_rendering_draw (r, cr, event->area.x, event->area.y, - event->area.width, event->area.height); - cairo_destroy (cr); +static gboolean +draw_callback (GtkWidget *widget, cairo_t *cr, gpointer data) +{ + GdkRectangle clip; + if (!gdk_cairo_get_clip_rectangle (cr, &clip)) + return TRUE; + struct xr_rendering *r = g_object_get_data (G_OBJECT (widget), "rendering"); + xr_rendering_draw (r, cr, clip.x, clip.y, + clip.x + clip.width, clip.y + clip.height); return TRUE; } @@ -133,35 +122,25 @@ free_rendering (gpointer rendering_) } static void -create_xr (struct psppire_output_view *view) +get_xr_options (struct psppire_output_view *view, struct string_map *options) { - const GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (view->output)); - struct text_item *text_item; - PangoFontDescription *font_desc; - struct xr_rendering *r; - char *font_name; - int font_width; - cairo_t *cr; - gchar *fgc; - - cr = gdk_cairo_create (GTK_WIDGET (view->output)->window); - - /* Set the widget's text color as the foreground color for the output driver */ - fgc = gdk_color_to_string (&style->text[gtk_widget_get_state (GTK_WIDGET (view->output))]); + string_map_clear (options); - string_map_insert (&view->render_opts, "foreground-color", fgc); - g_free (fgc); + GtkStyleContext *context + = gtk_widget_get_style_context (GTK_WIDGET (view->output)); + GtkStateFlags state = gtk_widget_get_state_flags (GTK_WIDGET (view->output)); /* Use GTK+ default font as proportional font. */ - font_name = pango_font_description_to_string (style->font_desc); - string_map_insert (&view->render_opts, "prop-font", font_name); + PangoFontDescription *font_desc; + gtk_style_context_get (context, state, "font", &font_desc, NULL); + char *font_name = pango_font_description_to_string (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 (&view->render_opts, "emph-font", font_name); + string_map_insert (options, "emph-font", font_name); g_free (font_name); pango_font_description_free (font_desc); @@ -170,22 +149,51 @@ create_xr (struct psppire_output_view *view) 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_nocopy (&view->render_opts, xstrdup ("paper-size"), + string_map_insert_nocopy (options, xstrdup ("paper-size"), xasprintf ("%dx1000000pt", view->render_width)); - string_map_insert (&view->render_opts, "left-margin", "0"); - string_map_insert (&view->render_opts, "right-margin", "0"); - string_map_insert (&view->render_opts, "top-margin", "0"); - string_map_insert (&view->render_opts, "bottom-margin", "0"); + 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"); +} - view->xr = xr_driver_create (cr, &view->render_opts); +static void +create_xr (struct psppire_output_view *view) +{ + get_xr_options (view, &view->render_opts); + + struct string_map options; + string_map_clone (&options, &view->render_opts); + + GdkWindow *win = gtk_layout_get_bin_window (view->output); + 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); + + view->xr = xr_driver_create (cr, &options); + string_map_destroy (&options); - text_item = text_item_create (TEXT_ITEM_PARAGRAPH, "X"); - r = xr_rendering_create (view->xr, text_item_super (text_item), cr); - xr_rendering_measure (r, &font_width, &view->font_height); - /* xr_rendering_destroy (r); */ + struct text_item *text_item = text_item_create (TEXT_ITEM_LOG, "X"); + struct xr_rendering *r + = xr_rendering_create (view->xr, text_item_super (text_item), cr); + xr_rendering_measure (r, NULL, &view->font_height); + xr_rendering_destroy (r); text_item_unref (text_item); - cairo_destroy (cr); + gdk_window_end_draw_frame (win, ctx); + cairo_region_destroy (region); +} + +/* Return the horizontal position to place a widget whose + width is CHILD_WIDTH */ +static gint +get_xpos (const struct psppire_output_view *view, gint child_width) +{ + GdkWindow *gdkw = gtk_widget_get_window (GTK_WIDGET (view->output)); + guint w = gdk_window_get_width (gdkw); + int gutter = 0; + g_object_get (view->output, "border-width", &gutter, NULL); + return (gtk_widget_get_direction (GTK_WIDGET (view->output)) == GTK_TEXT_DIR_RTL) ? w - child_width - gutter: gutter; } static void @@ -196,13 +204,13 @@ create_drawing_area (struct psppire_output_view *view, g_object_set_data_full (G_OBJECT (drawing_area), "rendering", r, free_rendering); - g_signal_connect (drawing_area, "realize", - G_CALLBACK (on_dwgarea_realize), view); - g_signal_connect (drawing_area, "expose_event", - G_CALLBACK (expose_event_callback), view); + g_signal_connect (drawing_area, "draw", + G_CALLBACK (draw_callback), view); gtk_widget_set_size_request (drawing_area, tw, th); - gtk_layout_put (view->output, drawing_area, 0, view->y); + gint xpos = get_xpos (view, tw); + + gtk_layout_put (view->output, drawing_area, xpos, view->y); gtk_widget_show (drawing_area); } @@ -211,27 +219,33 @@ static void rerender (struct psppire_output_view *view) { struct output_view_item *item; - cairo_t *cr; + GdkWindow *gdkw = gtk_widget_get_window (GTK_WIDGET (view->output)); - if (!view->n_items || !GTK_WIDGET (view->output)->window) + if (!view->n_items || ! gdkw) return; - string_map_clear (&view->render_opts); - xr_driver_destroy (view->xr); - create_xr (view); + if (view->xr == NULL) + create_xr (view); - cr = gdk_cairo_create (GTK_WIDGET (view->output)->window); + GdkWindow *win = gtk_layout_get_bin_window (view->output); + 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); view->y = 0; view->max_width = 0; for (item = view->items; item < &view->items[view->n_items]; item++) { struct xr_rendering *r; + GtkAllocation alloc; int tw, th; if (view->y > 0) view->y += view->font_height / 2; + if (is_group_open_item (item->item)) + continue; + r = xr_rendering_create (view->xr, item->item, cr); if (r == NULL) { @@ -241,6 +255,8 @@ rerender (struct psppire_output_view *view) xr_rendering_measure (r, &tw, &th); + gint xpos = get_xpos (view, tw); + if (!item->drawing_area) { item->drawing_area = gtk_drawing_area_new (); @@ -251,16 +267,38 @@ rerender (struct psppire_output_view *view) g_object_set_data_full (G_OBJECT (item->drawing_area), "rendering", r, free_rendering); gtk_widget_set_size_request (item->drawing_area, tw, th); - gtk_layout_move (view->output, item->drawing_area, 0, view->y); + gtk_layout_move (view->output, item->drawing_area, xpos, view->y); } + { + 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->y); - cairo_destroy (cr); + gtk_layout_set_size (view->output, + view->max_width + view->font_height, + view->y + view->font_height); + + gdk_window_end_draw_frame (win, ctx); + cairo_region_destroy (region); } void @@ -269,26 +307,26 @@ psppire_output_view_put (struct psppire_output_view *view, { struct output_view_item *view_item; GtkWidget *drawing_area; - struct xr_rendering *r; struct string name; - GtkTreeStore *store; - cairo_t *cr = NULL; - GtkTreePath *path; - GtkTreeIter iter; int tw, th; - if (is_text_item (item)) + if (is_group_close_item (item)) { - const struct text_item *text_item = to_text_item (item); - enum text_item_type type = text_item_get_type (text_item); - const char *text = text_item_get_text (text_item); - - if (type == TEXT_ITEM_COMMAND_CLOSE) + if (view->cur_group) { - view->in_command = false; - return; + if (!gtk_tree_path_up (view->cur_group)) + { + gtk_tree_path_free (view->cur_group); + view->cur_group = NULL; + } } - else if (text[0] == '\0') + return; + } + else if (is_text_item (item)) + { + const struct text_item *text_item = to_text_item (item); + const char *text = text_item_get_text (text_item); + if (text[0] == '\0') return; } @@ -299,52 +337,72 @@ psppire_output_view_put (struct psppire_output_view *view, view_item->item = output_item_ref (item); view_item->drawing_area = NULL; - if (GTK_WIDGET (view->output)->window) + GdkWindow *win = gtk_widget_get_window (GTK_WIDGET (view->output)); + if (is_group_open_item (item)) + tw = th = 0; + else if (win) { view_item->drawing_area = drawing_area = gtk_drawing_area_new (); - cr = gdk_cairo_create (GTK_WIDGET (view->output)->window); if (view->xr == NULL) create_xr (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->font_height / 2; - r = xr_rendering_create (view->xr, item, cr); + struct xr_rendering *r = xr_rendering_create (view->xr, item, cr); if (r == NULL) - goto done; + { + gdk_window_end_draw_frame (win, ctx); + cairo_region_destroy (region); + return; + } xr_rendering_measure (r, &tw, &th); create_drawing_area (view, drawing_area, r, tw, th); + gdk_window_end_draw_frame (win, ctx); + cairo_region_destroy (region); } else tw = th = 0; - if (view->overview - && (!is_text_item (item) - || text_item_get_type (to_text_item (item)) != TEXT_ITEM_SYNTAX - || !view->in_command)) + if (view->overview) { - store = GTK_TREE_STORE (gtk_tree_view_get_model (view->overview)); + GtkTreeStore *store = GTK_TREE_STORE ( + gtk_tree_view_get_model (view->overview)); ds_init_empty (&name); - if (is_text_item (item) - && text_item_get_type (to_text_item (item)) == TEXT_ITEM_COMMAND_OPEN) - { - gtk_tree_store_append (store, &iter, NULL); - view->cur_command = iter; /* XXX shouldn't save a GtkTreeIter */ - view->in_command = true; - } + + /* Create a new node in the tree and puts a reference to it in 'iter'. */ + GtkTreeIter iter; + GtkTreeIter parent; + if (view->cur_group + && gtk_tree_path_get_depth (view->cur_group) > 0 + && gtk_tree_model_get_iter (GTK_TREE_MODEL (store), + &parent, view->cur_group)) + gtk_tree_store_append (store, &iter, &parent); else + gtk_tree_store_append (store, &iter, NULL); + + if (is_group_open_item (item)) { - GtkTreeIter *p = view->in_command ? &view->cur_command : NULL; - gtk_tree_store_append (store, &iter, p); + 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)) - ds_put_cstr (&name, text_item_get_text (to_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); @@ -354,9 +412,10 @@ psppire_output_view_put (struct psppire_output_view *view, } else if (is_table_item (item)) { - const char *title = table_item_get_title (to_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); + ds_put_format (&name, "Table: %s", title->content); else ds_put_cstr (&name, "Table"); } @@ -368,6 +427,8 @@ psppire_output_view_put (struct psppire_output_view *view, 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_ADDR, item, @@ -375,7 +436,8 @@ psppire_output_view_put (struct psppire_output_view *view, -1); ds_destroy (&name); - path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); + GtkTreePath *path = gtk_tree_model_get_path ( + GTK_TREE_MODEL (store), &iter); gtk_tree_view_expand_row (view->overview, path, TRUE); gtk_tree_path_free (path); } @@ -385,9 +447,6 @@ psppire_output_view_put (struct psppire_output_view *view, view->y += th; gtk_layout_set_size (view->output, view->max_width, view->y); - -done: - cairo_destroy (cr); } static void @@ -410,9 +469,9 @@ on_row_activate (GtkTreeView *overview, y = g_value_get_long (&value); g_value_unset (&value); - vadj = gtk_layout_get_vadjustment (view->output); - min = vadj->lower; - max = vadj->upper - vadj->page_size; + vadj = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (view->output)); + min = gtk_adjustment_get_lower (vadj); + max = gtk_adjustment_get_upper (vadj) - gtk_adjustment_get_page_size (vadj); if (y < min) y = min; else if (y > max) @@ -421,32 +480,24 @@ on_row_activate (GtkTreeView *overview, } static void -copy_base_to_bg (GtkWidget *dest, GtkWidget *src) +on_style_updated (GtkWidget *toplevel, struct psppire_output_view *view) { - int i; - for (i = 0; i < 5; ++i) - { - gtk_widget_modify_bg (dest, i, >k_widget_get_style (src)->base[i]); - gtk_widget_modify_fg (dest, i, >k_widget_get_style (src)->text[i]); - } -} + if (!view->n_items || !gtk_widget_get_window (GTK_WIDGET (view->output))) + return; -/* Copy the base style from the parent widget to the container and all its - children. We do this because the container's primary purpose is to display - text. This way psppire appears to follow the chosen gnome theme. */ -static void -on_style_set (GtkWidget *toplevel, GtkStyle *prev, - struct psppire_output_view *view) -{ - copy_base_to_bg (GTK_WIDGET (view->output), toplevel); - gtk_container_foreach (GTK_CONTAINER (view->output), - (GtkCallback) copy_base_to_bg, view->output); -} + /* GTK+ fires this signal for trivial changes like the mouse moving in or out + of the window. Check whether the actual rendering options changed and + re-render only if they did. */ + struct string_map options = STRING_MAP_INITIALIZER (options); + get_xr_options (view, &options); + if (!string_map_equals (&options, &view->render_opts)) + { + xr_driver_destroy (view->xr); + view->xr = NULL; -static void -on_dwgarea_realize (GtkWidget *dwg_area, gpointer data) -{ - copy_base_to_bg (dwg_area, gtk_widget_get_toplevel (dwg_area)); + rerender (view); + } + string_map_destroy (&options); } enum { @@ -483,7 +534,7 @@ clipboard_get_cb (GtkClipboard *clipboard, GList *rows = gtk_tree_selection_get_selected_rows (sel, &model); GList *n = rows; - if ( n == NULL) + if (n == NULL) return; if (path_search (dirname, sizeof dirname, NULL, NULL, true) @@ -541,7 +592,7 @@ clipboard_get_cb (GtkClipboard *clipboard, n = n->next; } - if ( driver->class->flush) + if (driver->class->flush) driver->class->flush (driver); @@ -550,9 +601,9 @@ clipboard_get_cb (GtkClipboard *clipboard, output_driver_destroy (driver); driver = NULL; - if ( g_file_get_contents (filename, &text, &length, NULL) ) + if (g_file_get_contents (filename, &text, &length, NULL)) { - gtk_selection_data_set (selection_data, selection_data->target, + gtk_selection_data_set (selection_data, gtk_selection_data_get_target (selection_data), 8, (const guchar *) text, length); } @@ -605,10 +656,12 @@ on_copy (struct psppire_output_view *view) } static void -on_selection_change (GtkTreeSelection *sel, GtkAction *copy_action) +on_selection_change (GtkTreeSelection *sel, GAction *copy_action) { /* The Copy action is available only if there is something selected */ - gtk_action_set_sensitive (copy_action, gtk_tree_selection_count_selected_rows (sel) > 0); + g_object_set (copy_action, + "enabled", gtk_tree_selection_count_selected_rows (sel) > 0, + NULL); } static void @@ -624,22 +677,43 @@ on_size_allocate (GtkWidget *widget, GdkRectangle *allocation, struct psppire_output_view *view) { - int new_render_width = MAX (300, allocation->width); - if (view->render_width != new_render_width) - { - view->render_width = new_render_width; - rerender (view); - } + view->render_width = MAX (300, allocation->width); + rerender (view); +} + +static void +on_realize (GtkWidget *overview, GObject *view) +{ + GtkTreeSelection *sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (overview)); + gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); + + GtkWidget *toplevel = gtk_widget_get_toplevel (GTK_WIDGET (overview)); + + GAction *copy_action = g_action_map_lookup_action (G_ACTION_MAP (toplevel), + "copy"); + + GAction *select_all_action = g_action_map_lookup_action (G_ACTION_MAP (toplevel), + "select-all"); + + g_object_set (copy_action, "enabled", FALSE, NULL); + + g_signal_connect_swapped (select_all_action, "activate", + G_CALLBACK (on_select_all), view); + + g_signal_connect_swapped (copy_action, "activate", + G_CALLBACK (on_copy), view); + + g_signal_connect (sel, "changed", G_CALLBACK (on_selection_change), + copy_action); } struct psppire_output_view * -psppire_output_view_new (GtkLayout *output, GtkTreeView *overview, - GtkAction *copy_action, GtkAction *select_all_action) +psppire_output_view_new (GtkLayout *output, GtkTreeView *overview) { struct psppire_output_view *view; GtkTreeViewColumn *column; GtkCellRenderer *renderer; - GtkTreeSelection *sel; + GtkTreeModel *model; view = xmalloc (sizeof *view); @@ -651,8 +725,7 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview, view->y = 0; string_map_init (&view->render_opts); view->overview = overview; - memset (&view->cur_command, 0, sizeof view->cur_command); - view->in_command = false; + view->cur_group = NULL; view->toplevel = gtk_widget_get_toplevel (GTK_WIDGET (output)); view->items = NULL; view->n_items = view->allocated_items = 0; @@ -662,12 +735,19 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview, view->print_n_pages = 0; view->paginated = FALSE; - g_signal_connect (view->toplevel, "style-set", G_CALLBACK (on_style_set), view); + g_signal_connect (output, "draw", G_CALLBACK (layout_draw_callback), NULL); + + g_signal_connect (output, "style-updated", G_CALLBACK (on_style_updated), view); g_signal_connect (output, "size-allocate", G_CALLBACK (on_size_allocate), view); + gtk_style_context_add_class (gtk_widget_get_style_context (GTK_WIDGET (output)), + GTK_STYLE_CLASS_VIEW); + if (overview) { + g_signal_connect (overview, "realize", G_CALLBACK (on_realize), view); + model = GTK_TREE_MODEL (gtk_tree_store_new ( N_COLS, G_TYPE_STRING, /* COL_NAME */ @@ -676,11 +756,6 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview, gtk_tree_view_set_model (overview, model); g_object_unref (model); - sel = gtk_tree_view_get_selection (overview); - gtk_tree_selection_set_mode (sel, GTK_SELECTION_MULTIPLE); - g_signal_connect (sel, "changed", G_CALLBACK (on_selection_change), - copy_action); - column = gtk_tree_view_column_new (); gtk_tree_view_append_column (GTK_TREE_VIEW (overview), column); renderer = gtk_cell_renderer_text_new (); @@ -689,12 +764,6 @@ psppire_output_view_new (GtkLayout *output, GtkTreeView *overview, g_signal_connect (GTK_TREE_VIEW (overview), "row-activated", G_CALLBACK (on_row_activate), view); - - gtk_action_set_sensitive (copy_action, FALSE); - g_signal_connect_swapped (copy_action, "activate", - G_CALLBACK (on_copy), view); - g_signal_connect_swapped (select_all_action, "activate", - G_CALLBACK (on_select_all), view); } return view; @@ -708,8 +777,8 @@ psppire_output_view_destroy (struct psppire_output_view *view) if (!view) return; - g_signal_handlers_disconnect_by_func (view->toplevel, - G_CALLBACK (on_style_set), view); + g_signal_handlers_disconnect_by_func (view->output, + G_CALLBACK (on_style_updated), view); string_map_destroy (&view->render_opts); @@ -724,6 +793,9 @@ psppire_output_view_destroy (struct psppire_output_view *view) xr_driver_destroy (view->xr); + if (view->cur_group) + gtk_tree_path_free (view->cur_group); + free (view); } @@ -745,7 +817,7 @@ psppire_output_view_clear (struct psppire_output_view *view) view->items = NULL; view->n_items = view->allocated_items = 0; } - + /* Export. */ void @@ -771,17 +843,17 @@ static cairo_t * get_cairo_context_from_print_context (GtkPrintContext *context) { cairo_t *cr = gtk_print_context_get_cairo_context (context); - + /* For all platforms except windows, gtk_print_context_get_dpi_[xy] returns 72. Windows returns 600. */ double xres = gtk_print_context_get_dpi_x (context); double yres = gtk_print_context_get_dpi_y (context); - + /* This means that the cairo context now has its dimensions in Points */ cairo_scale (cr, xres / 72.0, yres / 72.0); - + return cr; } @@ -833,7 +905,7 @@ paginate (GtkPrintOperation *operation, complete. Don't let that screw up printing. */ return TRUE; } - else if ( view->print_item < view->n_items ) + else if (view->print_item < view->n_items) { xr_driver_output_item (view->print_xrd, view->items[view->print_item++].item); @@ -900,7 +972,7 @@ psppire_output_view_print (struct psppire_output_view *view, GtkPrintOperation *print = gtk_print_operation_new (); - if (view->print_settings != NULL) + if (view->print_settings != NULL) gtk_print_operation_set_print_settings (print, view->print_settings); g_signal_connect (print, "begin_print", G_CALLBACK (begin_print), view);