[glade] gladeui/glade-signal-editor.[ch]: o added GladeSignalEditor::detail-suggestions signal o Fixed m
- From: Juan Pablo Ugarte <jpu src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glade] gladeui/glade-signal-editor.[ch]: o added GladeSignalEditor::detail-suggestions signal o Fixed m
- Date: Tue, 3 Apr 2012 19:01:33 +0000 (UTC)
commit 5b131bb14180ce21632534c13a1b88ea28866475
Author: Juan Pablo Ugarte <juanpablougarte gmail com>
Date: Sat Mar 31 22:50:50 2012 -0300
gladeui/glade-signal-editor.[ch]:
o added GladeSignalEditor::detail-suggestions signal
o Fixed memory leak on handler-suggestion emmision
gladeui/glade-signal-model.c: Removed "__dummy" object data hack
Now only the data model returns user strings like <Type Here> when the GladeSignal value is null
gladeui/glade-signal.c: fixed bug in glade_signal_set_detail() that allowed to set an empty string as a detail
gladeui/glade-signal-editor.c | 221 ++++++++++++++++++++++++++++++++---------
gladeui/glade-signal-editor.h | 2 +-
gladeui/glade-signal-model.c | 59 ++++++------
gladeui/glade-signal.c | 2 +-
4 files changed, 205 insertions(+), 79 deletions(-)
---
diff --git a/gladeui/glade-signal-editor.c b/gladeui/glade-signal-editor.c
index c674b12..b984a66 100644
--- a/gladeui/glade-signal-editor.c
+++ b/gladeui/glade-signal-editor.c
@@ -49,7 +49,8 @@
G_DEFINE_TYPE (GladeSignalEditor, glade_signal_editor, GTK_TYPE_VBOX)
-#define DUMMY_DATA "__dummy"
+#define GLADE_SIGNAL_EDITOR_GET_PRIVATE(o) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GLADE_TYPE_SIGNAL_EDITOR, GladeSignalEditorPrivate))
struct _GladeSignalEditorPrivate
{
@@ -67,14 +68,16 @@ struct _GladeSignalEditorPrivate
GtkTreeViewColumn *column_after;
GtkCellRenderer *renderer_userdata;
-
- GtkListStore *handler_completion_store;
+
+ GtkListStore *detail_store;
+ GtkListStore *handler_store;
};
enum
{
SIGNAL_ACTIVATED,
CALLBACK_SUGGESTIONS,
+ DETAIL_SUGGESTIONS,
LAST_SIGNAL
};
@@ -90,7 +93,7 @@ static guint glade_signal_editor_signals[LAST_SIGNAL] = { 0 };
static inline gboolean
glade_signal_is_dummy (GladeSignal *signal)
{
- return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (signal), DUMMY_DATA));
+ return glade_signal_get_handler (signal) == NULL;
}
/* Signal handlers */
@@ -118,7 +121,6 @@ on_handler_edited (GtkCellRendererText *renderer,
GLADE_SIGNAL_COLUMN_SIGNAL, &signal, -1);
dummy = glade_signal_is_dummy (signal);
- g_object_unref (signal);
/* False alarm ? */
if (handler && !g_str_equal (old_handler, handler))
@@ -143,6 +145,7 @@ on_handler_edited (GtkCellRendererText *renderer,
glade_command_change_signal (self->priv->widget, old_signal, new_signal);
+ g_object_unref (old_signal);
g_object_unref (new_signal);
}
else
@@ -160,26 +163,24 @@ on_handler_edited (GtkCellRendererText *renderer,
}
else if (strlen (handler))
{
- GladeSignal *signal;
- GladeSignal *dummy;
- gchar *name;
+ GladeSignal *new_signal;
/* Get the signal name */
gtk_tree_model_get (self->priv->model, &iter,
- GLADE_SIGNAL_COLUMN_NAME, &name,
- GLADE_SIGNAL_COLUMN_SIGNAL, &dummy,
+ GLADE_SIGNAL_COLUMN_SIGNAL, &signal,
-1);
/* Add a new signal handler */
- signal = glade_signal_new (glade_signal_get_class (dummy),
- handler, NULL, FALSE, FALSE);
- glade_command_add_signal (self->priv->widget, signal);
-
- g_object_unref (signal);
- g_object_unref (dummy);
- g_free (name);
+ new_signal = glade_signal_new (glade_signal_get_class (signal),
+ handler, NULL, FALSE, FALSE);
+ glade_signal_set_detail (new_signal, glade_signal_get_detail (signal));
+ glade_command_add_signal (self->priv->widget, new_signal);
+ glade_signal_set_detail (signal, NULL);
+ g_object_unref (new_signal);
}
}
+
+ g_object_unref (signal);
g_free (old_handler);
gtk_tree_path_free (tree_path);
}
@@ -215,6 +216,105 @@ glade_signal_editor_callback_suggestions (GladeSignalEditor *editor,
return suggestions;
}
+static gchar **
+glade_signal_editor_detail_suggestions (GladeSignalEditor *editor,
+ GladeSignal *signal)
+{
+ /* We only support suggestions for notify signal */
+ if (!g_strcmp0 (glade_signal_get_name (signal), "notify"))
+ {
+ GladeSignalEditorPrivate *priv = editor->priv;
+ const GList *l, *properties = glade_widget_adaptor_get_properties (priv->adaptor);
+ gchar **suggestions = g_new (gchar *, g_list_length ((GList *)properties) + 1);
+ gint i;
+
+ for (i = 0, l = properties; l; l = g_list_next (l))
+ {
+ GladePropertyClass *prop = l->data;
+
+ if (!glade_property_class_is_visible (prop) ||
+ glade_property_class_get_virtual (prop)) continue;
+
+ suggestions[i++] = g_strdup (glade_property_class_id (prop));
+ }
+
+ suggestions[i] = NULL;
+
+ return suggestions;
+ }
+
+ return NULL;
+}
+
+static void
+gse_entry_completion_ensure_model (GtkEntry *entry, GtkTreeModel *model)
+{
+ GtkEntryCompletion *completion = gtk_entry_completion_new ();
+
+ gtk_entry_completion_set_text_column (completion, 0);
+ gtk_entry_completion_set_minimum_key_length (completion, 0);
+ gtk_entry_completion_set_inline_completion (completion, FALSE);
+ gtk_entry_completion_set_inline_selection (completion, TRUE);
+ gtk_entry_completion_set_popup_completion (completion, TRUE);
+
+ gtk_entry_completion_set_model (completion, model);
+
+ gtk_entry_set_completion (entry, completion);
+}
+
+static void
+on_detail_editing_started (GtkCellRenderer *renderer,
+ GtkCellEditable *editable,
+ gchar *path,
+ gpointer user_data)
+{
+ /* Check if editable is still an entry */
+ if (GTK_IS_ENTRY (editable))
+ {
+ GladeSignalEditor *self = GLADE_SIGNAL_EDITOR (user_data);
+ GladeSignalEditorPrivate *priv = self->priv;
+ GtkEntry *entry = GTK_ENTRY (editable);
+ GtkTreePath *tree_path;
+ GtkTreeIter iter;
+ GladeSignal *signal;
+ gchar **suggestions;
+
+ tree_path = gtk_tree_path_new_from_string (path);
+ gtk_tree_model_get_iter (priv->model, &iter, tree_path);
+ gtk_tree_path_free (tree_path);
+
+ gtk_tree_model_get (priv->model, &iter,
+ GLADE_SIGNAL_COLUMN_SIGNAL, &signal,
+ -1);
+
+ if (glade_signal_get_detail (signal) == NULL)
+ gtk_entry_set_text (entry, "");
+
+ g_object_unref (signal);
+
+ gtk_entry_set_completion (entry, NULL);
+ gtk_list_store_clear (priv->detail_store);
+
+ g_signal_emit (self, glade_signal_editor_signals [DETAIL_SUGGESTIONS], 0, signal, &suggestions);
+
+ if (suggestions)
+ {
+ register GtkListStore *store = priv->detail_store;
+ gint i;
+
+ for (i = 0; suggestions[i]; i++)
+ {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, suggestions[i], -1);
+ }
+
+ gse_entry_completion_ensure_model (entry, GTK_TREE_MODEL (store));
+
+ g_strfreev (suggestions);
+ }
+ }
+}
+
static void
on_detail_edited (GtkCellRendererText *renderer,
gchar *path,
@@ -233,25 +333,29 @@ on_detail_edited (GtkCellRendererText *renderer,
gtk_tree_model_get (self->priv->model, &iter,
GLADE_SIGNAL_COLUMN_DETAIL, &old_detail, -1);
- if (detail && g_strcmp0 (old_detail, detail))
+ if (detail && strlen (detail) && g_strcmp0 (old_detail, detail))
{
/* change an existing signal detail */
GladeSignal *old_signal;
- GladeSignal *new_signal;
gtk_tree_model_get (self->priv->model,
&iter,
GLADE_SIGNAL_COLUMN_SIGNAL,
&old_signal, -1);
- new_signal = glade_signal_clone (old_signal);
-
- /* Change the new signal detail */
- glade_signal_set_detail (new_signal, detail);
-
- glade_command_change_signal (self->priv->widget, old_signal, new_signal);
+ if (glade_signal_is_dummy (old_signal))
+ {
+ glade_signal_set_detail (old_signal, detail);
+ }
+ else
+ {
+ GladeSignal *new_signal = glade_signal_clone (old_signal);
+ glade_signal_set_detail (new_signal, detail);
+ glade_command_change_signal (self->priv->widget, old_signal, new_signal);
+ g_object_unref (new_signal);
+ }
- g_object_unref (new_signal);
+ g_object_unref (old_signal);
}
g_free (old_detail);
gtk_tree_path_free (tree_path);
@@ -269,8 +373,6 @@ on_handler_editing_started (GtkCellRenderer *renderer,
GladeSignalEditor *self = GLADE_SIGNAL_EDITOR (user_data);
GladeSignalEditorPrivate *priv = self->priv;
GtkEntry *entry = GTK_ENTRY (editable);
- GtkEntryCompletion *completion;
- const gchar *signal_name = NULL;
GtkTreePath *tree_path;
GtkTreeIter iter;
GladeSignal *signal;
@@ -284,7 +386,6 @@ on_handler_editing_started (GtkCellRenderer *renderer,
gtk_tree_model_get (priv->model, &iter,
GLADE_SIGNAL_COLUMN_SIGNAL, &signal,
-1);
- signal_name = glade_signal_get_name (signal);
if (glade_signal_is_dummy (signal))
gtk_entry_set_text (entry, "");
@@ -293,27 +394,21 @@ on_handler_editing_started (GtkCellRenderer *renderer,
g_object_unref (signal);
- if (!signal_name)
- return;
-
- completion = gtk_entry_completion_new ();
- gtk_entry_completion_set_text_column (completion, 0);
- gtk_entry_completion_set_minimum_key_length (completion, 0);
- gtk_entry_completion_set_inline_completion (completion, FALSE);
- gtk_entry_completion_set_inline_selection (completion, TRUE);
- gtk_entry_completion_set_popup_completion (completion, TRUE);
gtk_entry_set_completion (entry, NULL);
+ gtk_list_store_clear (priv->handler_store);
- gtk_list_store_clear (priv->handler_completion_store);
-
- for (i = 0; suggestions[i]; i++)
+ if (suggestions)
{
- gtk_list_store_append (priv->handler_completion_store, &iter);
- gtk_list_store_set (priv->handler_completion_store, &iter, 0, suggestions[i], -1);
+ register GtkListStore *store = priv->handler_store;
+ for (i = 0; suggestions[i]; i++)
+ {
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter, 0, suggestions[i], -1);
+ }
+
+ gse_entry_completion_ensure_model (entry, GTK_TREE_MODEL (store));
+ g_strfreev (suggestions);
}
-
- gtk_entry_completion_set_model (completion, GTK_TREE_MODEL (priv->handler_completion_store));
- gtk_entry_set_completion (entry, completion);
}
}
@@ -617,6 +712,11 @@ glade_signal_editor_enable_dnd (GladeSignalEditor *editor, gboolean enabled)
static void
glade_signal_editor_dispose (GObject *object)
{
+ GladeSignalEditorPrivate *priv = GLADE_SIGNAL_EDITOR_GET_PRIVATE (object);
+
+ g_object_unref (priv->detail_store);
+ g_object_unref (priv->handler_store);
+
G_OBJECT_CLASS (glade_signal_editor_parent_class)->dispose (object);
}
@@ -841,7 +941,7 @@ glade_signal_editor_detail_cell_data_func (GtkTreeViewColumn *column,
}
g_object_set (renderer,
- "sensitive", !dummy,
+ "sensitive", TRUE,
"visible", TRUE,
"editable", TRUE,
NULL);
@@ -1070,6 +1170,7 @@ glade_signal_editor_init (GladeSignalEditor *self)
/* Signal detail */
renderer = gtk_cell_renderer_text_new ();
g_signal_connect (renderer, "edited", G_CALLBACK(on_detail_edited), self);
+ g_signal_connect (renderer, "editing-started", G_CALLBACK (on_detail_editing_started), self);
priv->column_detail = gtk_tree_view_column_new_with_attributes (_("Detail"),
renderer,
"text", GLADE_SIGNAL_COLUMN_DETAIL,
@@ -1214,8 +1315,11 @@ glade_signal_editor_init (GladeSignalEditor *self)
G_CALLBACK(glade_signal_editor_drag_begin),
self);
+ /* Detail completion */
+ priv->detail_store = gtk_list_store_new (1, G_TYPE_STRING);
+
/* Handler completion */
- priv->handler_completion_store = gtk_list_store_new (1, G_TYPE_STRING);
+ priv->handler_store = gtk_list_store_new (1, G_TYPE_STRING);
/* Emit created signal */
g_signal_emit_by_name (glade_app_get(), "signal-editor-created", self);
@@ -1236,6 +1340,7 @@ glade_signal_editor_class_init (GladeSignalEditorClass *klass)
object_class->dispose = glade_signal_editor_dispose;
klass->callback_suggestions = glade_signal_editor_callback_suggestions;
+ klass->detail_suggestions = glade_signal_editor_detail_suggestions;
g_type_class_add_private (klass, sizeof (GladeSignalEditorPrivate));
@@ -1273,6 +1378,26 @@ glade_signal_editor_class_init (GladeSignalEditorClass *klass)
_glade_strv_handled_accumulator,
NULL, _glade_marshal_BOXED__OBJECT,
G_TYPE_STRV, 1,
+ GLADE_TYPE_SIGNAL);
+
+ /**
+ * GladeSignalEditor::detail-suggestions:
+ * @editor: the object which received the signal
+ * @signal: the #GladeSignal that needs callbacks suggestions
+ * @suggestions: Return
+ *
+ * Emitted when the editor needs to show a list of detail suggestions to the user.
+ *
+ * Returns wheter or not the event was handled.
+ */
+ glade_signal_editor_signals[DETAIL_SUGGESTIONS] =
+ g_signal_new ("detail-suggestions",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (GladeSignalEditorClass, detail_suggestions),
+ _glade_strv_handled_accumulator,
+ NULL, _glade_marshal_BOXED__OBJECT,
+ G_TYPE_STRV, 1,
GLADE_TYPE_SIGNAL);
diff --git a/gladeui/glade-signal-editor.h b/gladeui/glade-signal-editor.h
index 7902894..1e681ac 100644
--- a/gladeui/glade-signal-editor.h
+++ b/gladeui/glade-signal-editor.h
@@ -32,11 +32,11 @@ struct _GladeSignalEditorClass
GtkVBoxClass parent_class;
gchar ** (* callback_suggestions) (GladeSignalEditor *editor, GladeSignal *signal);
+ gchar ** (* detail_suggestions) (GladeSignalEditor *editor, GladeSignal *signal);
void (* glade_reserved1) (void);
void (* glade_reserved2) (void);
void (* glade_reserved3) (void);
void (* glade_reserved4) (void);
- void (* glade_reserved5) (void);
};
GType glade_signal_editor_get_type (void) G_GNUC_CONST;
diff --git a/gladeui/glade-signal-model.c b/gladeui/glade-signal-model.c
index 525fdb6..525e652 100644
--- a/gladeui/glade-signal-model.c
+++ b/gladeui/glade-signal-model.c
@@ -30,8 +30,6 @@
#define HANDLER_DEFAULT _("<Type here>")
#define USERDATA_DEFAULT _("<Click here>")
-#define DUMMY_DATA "__dummy"
-
struct _GladeSignalModelPrivate
{
GladeWidget *widget;
@@ -274,7 +272,7 @@ static inline gboolean
glade_signal_model_is_dummy_handler (GladeSignalModel *model,
GladeSignal *signal)
{
- return GPOINTER_TO_INT (g_object_get_data (G_OBJECT (signal), DUMMY_DATA));
+ return glade_signal_get_handler (signal) == NULL;
}
static GladeSignal *
@@ -289,12 +287,10 @@ glade_signal_model_get_dummy_handler (GladeSignalModel *model,
if (!signal)
{
signal = glade_signal_new (sig_class,
- HANDLER_DEFAULT,
- USERDATA_DEFAULT,
+ NULL,
+ NULL,
FALSE,
FALSE);
- glade_signal_set_detail (signal, DETAIL_DEFAULT);
- g_object_set_data (G_OBJECT (signal), DUMMY_DATA, GINT_TO_POINTER (TRUE));
g_hash_table_insert (model->priv->dummy_signals,
(gpointer) glade_signal_class_get_name (sig_class),
signal);
@@ -558,14 +554,14 @@ glade_signal_model_get_value (GtkTreeModel *model,
GValue *value)
{
const gchar *widget;
- GladeSignal *handler;
+ GladeSignal *signal;
GladeSignalModel *sig_model;
g_return_if_fail (iter != NULL);
g_return_if_fail (GLADE_IS_SIGNAL_MODEL(model));
widget = iter->user_data;
- handler = iter->user_data2;
+ signal = iter->user_data2;
sig_model = GLADE_SIGNAL_MODEL (model);
value = g_value_init (value,
@@ -574,39 +570,41 @@ glade_signal_model_get_value (GtkTreeModel *model,
switch (column)
{
case GLADE_SIGNAL_COLUMN_NAME:
- if (handler)
+ if (signal)
{
- g_value_set_static_string (value, glade_signal_get_name (handler));
+ g_value_set_static_string (value, glade_signal_get_name (signal));
break;
}
else
g_value_set_static_string (value, widget);
break;
case GLADE_SIGNAL_COLUMN_SHOW_NAME:
- if (handler)
+ if (signal)
{
GPtrArray *handlers = g_hash_table_lookup (sig_model->priv->signals,
- glade_signal_get_name (handler));
- if (!handlers || !handlers->len || g_ptr_array_find (handlers, handler) == 0)
+ glade_signal_get_name (signal));
+ if (!handlers || !handlers->len || g_ptr_array_find (handlers, signal) == 0)
g_value_set_boolean (value, TRUE);
else
- g_value_set_boolean (value,
- FALSE);
+ g_value_set_boolean (value, FALSE);
break;
}
else if (widget)
g_value_set_boolean (value, TRUE);
break;
case GLADE_SIGNAL_COLUMN_HANDLER:
- if (handler)
- g_value_set_static_string (value, glade_signal_get_handler (handler));
+ if (signal)
+ {
+ const gchar *handler = glade_signal_get_handler (signal);
+ g_value_set_static_string (value, handler ? handler : HANDLER_DEFAULT);
+ }
else
g_value_set_static_string (value, "");
break;
case GLADE_SIGNAL_COLUMN_OBJECT:
- if (handler)
+ if (signal)
{
- const gchar *userdata = glade_signal_get_userdata (handler);
+ const gchar *userdata = glade_signal_get_userdata (signal);
if (userdata && strlen (userdata))
g_value_set_static_string (value, userdata);
else
@@ -617,29 +615,32 @@ glade_signal_model_get_value (GtkTreeModel *model,
g_value_set_static_string (value, "");
break;
case GLADE_SIGNAL_COLUMN_SWAP:
- if (handler)
- g_value_set_boolean (value, glade_signal_get_swapped (handler));
+ if (signal)
+ g_value_set_boolean (value, glade_signal_get_swapped (signal));
else
g_value_set_boolean (value, FALSE);
break;
case GLADE_SIGNAL_COLUMN_AFTER:
- if (handler)
- g_value_set_boolean (value, glade_signal_get_after (handler));
+ if (signal)
+ g_value_set_boolean (value, glade_signal_get_after (signal));
else
g_value_set_boolean (value, FALSE);
break;
case GLADE_SIGNAL_COLUMN_TOOLTIP:
- if (handler)
- g_value_set_string (value, glade_signal_get_support_warning (handler));
+ if (signal)
+ g_value_set_string (value, glade_signal_get_support_warning (signal));
else
g_value_set_static_string (value, NULL);
break;
case GLADE_SIGNAL_COLUMN_SIGNAL:
- g_value_set_object (value, handler);
+ g_value_set_object (value, signal);
break;
case GLADE_SIGNAL_COLUMN_DETAIL:
- if (handler)
- g_value_set_static_string (value, glade_signal_get_detail (handler));
+ if (signal)
+ {
+ const gchar *detail = glade_signal_get_detail (signal);
+ g_value_set_static_string (value, detail ? detail : DETAIL_DEFAULT);
+ }
else
g_value_set_static_string (value, "");
break;
diff --git a/gladeui/glade-signal.c b/gladeui/glade-signal.c
index 6dc24cf..5a247be 100644
--- a/gladeui/glade-signal.c
+++ b/gladeui/glade-signal.c
@@ -450,7 +450,7 @@ glade_signal_set_detail (GladeSignal *signal, const gchar *detail)
g_strcmp0 (signal->priv->detail, detail))
{
g_free (signal->priv->detail);
- signal->priv->detail = (detail || g_utf8_strlen (detail, -1)) ? g_strdup (detail) : NULL;
+ signal->priv->detail = (detail && g_utf8_strlen (detail, -1)) ? g_strdup (detail) : NULL;
g_object_notify_by_pspec (G_OBJECT (signal), properties[PROP_DETAIL]);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]