X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Fpivot-table.h;h=2904fd4f357c1211da1d3b95d5aeb193e3776f6e;hb=1edfb965b2d68da0b46f34ec78222d129dc12782;hp=377579a013d356b3f5feb4cea5959381be201ae8;hpb=96994a54e60e9c95b8bba54c2281acf7059b1203;p=pspp diff --git a/src/output/pivot-table.h b/src/output/pivot-table.h index 377579a013..2904fd4f35 100644 --- a/src/output/pivot-table.h +++ b/src/output/pivot-table.h @@ -25,6 +25,8 @@ #include "libpspp/hmap.h" #include "output/table.h" +struct ccase; +struct dictionary; struct pivot_value; struct variable; union value; @@ -60,15 +62,11 @@ union value; Creating a pivot table usually consists of the following steps: 1. Create the table with pivot_table_create(), passing in the title. - It's commonly useful to set up a few options at this point: - - If empty rows or columns should not be displayed, set ->omit_empty to - true. + 2. Optionally, set the format to use for "count" values with + pivot_table_set_weight_var() or pivot_table_set_weight_format(). - - Set the format to use for "count" values with - pivot_table_set_weight_var() or pivot_table_set_weight_format(). - - 2. Create each dimension with pivot_dimension_create() and populate it with + 3. Create each dimension with pivot_dimension_create() and populate it with categories and, possibly, with groups that contain the categories. This call also assigns the dimension to an axis. @@ -81,14 +79,14 @@ union value; first cell for that variable. In that case, creating categories and inserting data can be interleaved. - 3. Insert data. For each cell, supply the category indexes, which are + 4. Insert data. For each cell, supply the category indexes, which are assigned starting from 0 in the order in which the categories were created in step 2, and the value to go in the cell. If the table has a small, fixed number of dimensions, functions like, e.g. pivot_table_put3() for 3 dimensions, can be used. The general function pivot_table_put() works for other cases. - 4. Output the table for user consumption. Use pivot_table_submit(). */ + 5. Output the table for user consumption. Use pivot_table_submit(). */ /* Pivot table display styling. */ @@ -107,7 +105,6 @@ enum pivot_area }; const char *pivot_area_to_string (enum pivot_area); -const struct area_style *pivot_area_get_default_style (enum pivot_area); /* Table borders for styling purposes. */ enum pivot_border @@ -146,17 +143,12 @@ enum pivot_border }; const char *pivot_border_to_string (enum pivot_border); -void pivot_border_get_default_style (enum pivot_border, - struct table_border_style *); /* Sizing for rows or columns of a rendered table. The comments below talk about columns and their widths but they apply equally to rows and their heights. */ struct pivot_table_sizing { - /* Minimum and maximum column width, in 1/96" units. */ - int range[2]; - /* Specific column widths, in 1/96" units. */ int *widths; size_t n_widths; @@ -187,9 +179,8 @@ enum pivot_axis_type { PIVOT_AXIS_LAYER, PIVOT_AXIS_ROW, - PIVOT_AXIS_COLUMN, - - PIVOT_N_AXES + PIVOT_AXIS_COLUMN +#define PIVOT_N_AXES 3 }; const char *pivot_axis_type_to_string (enum pivot_axis_type); @@ -288,7 +279,30 @@ struct pivot_dimension *pivot_dimension_create__ (struct pivot_table *, void pivot_dimension_destroy (struct pivot_dimension *); -void pivot_dimension_dump (const struct pivot_dimension *, int indentation); +void pivot_dimension_dump (const struct pivot_dimension *, + const struct pivot_table *, int indentation); + +struct pivot_splits *pivot_splits_create (struct pivot_table *, + enum pivot_axis_type, + const struct dictionary *); +void pivot_splits_destroy (struct pivot_splits *); + +void pivot_splits_new_split (struct pivot_splits *, const struct ccase *); +size_t pivot_splits_get_dindexes (const struct pivot_splits *, + size_t *dindexes); + +void pivot_splits_put1 (struct pivot_splits *, struct pivot_table *, + size_t idx1, struct pivot_value *); +void pivot_splits_put2 (struct pivot_splits *, struct pivot_table *, + size_t idx1, size_t idx2, struct pivot_value *); +void pivot_splits_put3 (struct pivot_splits *, struct pivot_table *, + size_t idx1, size_t idx2, size_t idx3, + struct pivot_value *); +void pivot_splits_put4 (struct pivot_splits *, struct pivot_table *, + size_t idx1, size_t idx2, size_t idx3, size_t idx4, + struct pivot_value *); + +size_t pivot_splits_count (const struct pivot_splits *); /* A pivot_category is a leaf (a category) or a group: @@ -316,10 +330,11 @@ struct pivot_category bool show_label_in_corner; /* Leaf only. */ - struct fmt_spec format; size_t group_index; /* In ->parent->subs[]. */ size_t data_index; /* In ->dimension->data_leaves[]. */ size_t presentation_index; /* In ->dimension->presentation_leaves[]. */ + struct fmt_spec format; /* Default format for values in this category. */ + bool honor_small; /* Honor pivot_table 'small' setting? */ }; static inline bool @@ -371,6 +386,56 @@ void pivot_category_destroy (struct pivot_category *); #define PIVOT_RC_COUNT ("RC_COUNT") bool pivot_result_class_change (const char *, const struct fmt_spec *); +bool is_pivot_result_class (const char *); + +/* Styling for a pivot table. + + The division between this and the style information in struct pivot_table + seems fairly arbitrary. The ultimate reason for the division is simply + because that's how SPSS documentation and file formats do it. */ +struct pivot_table_look + { + /* Reference count. A pivot_table_look may be shared between multiple + owners, indicated by a reference count greater than 1. When this is the + case, the pivot_table must not be modified. */ + int ref_cnt; + + char *name; /* May be null. */ + + /* General properties. */ + bool omit_empty; + bool row_labels_in_corner; + int width_ranges[TABLE_N_AXES][2]; /* In 1/96" units. */ + + /* Footnote display settings. */ + bool show_numeric_markers; + bool footnote_marker_superscripts; + + /* Styles. */ + struct table_area_style areas[PIVOT_N_AREAS]; + struct table_border_style borders[PIVOT_N_BORDERS]; + + /* Print settings. */ + bool print_all_layers; + bool paginate_layers; + bool shrink_to_fit[TABLE_N_AXES]; + bool top_continuation, bottom_continuation; + char *continuation; + size_t n_orphan_lines; + }; + +const struct pivot_table_look *pivot_table_look_get_default (void); +void pivot_table_look_set_default (const struct pivot_table_look *); + +char *pivot_table_look_read (const char *, struct pivot_table_look **) + WARN_UNUSED_RESULT; + +const struct pivot_table_look *pivot_table_look_builtin_default (void); +struct pivot_table_look *pivot_table_look_new_builtin_default (void); +struct pivot_table_look *pivot_table_look_ref ( + const struct pivot_table_look *); +void pivot_table_look_unref (struct pivot_table_look *); +struct pivot_table_look *pivot_table_look_unshare (struct pivot_table_look *); /* A pivot table. See the top of this file for more information. */ struct pivot_table @@ -380,40 +445,27 @@ struct pivot_table the pivot_table must not be modified. */ int ref_cnt; + /* Styling. */ + struct pivot_table_look *look; + /* Display settings. */ bool rotate_inner_column_labels; bool rotate_outer_row_labels; - bool row_labels_in_corner; bool show_grid_lines; + bool show_title; bool show_caption; - bool omit_empty; /* Omit empty rows and columns? */ - size_t *current_layer; /* axis[PIVOT_AXIS_LAYER].n_dimensions elements. */ - char *table_look; + size_t *current_layer; /* axes[PIVOT_AXIS_LAYER].n_dimensions elements. */ enum settings_value_show show_values; enum settings_value_show show_variables; struct fmt_spec weight_format; - /* Footnote display settings. */ - bool show_numeric_markers; - bool footnote_marker_superscripts; - /* Column and row sizing and page breaks. sizing[TABLE_HORZ] is for columns, sizing[TABLE_VERT] is for rows. */ struct pivot_table_sizing sizing[TABLE_N_AXES]; - /* Print settings. */ - bool print_all_layers; - bool paginate_layers; - bool shrink_to_fit[TABLE_N_AXES]; - bool top_continuation, bottom_continuation; - char *continuation; - size_t n_orphan_lines; - /* Format settings. */ - int epoch; - char decimal; /* Usually ',' or '.'. */ + struct fmt_settings settings; char grouping; /* Usually '.' or ','. */ - char *ccs[5]; /* Custom currency. */ double small; /* Command information. */ @@ -436,11 +488,7 @@ struct pivot_table struct pivot_value *subtype; /* Same as spv_item's subtype. */ struct pivot_value *corner_text; struct pivot_value *caption; - char *notes; - - /* Styles. */ - struct area_style areas[PIVOT_N_AREAS]; - struct table_border_style borders[PIVOT_N_BORDERS]; + char *notes; /* Shown as tooltip. */ /* Dimensions. */ struct pivot_dimension **dimensions; @@ -460,9 +508,30 @@ struct pivot_table *pivot_table_create_for_text (struct pivot_value *title, struct pivot_value *content); struct pivot_table *pivot_table_ref (const struct pivot_table *); +struct pivot_table *pivot_table_unshare (struct pivot_table *); void pivot_table_unref (struct pivot_table *); bool pivot_table_is_shared (const struct pivot_table *); +/* Titles. */ +void pivot_table_set_title (struct pivot_table *, struct pivot_value *); +void pivot_table_set_subtype (struct pivot_table *, struct pivot_value *); +void pivot_table_set_corner_text (struct pivot_table *, struct pivot_value *); +void pivot_table_set_caption (struct pivot_table *, struct pivot_value *); + +/* Axes. */ +void pivot_table_swap_axes (struct pivot_table *, + enum pivot_axis_type, enum pivot_axis_type); +void pivot_table_transpose (struct pivot_table *); +void pivot_table_move_dimension (struct pivot_table *, + struct pivot_dimension *, + enum pivot_axis_type, size_t ofs); + +/* Styling. */ +const struct pivot_table_look *pivot_table_get_look ( + const struct pivot_table *); +void pivot_table_set_look (struct pivot_table *, + const struct pivot_table_look *); + /* Format of PIVOT_RC_COUNT cells. */ void pivot_table_set_weight_var (struct pivot_table *, const struct variable *); @@ -493,6 +562,8 @@ const struct pivot_value *pivot_table_get (const struct pivot_table *, struct pivot_value *pivot_table_get_rw (struct pivot_table *, const size_t *dindexes); +bool pivot_table_delete (struct pivot_table *, const size_t *dindexes); + /* Footnotes. Use pivot_table_create_footnote() to create a footnote. @@ -511,6 +582,12 @@ struct pivot_footnote *pivot_table_create_footnote__ ( struct pivot_table *, size_t idx, struct pivot_value *marker, struct pivot_value *content); +void pivot_footnote_format_marker (const struct pivot_footnote *, + const struct pivot_table *, + struct string *); +char *pivot_footnote_marker_string (const struct pivot_footnote *, + const struct pivot_table *); + void pivot_footnote_destroy (struct pivot_footnote *); /* Internals. */ @@ -531,7 +608,7 @@ void pivot_table_dump (const struct pivot_table *, int indentation); /* pivot_value. */ -enum pivot_value_type +enum ATTRIBUTE ((packed)) pivot_value_type { PIVOT_VALUE_NUMERIC, /* A value of a numeric variable. */ PIVOT_VALUE_STRING, /* A value of a string variable. */ @@ -599,73 +676,85 @@ enum pivot_value_type */ struct pivot_value { - struct font_style *font_style; - struct cell_style *cell_style; - - char **subscripts; - size_t n_subscripts; - - char *superscript; - - const struct pivot_footnote **footnotes; - size_t n_footnotes; - - enum pivot_value_type type; + struct pivot_value_ex *ex; union { + enum pivot_value_type type; + /* PIVOT_VALUE_NUMERIC. */ struct { - double x; /* The numeric value. */ + enum pivot_value_type type; + enum settings_value_show show; /* Show value or label or both? */ struct fmt_spec format; /* Format to display 'x'. */ + bool honor_small; /* Honor value of pivot table 'small'? */ + double x; /* The numeric value. */ char *var_name; /* May be NULL. */ char *value_label; /* May be NULL. */ - enum settings_value_show show; /* Show value or label or both? */ } numeric; /* PIVOT_VALUE_STRING. */ struct { - char *s; /* The string value. */ + enum pivot_value_type type; + enum settings_value_show show; /* Show value or label or both? */ bool hex; /* Display in hex? */ + char *s; /* The string value. */ char *var_name; /* May be NULL. */ char *value_label; /* May be NULL. */ - enum settings_value_show show; /* Show value or label or both? */ } string; /* PIVOT_VALUE_VARIABLE. */ struct { + enum pivot_value_type type; + enum settings_value_show show; /* Show name or label or both? */ char *var_name; char *var_label; /* May be NULL. */ - enum settings_value_show show; /* Show name or label or both? */ } variable; /* PIVOT_VALUE_TEXT. */ struct { + enum pivot_value_type type; + + /* 'local', 'c', and 'id' must all be nonnull, but they are allowed + to be the same pointer. */ + bool user_provided; char *local; /* Localized. */ char *c; /* English. */ char *id; /* Identifier. */ - bool user_provided; } text; /* PIVOT_VALUE_TEMPLATE. */ struct { + enum pivot_value_type type; + + /* Arguments. + + The odd ordering in this struct reduces the overall size + of struct pivot_value. */ + unsigned int n_args; + struct pivot_argument *args; + + /* Both 'local' and 'id' must be nonnull, but they are allowed to + be the same pointer. */ char *local; /* Localized. */ char *id; /* Identifier. */ - struct pivot_argument *args; - size_t n_args; } template; }; }; +/* Life cycle. */ +struct pivot_value *pivot_value_clone (const struct pivot_value *); +void pivot_value_destroy (struct pivot_value *); + /* Numbers resulting from calculations. */ struct pivot_value *pivot_value_new_number (double); struct pivot_value *pivot_value_new_integer (double); @@ -679,17 +768,24 @@ struct pivot_value *pivot_value_new_value (const union value *, int width, /* Values from variable names. */ struct pivot_value *pivot_value_new_variable (const struct variable *); +struct pivot_value *pivot_value_new_variable__ (const char *name, + const char *label); /* Values from text strings. */ struct pivot_value *pivot_value_new_text (const char *); struct pivot_value *pivot_value_new_text_format (const char *, ...) - PRINTF_FORMAT (1, 2); +#if defined(__GNUC__) && ((__GNUC__ == 4 && __GNUC_MINOR__>= 4) || __GNUC__ > 4) + __attribute__((format(gnu_printf, 1, 2))); +#else + __attribute__((format(__printf__, 1, 2))); +#endif struct pivot_value *pivot_value_new_user_text (const char *, size_t length); struct pivot_value *pivot_value_new_user_text_nocopy (char *); /* Footnotes. */ void pivot_value_add_footnote (struct pivot_value *, const struct pivot_footnote *); +void pivot_value_sort_footnotes (struct pivot_value *); /* Numeric formats. */ void pivot_value_set_rc (const struct pivot_table *, struct pivot_value *, @@ -697,25 +793,25 @@ void pivot_value_set_rc (const struct pivot_table *, struct pivot_value *, /* Converting a pivot_value to a string for display. */ char *pivot_value_to_string (const struct pivot_value *, - enum settings_value_show show_values, - enum settings_value_show show_variables); -void pivot_value_format (const struct pivot_value *, - enum settings_value_show show_values, - enum settings_value_show show_variables, - struct string *); + const struct pivot_table *); +char *pivot_value_to_string_defaults (const struct pivot_value *); +bool pivot_value_format (const struct pivot_value *, + const struct pivot_table *, struct string *); bool pivot_value_format_body (const struct pivot_value *, - enum settings_value_show show_values, - enum settings_value_show show_variables, + const struct pivot_table *, struct string *); -void pivot_value_destroy (struct pivot_value *); - /* Styling. */ void pivot_value_get_style (struct pivot_value *, const struct font_style *base_font_style, const struct cell_style *base_cell_style, - struct area_style *); -void pivot_value_set_style (struct pivot_value *, const struct area_style *); + struct table_area_style *); +void pivot_value_set_style (struct pivot_value *, + const struct table_area_style *); +void pivot_value_set_font_style (struct pivot_value *, + const struct font_style *); +void pivot_value_set_cell_style (struct pivot_value *, + const struct cell_style *); /* Template arguments. */ struct pivot_argument @@ -725,6 +821,35 @@ struct pivot_argument }; void pivot_argument_uninit (struct pivot_argument *); +void pivot_argument_copy (struct pivot_argument *, + const struct pivot_argument *); + +/* Extra styling for a pivot_value. + + This is logically part of pivot_value itself. It is broken into a separate + structure to save memory because it is rarely used. */ +struct pivot_value_ex + { + struct font_style *font_style; + struct cell_style *cell_style; + + char **subscripts; + size_t n_subscripts; + + size_t *footnote_indexes; + size_t n_footnotes; + }; + +static inline const struct pivot_value_ex * +pivot_value_ex (const struct pivot_value *value) +{ + static const struct pivot_value_ex empty_ex = { .font_style = NULL }; + return value->ex ? value->ex : &empty_ex; +} + +struct pivot_value_ex *pivot_value_ex_rw (struct pivot_value *); +struct pivot_value_ex *pivot_value_ex_clone (const struct pivot_value_ex *); +void pivot_value_ex_destroy (struct pivot_value_ex *); /* One piece of data within a pivot table. */ struct pivot_cell