X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fui%2Fgui%2Fpsppire-scanf.c;h=88128a3090a717f959502fcb1623ced90d39f974;hb=e7913c62251710319b06c50702c5db9afb612be5;hp=2573c2e31093d62b814bdbafff417d16faf5820b;hpb=efcd93af16dfc6c6c9f60b71d94cc091d2417e17;p=pspp diff --git a/src/ui/gui/psppire-scanf.c b/src/ui/gui/psppire-scanf.c index 2573c2e310..88128a3090 100644 --- a/src/ui/gui/psppire-scanf.c +++ b/src/ui/gui/psppire-scanf.c @@ -12,7 +12,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program. If not, see . */ + along with this program. If not, see . +*/ #include #include @@ -25,19 +26,19 @@ #include "xalloc.h" - - static void psppire_scanf_class_init (PsppireScanfClass *class); static void psppire_scanf_init (PsppireScanf *w); -G_DEFINE_TYPE (PsppireScanf, psppire_scanf, GTK_TYPE_HBOX) +G_DEFINE_TYPE (PsppireScanf, psppire_scanf, GTK_TYPE_BOX) /* Properties */ enum { PROP_0, PROP_FORMAT, - PROP_NCONV + PROP_NCONV, + PROP_USE_UNDERLINE, + PROP_MNEMONIC_WIDGET }; /* Create a GtkLabel and pack it into BOX. @@ -47,18 +48,18 @@ enum After this function returns, *S points to the first unused character. */ static void -ship_label (GtkBox *box, const char **s, +ship_label (PsppireScanf *box, const char **s, const char_directives *dirs, size_t dir_idx) { GtkWidget *label ; GString *str = g_string_new (*s); - if ( dirs) + if (dirs) { char_directive dir = dirs->dir[dir_idx]; int n = 0; - while (dir_idx < dirs->count && dir.conversion == '%' ) + while (dir_idx < dirs->count && dir.conversion == '%') { g_string_erase (str, dir.dir_start - *s, 1); dir = dirs->dir[++dir_idx]; @@ -67,7 +68,7 @@ ship_label (GtkBox *box, const char **s, g_string_truncate (str, dir.dir_start - *s - n); - if ( dir_idx >= dirs->count) + if (dir_idx >= dirs->count) *s = NULL; else *s = dir.dir_end; @@ -77,7 +78,7 @@ ship_label (GtkBox *box, const char **s, g_string_free (str, TRUE); - gtk_box_pack_start (box, label, FALSE, FALSE, 0); + gtk_box_pack_start (GTK_BOX (box), label, FALSE, FALSE, 0); gtk_widget_show (label); } @@ -91,31 +92,31 @@ guts (PsppireScanf *scanf) /* Get the number of args into D */ g_return_if_fail (0 == printf_parse (scanf->format, &scanf->d, &a)); - if ( scanf->d.count > 0) - scanf->widgets = xcalloc (sizeof (*scanf->widgets), scanf->d.count); + if (scanf->d.count > 0) + scanf->widgets = xcalloc (scanf->d.count, sizeof (*scanf->widgets)); /* A is not used, so get rid of it */ if (a.arg != a.direct_alloc_arg) free (a.arg); - for (i = 0 ; i < scanf->d.count ; ++i ) + for (i = 0 ; i < scanf->d.count ; ++i) { GtkWidget **w; char_directive dir = scanf->d.dir[i]; int precision = 0; int width = 0; - if ( dir.precision_start && dir.precision_end) - precision = strtol (dir.precision_start + 1, + if (dir.precision_start && dir.precision_end) + precision = g_ascii_strtoll (dir.precision_start + 1, (char **) &dir.precision_end, 10); - if ( dir.width_start && dir.width_end ) - width = strtol (dir.width_start, (char **) &dir.width_end, 10); + if (dir.width_start && dir.width_end) + width = g_ascii_strtoll (dir.width_start, (char **) &dir.width_end, 10); - if ( dir.dir_start > s ) - ship_label (GTK_BOX (scanf), &s, &scanf->d, i); + if (dir.dir_start > s) + ship_label (scanf, &s, &scanf->d, i); - if ( dir.conversion == '%') + if (dir.conversion == '%') { if (s) s++; continue; @@ -141,12 +142,39 @@ guts (PsppireScanf *scanf) gtk_widget_show (*w); } - if ( s && *s ) - ship_label (GTK_BOX (scanf), &s, NULL, 0); + if (s && *s) + ship_label (scanf, &s, NULL, 0); } +static void +set_mnemonic (PsppireScanf *scanf) +{ + if (scanf->use_underline || scanf->mnemonic_widget) + { + GList *l = gtk_container_get_children (GTK_CONTAINER (scanf)); + while (l) + { + if (GTK_IS_LABEL (l->data)) + { + const gchar *t = gtk_label_get_label (l->data); + if (g_strstr_len (t, -1, "_")) + { + g_object_set (l->data, + "use-underline", TRUE, + "mnemonic-widget", scanf->mnemonic_widget, + NULL); + + break; + } + } + l = l->next; + } + g_list_free (l); + } +} + static void psppire_scanf_set_property (GObject *object, guint prop_id, @@ -161,6 +189,14 @@ psppire_scanf_set_property (GObject *object, scanf->format = g_value_get_string (value); guts (scanf); break; + case PROP_MNEMONIC_WIDGET: + scanf->mnemonic_widget = g_value_get_object (value); + set_mnemonic (scanf); + break; + case PROP_USE_UNDERLINE: + scanf->use_underline = g_value_get_boolean (value); + set_mnemonic (scanf); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -184,6 +220,12 @@ psppire_scanf_get_property (GObject *object, case PROP_NCONV: g_value_set_int (value, scanf->d.count); break; + case PROP_USE_UNDERLINE: + g_value_set_boolean (value, scanf->use_underline); + break; + case PROP_MNEMONIC_WIDGET: + g_value_set_object (value, scanf->mnemonic_widget); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -196,7 +238,7 @@ static GObjectClass *parent_class = NULL; static void psppire_scanf_dispose (GObject *obj) { - PsppireScanf *w = (PsppireScanf *)obj; + PsppireScanf *w = PSPPIRE_SCANF (obj); if (w->dispose_has_run) return; @@ -243,6 +285,22 @@ psppire_scanf_class_init (PsppireScanfClass *class) G_PARAM_READABLE); + GParamSpec *use_underline_spec = + g_param_spec_boolean ("use-underline", + "Use Underline", + "If set, an underline in the text indicates the next character should be used for the mnemonic accelerator key", + FALSE, + G_PARAM_READWRITE); + + + GParamSpec *mnemonic_widget_spec = + g_param_spec_object ("mnemonic-widget", + "Mnemonic widget", + "The widget which is to be activated when the Scanf's mnemonic key is pressed. Has no effect if use-underline is false.", + GTK_TYPE_WIDGET, + G_PARAM_READWRITE); + + parent_class = g_type_class_peek_parent (class); object_class->dispose = psppire_scanf_dispose; @@ -259,6 +317,13 @@ psppire_scanf_class_init (PsppireScanfClass *class) PROP_FORMAT, format_spec); + g_object_class_install_property (object_class, + PROP_USE_UNDERLINE, + use_underline_spec); + + g_object_class_install_property (object_class, + PROP_MNEMONIC_WIDGET, + mnemonic_widget_spec); } @@ -266,25 +331,28 @@ psppire_scanf_class_init (PsppireScanfClass *class) static void psppire_scanf_init (PsppireScanf *w) { + w->dispose_has_run = FALSE; + + gtk_orientable_set_orientation (GTK_ORIENTABLE (w), GTK_ORIENTATION_HORIZONTAL); } -gchar +static gchar psppire_get_conversion_char (PsppireScanf *w, gint n) { - g_return_val_if_fail ( n < w->d.count, '\0'); + g_return_val_if_fail (n < w->d.count, '\0'); return w->d.dir[n].conversion; } GtkWidget * psppire_scanf_get_child (PsppireScanf *w, gint n) { - g_return_val_if_fail ( n < w->d.count, NULL); + g_return_val_if_fail (n < w->d.count, NULL); return w->widgets[n]; } /* - This widget is a GtkHBox populated with GtkLabel and GtkEntry widgets. + This widget is a horizontal GtkBox populated with GtkLabel and GtkEntry widgets. Each conversion in FMT will cause a GtkEntry (possibly a GtkSpinButton) to be created. Any text between conversions produces a GtkLabel. There should be N arguments following FMT should be of type GtkEntry **, @@ -305,11 +373,11 @@ psppire_scanf_new (const gchar *fmt, ...) va_start (ap, fmt); - for (i = 0 ; i < n ; ++i ) + for (i = 0 ; i < n ; ++i) { GtkWidget **field; - if ( psppire_get_conversion_char (PSPPIRE_SCANF (w), i) == '%') + if (psppire_get_conversion_char (PSPPIRE_SCANF (w), i) == '%') continue; field = va_arg (ap, GtkWidget **);