[Glade-devel] Glade 3 development



--=-BBVfnbkYCfN5D9bhxLvU
Content-Type: text/plain
Content-Transfer-Encoding: 7bit

On Sun, 2004-04-18 at 22:56, Joaquin Cuenca Abela wrote:

 o Support for the event mask property.

These 3 bugs should be independent of the changes that I have in my hard
drive, so if you can start by these hopefully we will not step on each other
feet

Here's a patch to support flags properties.
They seem to work in the GUI and to save and load OK.

Damon


--=-BBVfnbkYCfN5D9bhxLvU
Content-Disposition: attachment; filename=glade3.patch2
Content-Type: text/x-patch; name=glade3.patch2; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Index: glade-editor.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-editor.c,v
retrieving revision 1.52
diff -u -r1.52 glade-editor.c
--- glade-editor.c      21 Apr 2004 21:03:40 -0000      1.52
+++ glade-editor.c      22 Apr 2004 11:49:59 -0000
@@ -481,6 +481,162 @@
        glade_editor_property_changed_unichar (entry, property);
 }
 
+#define FLAGS_COLUMN_SETTING           0
+#define FLAGS_COLUMN_SYMBOL            1
+
+static void
+flag_toggled (GtkCellRendererToggle *cell,
+             gchar                 *path_string,
+             GtkTreeModel          *model)
+{
+       GtkTreeIter iter;
+       gboolean setting;
+
+       gtk_tree_model_get_iter_from_string (model, &iter, path_string);
+
+       gtk_tree_model_get (model, &iter,
+                           FLAGS_COLUMN_SETTING, &setting,
+                           -1);
+
+       setting = setting ? FALSE : TRUE;
+
+       gtk_list_store_set (GTK_LIST_STORE (model), &iter,
+                           FLAGS_COLUMN_SETTING, setting,
+                           -1);
+}
+
+
+static void
+glade_editor_property_show_flags_dialog (GtkWidget *entry,
+                                        GladeEditorProperty *property)
+{
+       GtkWidget *editor;
+       GtkWidget *dialog;
+       GtkWidget *scrolled_window;
+       GtkListStore *model;
+       GtkWidget *tree_view;
+       GtkTreeViewColumn *column;
+       GtkCellRenderer *renderer;
+       GFlagsClass *class;
+       gint flag_num, response_id;
+       guint value;
+
+       g_return_if_fail (property != NULL);
+
+       editor = gtk_widget_get_toplevel (entry);
+       dialog = gtk_dialog_new_with_buttons (_("Set Flags"),
+                                             GTK_WINDOW (editor),
+                                             GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
+                                             GTK_STOCK_CANCEL,
+                                             GTK_RESPONSE_CANCEL,
+                                             GTK_STOCK_OK,
+                                             GTK_RESPONSE_OK,
+                                             NULL);
+       gtk_window_set_default_size (GTK_WINDOW (dialog), 300, 400);
+
+       scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+       gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                       GTK_POLICY_AUTOMATIC,
+                                       GTK_POLICY_AUTOMATIC);
+       gtk_widget_show (scrolled_window);
+       gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
+                           scrolled_window, TRUE, TRUE, 0);
+
+       /* Create the treeview using a simple list model with 3 columns. */
+       model = gtk_list_store_new (3, G_TYPE_BOOLEAN, G_TYPE_STRING,
+                                   G_TYPE_STRING);
+
+       tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
+       gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (tree_view), FALSE);
+       gtk_widget_show (tree_view);
+       gtk_container_add (GTK_CONTAINER (scrolled_window), tree_view);
+
+       column = gtk_tree_view_column_new ();
+
+       renderer = gtk_cell_renderer_toggle_new ();
+       gtk_tree_view_column_pack_start (column, renderer, FALSE);
+       gtk_tree_view_column_set_attributes (column, renderer,
+                                            "active", FLAGS_COLUMN_SETTING,
+                                            NULL);
+       g_signal_connect (renderer, "toggled",
+                         G_CALLBACK (flag_toggled), model);
+
+       renderer = gtk_cell_renderer_text_new ();
+       gtk_tree_view_column_pack_start (column, renderer, TRUE);
+       gtk_tree_view_column_set_attributes (column, renderer,
+                                            "text", FLAGS_COLUMN_SYMBOL,
+                                            NULL);
+
+       gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
+
+
+       /* Populate the model with the flags. */
+       class = g_type_class_ref (G_VALUE_TYPE (property->property->value));
+       value = g_value_get_flags (property->property->value);
+
+       /* Step through each of the flags in the class. */
+       for (flag_num = 0; flag_num < class->n_values; flag_num++) {
+               GtkTreeIter iter;
+               guint mask;
+               gboolean setting;
+
+               mask = class->values[flag_num].value;
+               setting = ((value & mask) == mask) ? TRUE : FALSE;
+
+               /* Add a row to represent the flag. */
+               gtk_list_store_append (model, &iter);
+               gtk_list_store_set (model, &iter,
+                                   FLAGS_COLUMN_SETTING,
+                                   setting,
+                                   FLAGS_COLUMN_SYMBOL,
+                                   class->values[flag_num].value_name,
+                                   -1);
+       }
+
+       /* Run the dialog. */
+       response_id = gtk_dialog_run (GTK_DIALOG (dialog));
+
+       /* If the user selects OK, update the flags property. */
+       if (response_id == GTK_RESPONSE_OK) {
+               GtkTreeIter iter;
+               guint new_value = 0;
+
+               gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
+
+               /* Step through each of the flags in the class, checking if
+                  the corresponding toggle in the dialog is selected, If it
+                  is, OR the flags' mask with the new value. */
+               for (flag_num = 0; flag_num < class->n_values; flag_num++) {
+                       gboolean setting;
+
+                       gtk_tree_model_get (GTK_TREE_MODEL (model), &iter,
+                                           FLAGS_COLUMN_SETTING, &setting,
+                                           -1);
+
+                       if (setting)
+                               new_value |= class->values[flag_num].value;
+
+                       gtk_tree_model_iter_next (GTK_TREE_MODEL (model),
+                                                 &iter);
+               }
+
+               /* If the new_value is different from the old value, we need
+                  to update the property. */
+               if (new_value != value) {
+                       GValue val = { 0, };
+
+                       g_value_init (&val, G_VALUE_TYPE (property->property->value));
+                       g_value_set_flags (&val, new_value);
+                       glade_command_set_property (property->property, &val);
+               }
+
+       }
+
+       g_type_class_unref (class);
+
+       gtk_widget_destroy (dialog);
+}
+
 /* ================================ Create inputs ==================================== */
 static GtkWidget *
 glade_editor_create_input_enum_item (GladeEditorProperty *property,
@@ -530,7 +686,26 @@
 static GtkWidget *
 glade_editor_create_input_flags (GladeEditorProperty *property) 
 {
-       return gtk_label_new ("Fix Me");
+       GtkWidget *hbox;
+       GtkWidget *entry;
+       GtkWidget *button;
+
+       hbox = gtk_hbox_new (FALSE, 0);
+
+       entry = gtk_entry_new ();
+       gtk_entry_set_editable (GTK_ENTRY (entry), FALSE);
+       gtk_widget_show (entry);
+       gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, TRUE, 0);
+
+       button = gtk_button_new_with_label ("...");
+       gtk_widget_show (button);
+       gtk_box_pack_start (GTK_BOX (hbox), button,  FALSE, FALSE, 0);
+
+       g_signal_connect (G_OBJECT (button), "clicked",
+                         G_CALLBACK (glade_editor_property_show_flags_dialog),
+                         property);
+
+       return hbox;
 }
 
 static GtkWidget *
@@ -1175,7 +1350,30 @@
 static void
 glade_editor_property_load_flags (GladeEditorProperty *property)
 {
-       glade_implement_me ();
+       GtkBoxChild *child;
+       GtkWidget *entry;
+       GValue tmp_value = { 0, };
+       gchar *text;
+
+       g_return_if_fail (property != NULL);
+       g_return_if_fail (property->property != NULL);
+       g_return_if_fail (property->property->value != NULL);
+       g_return_if_fail (property->input != NULL);
+       g_return_if_fail (GTK_IS_HBOX (property->input));
+
+       /* The entry should be the first child. */
+       child = GTK_BOX (property->input)->children->data;
+       entry = child->widget;
+       g_return_if_fail (GTK_IS_ENTRY (entry));
+
+       /* Transform the GValue from flags to a string. */
+       g_value_init (&tmp_value, G_TYPE_STRING);
+       g_value_transform (property->property->value, &tmp_value);
+       text = g_strescape (g_value_get_string (&tmp_value), NULL);
+       g_value_unset (&tmp_value);
+
+       gtk_entry_set_text (GTK_ENTRY (entry), text);
+       g_free (text);
 }
 
 static void
Index: glade-property-class.h
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-property-class.h,v
retrieving revision 1.27
diff -u -r1.27 glade-property-class.h
--- glade-property-class.h      7 Nov 2003 16:20:17 -0000       1.27
+++ glade-property-class.h      22 Apr 2004 11:50:22 -0000
@@ -132,8 +132,9 @@
                            * and is NULL for other poperties.
                            * [See glade-choice.h]
                            */
-       GType enum_type;   /* If it is GLADE_PROPERTY_TYPE_ENUM, this holds
-                           * the GType of the enum, otherwise it's 0.
+       GType enum_type;   /* If it is GLADE_PROPERTY_TYPE_ENUM or
+                           * GLADE_PROPERTY_TYPE_FLAGS, this holds
+                           * the GType of the enum or flags, otherwise it's 0.
                            */
 
        gboolean optional; /* Some properties are optional by nature like
Index: glade-property-class.c
===================================================================
RCS file: /cvs/gnome/glade3/src/glade-property-class.c,v
retrieving revision 1.53
diff -u -r1.53 glade-property-class.c
--- glade-property-class.c      27 Jan 2004 18:27:40 -0000      1.53
+++ glade-property-class.c      22 Apr 2004 11:50:52 -0000
@@ -259,11 +259,7 @@
        } else if (G_IS_PARAM_SPEC_ENUM (spec)) {
                return GLADE_PROPERTY_TYPE_ENUM;
        } else if (G_IS_PARAM_SPEC_FLAGS (spec)) {
-               /* FIXME: We should implement the "events" property */
-               if (g_ascii_strcasecmp (spec->name, "events") == 0)
-                       return GLADE_PROPERTY_TYPE_ERROR;
-               else
-                       return GLADE_PROPERTY_TYPE_FLAGS;
+               return GLADE_PROPERTY_TYPE_FLAGS;
        } else if (G_IS_PARAM_SPEC_DOUBLE (spec)) {
                return GLADE_PROPERTY_TYPE_DOUBLE;
        } else if (G_IS_PARAM_SPEC_LONG (spec)) {
@@ -385,6 +381,17 @@
                        }
                }
                break;
+       case GLADE_PROPERTY_TYPE_FLAGS:
+               {
+                       GValue tmp_value = { 0, };
+
+                       g_value_init (&tmp_value, G_TYPE_STRING);
+                       g_value_transform (value, &tmp_value);
+                       string = g_strescape (g_value_get_string (&tmp_value),
+                                             NULL);
+                       g_value_unset (&tmp_value);
+               }
+               break;
        default:
                g_warning ("Could not make string from gvalue for type %s\n",
                         glade_property_type_enum_to_string (type));
@@ -393,6 +400,86 @@
        return string;
 }
 
+/* This is copied exactly from libglade. I've just renamed the function. */
+static guint
+glade_property_class_make_flags_from_string (GType type, const char *string)
+{
+    GFlagsClass *fclass;
+    gchar *endptr, *prevptr;
+    guint i, j, ret = 0;
+    char *flagstr;
+
+    ret = strtoul(string, &endptr, 0);
+    if (endptr != string) /* parsed a number */
+       return ret;
+
+    fclass = g_type_class_ref(type);
+
+
+    flagstr = g_strdup (string);
+    for (ret = i = j = 0; ; i++) {
+       gboolean eos;
+
+       eos = flagstr [i] == '\0';
+       
+       if (eos || flagstr [i] == '|') {
+           GFlagsValue *fv;
+           const char  *flag;
+           gunichar ch;
+
+           flag = &flagstr [j];
+            endptr = &flagstr [i];
+
+           if (!eos) {
+               flagstr [i++] = '\0';
+               j = i;
+           }
+
+            /* trim spaces */
+           for (;;)
+             {
+               ch = g_utf8_get_char (flag);
+               if (!g_unichar_isspace (ch))
+                 break;
+               flag = g_utf8_next_char (flag);
+             }
+
+           while (endptr > flag)
+             {
+               prevptr = g_utf8_prev_char (endptr);
+               ch = g_utf8_get_char (prevptr);
+               if (!g_unichar_isspace (ch))
+                 break;
+               endptr = prevptr;
+             }
+
+           if (endptr > flag)
+             {
+               *endptr = '\0';
+               fv = g_flags_get_value_by_name (fclass, flag);
+
+               if (!fv)
+                 fv = g_flags_get_value_by_nick (fclass, flag);
+
+               if (fv)
+                 ret |= fv->value;
+               else
+                 g_warning ("Unknown flag: '%s'", flag);
+             }
+
+           if (eos)
+               break;
+       }
+    }
+    
+    g_free (flagstr);
+
+    g_type_class_unref(fclass);
+
+    return ret;
+}
+
+
 GValue *
 glade_property_class_make_gvalue_from_string (GladePropertyClass *property_class,
                                              const gchar *string)
@@ -454,6 +541,14 @@
                        }
                }
                break;
+       case GLADE_PROPERTY_TYPE_FLAGS:
+               {
+                       guint flags;
+
+                       g_value_init (value, property_class->enum_type);
+                       flags = glade_property_class_make_flags_from_string (property_class->enum_type, 
string);
+                       g_value_set_flags (value, flags);
+               }
        case GLADE_PROPERTY_TYPE_OBJECT:
                break;
        default:
@@ -562,6 +657,7 @@
                property_class->enum_type = spec->value_type;
                break;
        case GLADE_PROPERTY_TYPE_FLAGS:
+               property_class->enum_type = spec->value_type;
                break;
        case GLADE_PROPERTY_TYPE_STRING:
                break;

--=-BBVfnbkYCfN5D9bhxLvU--





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