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.command_name = xstrdup_if_nonnull (output_get_command_name ()),
104 .output_item.label = label,
111 /* Returns ITEM's type. */
113 text_item_get_type (const struct text_item *item)
118 /* Returns ITEM's text, which the caller must eventually free. */
120 text_item_get_plain_text (const struct text_item *item)
122 return pivot_value_to_string_defaults (item->text);
125 /* Submits ITEM to the configured output drivers, and transfers ownership to
126 the output subsystem. */
128 text_item_submit (struct text_item *item)
130 output_submit (&item->output_item);
134 text_item_unshare (struct text_item *old)
136 assert (old->output_item.ref_cnt > 0);
137 if (!text_item_is_shared (old))
139 text_item_unref (old);
141 struct text_item *new = xmalloc (sizeof *new);
142 *new = (struct text_item) {
143 .output_item = OUTPUT_ITEM_CLONE_INITIALIZER (&old->output_item),
144 .text = pivot_value_clone (old->text),
151 nullable_font_style_equal (const struct font_style *a,
152 const struct font_style *b)
154 return a && b ? font_style_equal (a, b) : !a && !b;
157 /* Attempts to append the text in SRC to DST. If successful, returns true,
160 Only TEXT_ITEM_SYNTAX and TEXT_ITEM_LOG items can be combined, and not with
163 DST must not be shared. */
165 text_item_append (struct text_item *dst, const struct text_item *src)
167 assert (!text_item_is_shared (dst));
168 if (dst->type != src->type
169 || (dst->type != TEXT_ITEM_SYNTAX && dst->type != TEXT_ITEM_LOG)
170 || strcmp (output_item_get_label (&dst->output_item),
171 output_item_get_label (&src->output_item))
172 || !nullable_font_style_equal (dst->text->font_style,
173 src->text->font_style)
174 || (dst->text->font_style && dst->text->font_style->markup)
175 || src->text->type != PIVOT_VALUE_TEXT
176 || dst->text->type != PIVOT_VALUE_TEXT)
180 char *new_text = xasprintf ("%s\n%s", dst->text->text.local,
181 src->text->text.local);
183 free (dst->text->text.local);
184 if (dst->text->text.c != dst->text->text.local)
185 free (dst->text->text.c);
186 if (dst->text->text.id != dst->text->text.local
187 && dst->text->text.id != dst->text->text.c)
188 free (dst->text->text.id);
190 dst->text->text.local = new_text;
191 dst->text->text.c = new_text;
192 dst->text->text.id = new_text;
198 static const struct pivot_table_look *
199 text_item_table_look (void)
201 static struct pivot_table_look *look;
204 look = pivot_table_look_new_builtin_default ();
206 for (int a = 0; a < PIVOT_N_AREAS; a++)
207 memset (look->areas[a].cell_style.margin, 0,
208 sizeof look->areas[a].cell_style.margin);
209 for (int b = 0; b < PIVOT_N_BORDERS; b++)
210 look->borders[b].stroke = TABLE_STROKE_NONE;
216 text_item_to_table_item (struct text_item *text_item)
218 struct pivot_table *table = pivot_table_create__ (NULL, "Text");
219 pivot_table_set_look (table, text_item_table_look ());
221 struct pivot_dimension *d = pivot_dimension_create (
222 table, PIVOT_AXIS_ROW, N_("Text"));
223 d->hide_all_labels = true;
224 pivot_category_create_leaf (d->root, pivot_value_new_text ("null"));
226 pivot_table_put1 (table, 0, pivot_value_clone (text_item->text));
228 text_item_unref (text_item);
230 return table_item_create (table);
234 text_item_get_label (const struct output_item *output_item)
236 const struct text_item *item = to_text_item (output_item);
237 return text_item_type_to_string (item->type);
241 text_item_destroy (struct output_item *output_item)
243 struct text_item *item = to_text_item (output_item);
244 pivot_value_destroy (item->text);
248 const struct output_item_class text_item_class =