1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2007, 2009 Free Software Foundation
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 "widget-io.h"
23 #include <gl/printf-parse.h>
27 #include <gl/gettext.h>
31 /* Create a GtkLabel and pack it into BOX.
32 The label is created using part of the string at S, and the directives
33 at DIRS[DIR_IDX] and subsequent.
35 After this function returns, *S points to the first unused character.
38 ship_label (GtkBox *box, const char **s,
39 const char_directives *dirs, size_t dir_idx)
42 GString *str = g_string_new (*s);
46 char_directive dir = dirs->dir[dir_idx];
49 while (dir_idx < dirs->count && dir.conversion == '%' )
51 g_string_erase (str, dir.dir_start - *s, 1);
52 dir = dirs->dir[++dir_idx];
56 g_string_truncate (str, dir.dir_start - *s - n);
58 if ( dir_idx >= dirs->count)
64 label = gtk_label_new (str->str);
66 g_string_free (str, TRUE);
68 gtk_box_pack_start (box, label, FALSE, FALSE, 0);
69 gtk_widget_show (label);
72 /* Returns a string generated from FMT and a list of GtkEntry widgets.
73 Each conversion in FMT will be replaced with the text from the
74 corresponding GtkEntry. The normal printf semantics will be ignored.
75 Note that the GtkEntry widgets may be GtkSpinbuttons or any other widget
76 derived from GtkEntry.
77 The returned string should be freed when no longer required.
80 widget_printf (const gchar *fmt, ...)
91 if ( 0 != printf_parse (fmt, &d, &a) )
94 widgets = xcalloc (sizeof (*widgets), d.count);
96 for (i = 0 ; i < d.count ; ++i )
98 if ( d.dir[i].conversion != '%')
99 widgets[i] = va_arg (ap, GtkWidget *);
105 output = g_string_sized_new (strlen (fmt));
107 for (i = 0 ; i < d.count ; ++i )
109 char_directive dir = d.dir[i];
111 const gchar *entry_text;
113 if ( dir.conversion == '%')
119 w = widgets [dir.arg_index];
120 entry_text = gtk_entry_get_text (GTK_ENTRY (w));
122 if ( dir.dir_start > s )
123 g_string_append_len (output, s, dir.dir_start - s);
127 g_string_append (output, entry_text);
134 g_string_append_len (output, s, -1);
137 g_string_free (output, FALSE);
142 Returns a GtkHBox populated with an GtkLabel and GtkEntry widgets.
143 Each conversion in FMT will cause a GtkEntry (possibly a GtkSpinButton) to
144 be created. Any text between conversions produces a GtkLabel.
145 There should be N arguments following FMT should be of type GtkEntry **,
146 where N is the number of conversions.
147 These arguments will be filled with a pointer to the corresponding widgets.
148 Their properties may be changed, but they should not be unrefed.
151 widget_scanf (const gchar *fmt, ...)
157 GtkWidget ***widgets = NULL;
158 GtkWidget *hbox = NULL;
162 if ( 0 != printf_parse (fmt, &d, &a) )
171 hbox = gtk_hbox_new (FALSE, 0);
172 widgets = calloc (sizeof (*widgets), d.count);
175 for (i = 0 ; i < d.count ; ++i )
177 if ( d.dir[i].conversion != '%')
178 widgets[i] = va_arg (ap, GtkWidget **);
184 for (i = 0 ; i < d.count ; ++i )
186 char_directive dir = d.dir[i];
191 if ( dir.precision_start && dir.precision_end)
192 precision = strtol (dir.precision_start + 1,
193 (char **) &dir.precision_end, 10);
195 if ( dir.width_start && dir.width_end )
196 width = strtol (dir.width_start, (char **) &dir.width_end, 10);
198 if ( dir.dir_start > s )
199 ship_label (GTK_BOX (hbox), &s, &d, i);
201 if ( dir.conversion == '%')
207 w = widgets [dir.arg_index];
208 switch (dir.conversion)
214 *w = gtk_spin_button_new_with_range (0, 100.0, 1.0);
215 g_object_set (*w, "digits", precision, NULL);
219 *w = gtk_entry_new ();
223 g_object_set (*w, "width-chars", width, NULL);
224 gtk_box_pack_start (GTK_BOX (hbox), *w, FALSE, FALSE, 0);
225 gtk_widget_show (*w);
229 ship_label (GTK_BOX (hbox), &s, NULL, 0);