1 /* PSPP - a program for statistical analysis.
2 Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19 #include "output/text-item.h"
24 #include "libpspp/cast.h"
25 #include "libpspp/pool.h"
26 #include "output/driver.h"
27 #include "output/output-item-provider.h"
28 #include "output/pivot-table.h"
29 #include "output/table.h"
30 #include "output/table-item.h"
31 #include "output/table-provider.h"
33 #include "gl/xalloc.h"
34 #include "gl/xvasprintf.h"
37 #define _(msgid) gettext (msgid)
38 #define N_(msgid) msgid
41 text_item_type_to_string (enum text_item_type type)
45 case TEXT_ITEM_PAGE_TITLE:
46 return _("Page Title");
51 case TEXT_ITEM_SYNTAX:
60 /* Creates and returns a new text item containing TEXT and the specified TYPE
61 and LABEL. The new text item takes ownership of TEXT and LABEL. If LABEL
62 is NULL, uses the default label for TYPE. */
64 text_item_create_nocopy (enum text_item_type type, char *text, char *label)
66 return text_item_create_value (type, pivot_value_new_user_text_nocopy (text),
70 /* Creates and returns a new text item containing a copy of TEXT and the
71 specified TYPE and LABEL. The caller retains ownership of TEXT and LABEL.
72 If LABEL is null, uses a default label for TYPE. */
74 text_item_create (enum text_item_type type, const char *text,
77 return text_item_create_nocopy (type, xstrdup (text),
78 xstrdup_if_nonnull (label));
81 /* Creates and returns a new text item containing VALUE, TYPE, and LABEL.
82 Takes ownership of VALUE and LABEL. If LABEL is null, uses a default label
85 text_item_create_value (enum text_item_type type, struct pivot_value *value,
88 if (type == TEXT_ITEM_SYNTAX || type == TEXT_ITEM_LOG)
90 if (!value->font_style)
92 value->font_style = xmalloc (sizeof *value->font_style);
93 *value->font_style = (struct font_style) FONT_STYLE_INITIALIZER;
96 free (value->font_style->typeface);
97 value->font_style->typeface = xstrdup ("Monospaced");
100 struct text_item *item = xzalloc (sizeof *item);
101 *item = (struct text_item) {
102 .output_item = OUTPUT_ITEM_INITIALIZER (&text_item_class),
103 .output_item.label = label,
110 /* Returns ITEM's type. */
112 text_item_get_type (const struct text_item *item)
117 /* Returns ITEM's text, which the caller must eventually free. */
119 text_item_get_plain_text (const struct text_item *item)
121 return pivot_value_to_string_defaults (item->text);
124 /* Submits ITEM to the configured output drivers, and transfers ownership to
125 the output subsystem. */
127 text_item_submit (struct text_item *item)
129 output_submit (&item->output_item);
133 text_item_unshare (struct text_item *old)
135 assert (old->output_item.ref_cnt > 0);
136 if (!text_item_is_shared (old))
138 text_item_unref (old);
140 struct text_item *new = xmalloc (sizeof *new);
141 *new = (struct text_item) {
142 .output_item = OUTPUT_ITEM_CLONE_INITIALIZER (&old->output_item),
143 .text = pivot_value_clone (old->text),
150 nullable_font_style_equal (const struct font_style *a,
151 const struct font_style *b)
153 return a && b ? font_style_equal (a, b) : !a && !b;
156 /* Attempts to append the text in SRC to DST. If successful, returns true,
159 Only TEXT_ITEM_SYNTAX and TEXT_ITEM_LOG items can be combined, and not with
162 DST must not be shared. */
164 text_item_append (struct text_item *dst, const struct text_item *src)
166 assert (!text_item_is_shared (dst));
167 if (dst->type != src->type
168 || (dst->type != TEXT_ITEM_SYNTAX && dst->type != TEXT_ITEM_LOG)
169 || strcmp (output_item_get_label (&dst->output_item),
170 output_item_get_label (&src->output_item))
171 || !nullable_font_style_equal (dst->text->font_style,
172 src->text->font_style)
173 || (dst->text->font_style && dst->text->font_style->markup)
174 || src->text->type != PIVOT_VALUE_TEXT
175 || dst->text->type != PIVOT_VALUE_TEXT)
179 char *new_text = xasprintf ("%s\n%s", dst->text->text.local,
180 src->text->text.local);
182 free (dst->text->text.local);
183 if (dst->text->text.c != dst->text->text.local)
184 free (dst->text->text.c);
185 if (dst->text->text.id != dst->text->text.local
186 && dst->text->text.id != dst->text->text.c)
187 free (dst->text->text.id);
189 dst->text->text.local = new_text;
190 dst->text->text.c = new_text;
191 dst->text->text.id = new_text;
197 static const struct pivot_table_look *
198 text_item_table_look (void)
200 static struct pivot_table_look *look;
203 look = pivot_table_look_new_builtin_default ();
205 for (int a = 0; a < PIVOT_N_AREAS; a++)
206 memset (look->areas[a].cell_style.margin, 0,
207 sizeof look->areas[a].cell_style.margin);
208 for (int b = 0; b < PIVOT_N_BORDERS; b++)
209 look->borders[b].stroke = TABLE_STROKE_NONE;
215 text_item_to_table_item (struct text_item *text_item)
217 struct pivot_table *table = pivot_table_create__ (NULL, "Text");
218 pivot_table_set_look (table, text_item_table_look ());
220 struct pivot_dimension *d = pivot_dimension_create (
221 table, PIVOT_AXIS_ROW, N_("Text"));
222 d->hide_all_labels = true;
223 pivot_category_create_leaf (d->root, pivot_value_new_text ("null"));
225 pivot_table_put1 (table, 0, pivot_value_clone (text_item->text));
227 text_item_unref (text_item);
229 return table_item_create (table);
233 text_item_get_label (const struct output_item *output_item)
235 const struct text_item *item = to_text_item (output_item);
236 return text_item_type_to_string (item->type);
240 text_item_destroy (struct output_item *output_item)
242 struct text_item *item = to_text_item (output_item);
243 pivot_value_destroy (item->text);
247 const struct output_item_class text_item_class =