1 /* PSPPIRE - a graphical user interface for PSPP.
2 Copyright (C) 2007 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>
30 /* Create a GtkLabel and pack it into BOX.
31 The label is created using part of the string at S, and the directives
32 at DIRS[DIR_IDX] and subsequent.
34 After this function returns, *S points to the first unused character.
37 ship_label (GtkBox *box, const char **s,
38 const char_directives *dirs, size_t dir_idx)
41 GString *str = g_string_new (*s);
45 char_directive dir = dirs->dir[dir_idx];
48 while (dir_idx < dirs->count && dir.conversion == '%' )
50 g_string_erase (str, dir.dir_start - *s, 1);
51 dir = dirs->dir[++dir_idx];
55 g_string_truncate (str, dir.dir_start - *s - n);
57 if ( dir_idx >= dirs->count)
63 label = gtk_label_new (str->str);
65 g_string_free (str, TRUE);
67 gtk_box_pack_start (box, label, FALSE, FALSE, 0);
68 gtk_widget_show (label);
71 /* Returns a string generated from FMT and a list of GtkEntry widgets.
72 Each conversion in FMT will be replaced with the text from the
73 corresponding GtkEntry. The normal printf semantics will be ignored.
74 Note that the GtkEntry widgets may be GtkSpinbuttons or any other widget
75 derived from GtkEntry.
76 The returned string should be freed when no longer required.
79 widget_printf (const gchar *fmt, ...)
90 if ( 0 != printf_parse (fmt, &d, &a) )
93 widgets = calloc (sizeof (*widgets), d.count);
95 for (i = 0 ; i < d.count ; ++i )
97 if ( d.dir[i].conversion != '%')
98 widgets[i] = va_arg (ap, GtkWidget *);
104 output = g_string_sized_new (strlen (fmt));
106 for (i = 0 ; i < d.count ; ++i )
108 char_directive dir = d.dir[i];
110 const gchar *entry_text;
112 if ( dir.conversion == '%')
118 w = widgets [dir.arg_index];
119 entry_text = gtk_entry_get_text (GTK_ENTRY (w));
121 if ( dir.dir_start > s )
122 g_string_append_len (output, s, dir.dir_start - s);
126 g_string_append (output, entry_text);
133 g_string_append_len (output, s, -1);
136 g_string_free (output, FALSE);
141 Returns a GtkHBox populated with an GtkLabel and GtkEntry widgets.
142 Each conversion in FMT will cause a GtkEntry (possibly a GtkSpinButton) to
143 be created. Any text between conversions produces a GtkLabel.
144 There should be N arguments following FMT should be of type GtkEntry **,
145 where N is the number of conversions.
146 These arguments will be filled with a pointer to the corresponding widgets.
147 Their properties may be changed, but they should not be unrefed.
150 widget_scanf (const gchar *fmt, ...)
156 GtkWidget ***widgets = NULL;
157 GtkWidget *hbox = NULL;
161 if ( 0 != printf_parse (fmt, &d, &a) )
170 hbox = gtk_hbox_new (FALSE, 0);
171 widgets = calloc (sizeof (*widgets), d.count);
174 for (i = 0 ; i < d.count ; ++i )
176 if ( d.dir[i].conversion != '%')
177 widgets[i] = va_arg (ap, GtkWidget **);
183 for (i = 0 ; i < d.count ; ++i )
185 char_directive dir = d.dir[i];
190 if ( dir.precision_start && dir.precision_end)
191 precision = strtol (dir.precision_start + 1,
192 (char **) &dir.precision_end, 10);
194 if ( dir.width_start && dir.width_end )
195 width = strtol (dir.width_start, (char **) &dir.width_end, 10);
197 if ( dir.dir_start > s )
198 ship_label (GTK_BOX (hbox), &s, &d, i);
200 if ( dir.conversion == '%')
206 w = widgets [dir.arg_index];
207 switch (dir.conversion)
213 *w = gtk_spin_button_new_with_range (0, 100.0, 1.0);
214 g_object_set (*w, "digits", precision, NULL);
218 *w = gtk_entry_new ();
222 g_object_set (*w, "width-chars", width, NULL);
223 gtk_box_pack_start (GTK_BOX (hbox), *w, FALSE, FALSE, 0);
224 gtk_widget_show (*w);
228 ship_label (GTK_BOX (hbox), &s, NULL, 0);