[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#395052: Please provide the GTK frontend with a better handler for BOOLEAN questions



Frans Pop wrote:
On Tuesday 24 October 2006 17:47, Attilio Fiandrotti wrote:

Many users complained about poor "checkbox" handler provided in the GTK
frontend to handle BOOLEAN questions.
A "yes/no" widget based handler would do better for this purpose, ATM
i'm thinking about implementing this with a combobox [1] widget.


I don't agree that this would be a better solution as it would not be obvious to users which options are available and having to always open the combobox to select a different choice is very user unfriendly.

The optimal solution would be to have yes and no buttons, just like in the newt frontend.

An IMHO somewhat acceptable alternative solution is possibly to use radio buttons:
http://developer.gnome.org/doc/API/2.0/gtk/GtkRadioButton.html

Attached to this mail you'll find a patch to current GTK frontend in SVN that implements BOOLEAN questions with gtkradiobuttons and; it's included a screenshot too. I belive this handler is better than the one based on gtkcombobox and as good as the current one based on gtkcheckbox. It also fixes the bug i discovered yesterday, which currently causes a BOOLEAN question to be updated in the database, even if the user pressed BACK, as soon as he checks/unchecks the checkbox.

cheers

Attilio
Index: gtk.c
===================================================================
--- gtk.c	(revisione 42209)
+++ gtk.c	(copia locale)
@@ -124,9 +124,9 @@
     return TRUE;
 }
 
-static void bool_setter(void *check, struct question *q)
+static void bool_setter(void *button, struct question *q)
 {
-    question_setvalue(q, (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(check)) ? "true" : "false"));
+    question_setvalue(q, (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)) ? "true" : "false"));
 }
 
 static void entry_setter(void *entry, struct question *q)
@@ -374,16 +374,6 @@
     gtk_main_quit();
 }
 
-void check_toggled_callback (GtkWidget *toggle, gpointer data)
-{
-    struct question *q = (struct question*)data;
-    gboolean value;
-
-    /* INFO(INFO_DEBUG, "GTK_DI - check_toggled_callback() called"); */
-    value = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(toggle));
-    bool_setter (toggle, q);
-}
-
 void boolean_single_callback(GtkWidget *button, struct frontend_question_data* data )
 {
     struct frontend *obj = data->obj;
@@ -613,7 +603,7 @@
     }
 
     /* here is created the question's description, unless question is BOOLEAN */
-    if( strcmp(q->template->type, "boolean") != 0 ) {
+//    if( strcmp(q->template->type, "boolean") != 0 ) {
         description_view = gtk_text_view_new ();
         description_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (description_view));
         gtk_text_buffer_set_text (description_buffer, q_get_description(q), -1);
@@ -628,7 +618,7 @@
         gtk_text_buffer_get_end_iter  (description_buffer, &end);
         gtk_text_buffer_apply_tag_by_name (description_buffer, "italic", &start, &end);
         gtk_widget_modify_base(GTK_WIDGET(description_view), GTK_STATE_NORMAL, bg_color);
-    }
+//    }
 
     gtk_container_set_focus_chain(GTK_CONTAINER(description_box), NULL);
 
@@ -642,7 +632,7 @@
     {
         if (strlen (q_get_extended_description(q)) > 0)
             gtk_box_pack_start(GTK_BOX (description_box), ext_description_view, FALSE, FALSE, 2);
-        if( strcmp(q->template->type, "boolean") != 0 )
+//        if( strcmp(q->template->type, "boolean") != 0 )
             gtk_box_pack_start(GTK_BOX (description_box), description_view, FALSE, FALSE, 3);
     }
 
@@ -665,7 +655,7 @@
 
 static int gtkhandler_boolean(struct frontend *obj, struct question *q, GtkWidget *qbox)
 {
-    GtkWidget *description_box, *check, *hpadbox, *vpadbox;
+    GtkWidget *description_box, *radio_false, *radio_true, *hpadbox, *vpadbox;
     struct frontend_question_data *data;
     const char *defval = question_getvalue(q, "");
 
@@ -675,30 +665,39 @@
     data->obj = obj;
     data->q = q;
 
-    check = gtk_check_button_new_with_label(q_get_description(q));
-    if (strcmp(defval, "true") == 0)
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE);
-    else
-        gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), FALSE);
+   radio_false = gtk_radio_button_new_with_label (NULL, question_get_text(obj, "debconf/no", "No"));
+   radio_true = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio_false), question_get_text(obj, "debconf/yes", "Yes"));
 
-    if (q->next == NULL && q->prev == NULL)
-        g_signal_connect (G_OBJECT(check), "toggled", G_CALLBACK(check_toggled_callback), q);
-    else
-        register_setter(bool_setter, check, q, obj);
+    if (strcmp(defval, "true") == 0) {
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio_false), FALSE);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio_true), TRUE);
+    }
+    else {
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio_false), TRUE);
+        gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(radio_true), FALSE);
+    }
 
-    g_signal_connect (G_OBJECT(check), "destroy", G_CALLBACK (free_description_data), data);
+    register_setter(bool_setter, radio_true, q, obj);
 
+    g_signal_connect (G_OBJECT(radio_true), "destroy", G_CALLBACK (free_description_data), data);
+
     description_box = display_descriptions(q, obj);
 
     vpadbox = gtk_vbox_new (FALSE, DEFAULT_PADDING);
     gtk_box_pack_start (GTK_BOX(vpadbox), description_box, FALSE, FALSE, 0);
-    gtk_box_pack_start (GTK_BOX(vpadbox), check, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX(vpadbox), radio_false, FALSE, FALSE, 0);
+    gtk_box_pack_start (GTK_BOX(vpadbox), radio_true, FALSE, FALSE, 0);
     hpadbox = gtk_hbox_new (FALSE, DEFAULT_PADDING);
     gtk_box_pack_start (GTK_BOX(hpadbox), vpadbox, TRUE, TRUE, QUESTIONBOX_HPADDING);
     gtk_box_pack_start(GTK_BOX(qbox), hpadbox, FALSE, FALSE, QUESTIONBOX_VPADDING);
 
-    if (is_first_question(q))
-        gtk_widget_grab_focus(check);
+    if (is_first_question(q)) {
+    /* focus is given to the inactive radio button, is this ok? */
+        if (strcmp(defval, "true") == 0)
+            gtk_widget_grab_focus(radio_false);
+        else
+            gtk_widget_grab_focus(radio_true);
+    }
 
     return DC_OK;
 }

PNG image


Reply to: