X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Foutput%2Ftext-item.c;h=a0428acc82c44209e3c91d16e98ebb2a6a34a8c2;hb=3ad7936615cf7e9277e25a963364c3613a0cf6d9;hp=2837c93bb611714ecfee4d3a8bb8b217b8fafd02;hpb=7e0d00ad64b1957062f6f06c119e8808b9e6b727;p=pspp diff --git a/src/output/text-item.c b/src/output/text-item.c index 2837c93bb6..a0428acc82 100644 --- a/src/output/text-item.c +++ b/src/output/text-item.c @@ -18,53 +18,92 @@ #include "output/text-item.h" -#include #include #include #include "libpspp/cast.h" +#include "libpspp/pool.h" #include "output/driver.h" #include "output/output-item-provider.h" +#include "output/pivot-table.h" +#include "output/table.h" +#include "output/table-item.h" +#include "output/table-provider.h" #include "gl/xalloc.h" #include "gl/xvasprintf.h" #include "gettext.h" #define _(msgid) gettext (msgid) +#define N_(msgid) msgid -/* Creates and returns a new text item containing TEXT and the specified TYPE. - The new text item takes ownership of TEXT. */ +const char * +text_item_type_to_string (enum text_item_type type) +{ + switch (type) + { + case TEXT_ITEM_PAGE_TITLE: + return _("Page Title"); + + case TEXT_ITEM_TITLE: + return _("Title"); + + case TEXT_ITEM_SYNTAX: + case TEXT_ITEM_LOG: + return _("Log"); + + default: + return _("Text"); + } +} + +/* Creates and returns a new text item containing TEXT and the specified TYPE + and LABEL. The new text item takes ownership of TEXT and LABEL. If LABEL + is NULL, uses the default label for TYPE. */ struct text_item * -text_item_create_nocopy (enum text_item_type type, char *text) +text_item_create_nocopy (enum text_item_type type, char *text, char *label) { - struct text_item *item = xzalloc (sizeof *item); - output_item_init (&item->output_item, &text_item_class); - item->text = text; - item->type = type; - return item; + return text_item_create_value (type, pivot_value_new_user_text_nocopy (text), + label); } /* Creates and returns a new text item containing a copy of TEXT and the - specified TYPE. The caller retains ownership of TEXT. */ + specified TYPE and LABEL. The caller retains ownership of TEXT and LABEL. + If LABEL is null, uses a default label for TYPE. */ struct text_item * -text_item_create (enum text_item_type type, const char *text) +text_item_create (enum text_item_type type, const char *text, + const char *label) { - return text_item_create_nocopy (type, xstrdup (text)); + return text_item_create_nocopy (type, xstrdup (text), + xstrdup_if_nonnull (label)); } -/* Creates and returns a new text item containing a copy of FORMAT, which is - formatted as if by printf(), and the specified TYPE. The caller retains - ownership of FORMAT. */ +/* Creates and returns a new text item containing VALUE, TYPE, and LABEL. + Takes ownership of VALUE and LABEL. If LABEL is null, uses a default label + for TYPE. */ struct text_item * -text_item_create_format (enum text_item_type type, const char *format, ...) +text_item_create_value (enum text_item_type type, struct pivot_value *value, + char *label) { - struct text_item *item; - va_list args; - - va_start (args, format); - item = text_item_create_nocopy (type, xvasprintf (format, args)); - va_end (args); + if (type == TEXT_ITEM_SYNTAX || type == TEXT_ITEM_LOG) + { + if (!value->font_style) + { + value->font_style = xmalloc (sizeof *value->font_style); + *value->font_style = (struct font_style) FONT_STYLE_INITIALIZER; + } + + free (value->font_style->typeface); + value->font_style->typeface = xstrdup ("Monospaced"); + } + struct text_item *item = xzalloc (sizeof *item); + *item = (struct text_item) { + .output_item = OUTPUT_ITEM_INITIALIZER (&text_item_class), + .output_item.label = label, + .type = type, + .text = value, + }; return item; } @@ -75,11 +114,11 @@ text_item_get_type (const struct text_item *item) return item->type; } -/* Returns ITEM's text, which the caller may not modify or free. */ -const char * -text_item_get_text (const struct text_item *item) +/* Returns ITEM's text, which the caller must eventually free. */ +char * +text_item_get_plain_text (const struct text_item *item) { - return item->text; + return pivot_value_to_string_defaults (item->text); } /* Submits ITEM to the configured output drivers, and transfers ownership to @@ -89,17 +128,124 @@ text_item_submit (struct text_item *item) { output_submit (&item->output_item); } + +struct text_item * +text_item_unshare (struct text_item *old) +{ + assert (old->output_item.ref_cnt > 0); + if (!text_item_is_shared (old)) + return old; + text_item_unref (old); + + struct text_item *new = xmalloc (sizeof *new); + *new = (struct text_item) { + .output_item = OUTPUT_ITEM_CLONE_INITIALIZER (&old->output_item), + .text = pivot_value_clone (old->text), + .type = old->type, + }; + return new; +} + +static bool +nullable_font_style_equal (const struct font_style *a, + const struct font_style *b) +{ + return a && b ? font_style_equal (a, b) : !a && !b; +} + +/* Attempts to append the text in SRC to DST. If successful, returns true, + otherwise false. + + Only TEXT_ITEM_SYNTAX and TEXT_ITEM_LOG items can be combined, and not with + each other. + + DST must not be shared. */ +bool +text_item_append (struct text_item *dst, const struct text_item *src) +{ + assert (!text_item_is_shared (dst)); + if (dst->type != src->type + || (dst->type != TEXT_ITEM_SYNTAX && dst->type != TEXT_ITEM_LOG) + || strcmp (output_item_get_label (&dst->output_item), + output_item_get_label (&src->output_item)) + || !nullable_font_style_equal (dst->text->font_style, + src->text->font_style) + || (dst->text->font_style && dst->text->font_style->markup) + || src->text->type != PIVOT_VALUE_TEXT + || dst->text->type != PIVOT_VALUE_TEXT) + return false; + else + { + char *new_text = xasprintf ("%s\n%s", dst->text->text.local, + src->text->text.local); + + free (dst->text->text.local); + if (dst->text->text.c != dst->text->text.local) + free (dst->text->text.c); + if (dst->text->text.id != dst->text->text.local + && dst->text->text.id != dst->text->text.c) + free (dst->text->text.id); + + dst->text->text.local = new_text; + dst->text->text.c = new_text; + dst->text->text.id = new_text; + + return true; + } +} + +static const struct pivot_table_look * +text_item_table_look (void) +{ + static struct pivot_table_look *look; + if (!look) + { + look = pivot_table_look_new_builtin_default (); + + for (int a = 0; a < PIVOT_N_AREAS; a++) + memset (look->areas[a].cell_style.margin, 0, + sizeof look->areas[a].cell_style.margin); + for (int b = 0; b < PIVOT_N_BORDERS; b++) + look->borders[b].stroke = TABLE_STROKE_NONE; + } + return look; +} + +struct table_item * +text_item_to_table_item (struct text_item *text_item) +{ + struct pivot_table *table = pivot_table_create__ (NULL, "Text"); + pivot_table_set_look (table, text_item_table_look ()); + + struct pivot_dimension *d = pivot_dimension_create ( + table, PIVOT_AXIS_ROW, N_("Text")); + d->hide_all_labels = true; + pivot_category_create_leaf (d->root, pivot_value_new_text ("null")); + + pivot_table_put1 (table, 0, pivot_value_clone (text_item->text)); + + text_item_unref (text_item); + + return table_item_create (table); +} +static const char * +text_item_get_label (const struct output_item *output_item) +{ + const struct text_item *item = to_text_item (output_item); + return text_item_type_to_string (item->type); +} + static void text_item_destroy (struct output_item *output_item) { struct text_item *item = to_text_item (output_item); - free (item->text); - free (item->font); + pivot_value_destroy (item->text); free (item); } const struct output_item_class text_item_class = { + text_item_get_label, text_item_destroy, };