[Glade-devel] Glade 3 development
- From: damon karuna uklinux net (Damon Chaplin)
- Subject: [Glade-devel] Glade 3 development
- Date: 22 Apr 2004 12:55:07 +0100
--=-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]