summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog7
-rw-r--r--src/glade-debug.c15
-rw-r--r--src/glade-signal-editor.c704
-rw-r--r--src/glade-signal-editor.h11
-rw-r--r--src/glade-signal.c6
-rw-r--r--src/glade-signal.h2
-rw-r--r--src/glade-widget.c93
-rw-r--r--src/glade-widget.h3
8 files changed, 290 insertions, 551 deletions
diff --git a/ChangeLog b/ChangeLog
index c495a5a1..d5c92df5 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2004-01-18 Joaquin Cuenca Abela <e98cuenc@yahoo.com>
+
+ * src/glade-signal.[ch]: add a glade_signal_copy function.
+ * src/glade-widget.[ch]: put the signals with a handler on a hash
+ indexed by the name of the signal.
+ * src/glade-signal-editor.[ch]: rework the UI of the signal editor.
+
2004-01-09 Tommi Komulainen <tommi.komulainen@nokia.com>
* src/glade-catalog.c
diff --git a/src/glade-debug.c b/src/glade-debug.c
index 02148ac5..8975992f 100644
--- a/src/glade-debug.c
+++ b/src/glade-debug.c
@@ -38,20 +38,11 @@ glade_log_handler (const char *domain,
const char *message,
gpointer data)
{
+ static volatile int want_breakpoint = 1;
+
g_log_default_handler (domain, level, message, data);
- if ((level & (G_LOG_LEVEL_CRITICAL /* | G_LOG_LEVEL_WARNING */)) != 0) {
+ if (want_breakpoint && ((level & (G_LOG_LEVEL_CRITICAL /* | G_LOG_LEVEL_WARNING */)) != 0)) {
G_BREAKPOINT ();
-#if 0
-#ifdef G_OS_WIN32
- __asm { int 3 }
-#else
- RETSIGTYPE (* saved_handler) (int);
-
- saved_handler = signal (SIGINT, SIG_IGN);
- raise (SIGINT);
- signal (SIGINT, saved_handler);
-#endif
-#endif
}
}
diff --git a/src/glade-signal-editor.c b/src/glade-signal-editor.c
index 52c5cdbf..ba1e11f3 100644
--- a/src/glade-signal-editor.c
+++ b/src/glade-signal-editor.c
@@ -31,563 +31,217 @@
#include "glade-editor.h"
-static void
-glade_signal_editor_append_column (GtkTreeView *view, const gint col_num, const gchar *name)
-{
- GtkTreeViewColumn *column;
- GtkCellRenderer *renderer;
-
- renderer = gtk_cell_renderer_text_new ();
- column = gtk_tree_view_column_new_with_attributes (name, renderer,
- "text", col_num, NULL);
- gtk_tree_view_append_column (view, column);
-}
-
-
-static gboolean
-glade_signal_editor_dialog_list_select_cb (GtkTreeSelection *selection,
- GtkTreeModel *model,
- GtkTreePath *path,
- gboolean path_selected,
- GladeSignalEditor *editor)
-{
- GtkTreeIter iter;
- GValue value = { 0, };
- GList *list = NULL;
- GladeWidgetClassSignal *signal;
-
- gtk_tree_model_get_iter (model, &iter, path);
- gtk_tree_model_get_value (model, &iter, 0, &value);
-
- for (list = editor->class->signals; list; list = list->next)
- {
- signal = (GladeWidgetClassSignal *) list->data;
- if (!strcmp (signal->name, g_value_get_string (&value)))
- break;
- }
-
- g_value_unset (&value);
-
- if (list)
- return TRUE;
- else
- return FALSE;
-}
-
-static GtkWidget *
-glade_signal_editor_dialog_construct_list (GladeSignalEditor *editor)
-{
- GtkTreeSelection *selection;
- GtkTreeStore *model;
- GtkTreeView *view;
- GtkWidget *view_widget;
-
- model = gtk_tree_store_new (1, G_TYPE_STRING);
-
- view_widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
- view = GTK_TREE_VIEW (view_widget);
-
- g_object_unref (G_OBJECT (model));
-
- glade_signal_editor_append_column (view, 0, _("Signals"));
-
- selection = gtk_tree_view_get_selection (view);
- gtk_tree_selection_set_select_function (selection,
- (GtkTreeSelectionFunc) glade_signal_editor_dialog_list_select_cb,
- editor, NULL);
-
- return view_widget;
-}
-
-static GtkWidget *
-glade_signal_editor_dialog_construct (GladeSignalEditor *editor, GtkWidget **view)
-{
- GtkWidget *dialog;
- GtkWidget *scroll;
- GtkWidget *vbox;
-
- dialog = gtk_dialog_new_with_buttons (
- _("Select signal"),
- NULL,
- 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), -1, 300);
- gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
-
- vbox = gtk_bin_get_child (GTK_BIN (dialog));
-
- scroll = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
- GTK_POLICY_AUTOMATIC,
- GTK_POLICY_AUTOMATIC);
- gtk_box_pack_start_defaults (GTK_BOX (vbox), GTK_WIDGET (scroll));
-
- *view = glade_signal_editor_dialog_construct_list (editor);
- gtk_container_add (GTK_CONTAINER (scroll), *view);
-
- gtk_widget_show_all (vbox);
-
- return dialog;
-}
-
-static GtkTreeIter *
-glade_signal_editor_dialog_append_signal (GtkTreeStore *model,
- const gchar *label_text,
- GtkTreeIter *parent)
+enum
{
- GtkTreeIter *iter;
- GValue value = { 0, };
+ COLUMN_SIGNAL,
+ COLUMN_HANDLER,
+ COLUMN_AFTER,
- g_value_init (&value, G_TYPE_STRING);
- g_value_set_string (&value, label_text);
- iter = g_new0 (GtkTreeIter, 1);
- gtk_tree_store_append (GTK_TREE_STORE (model), iter, parent);
- gtk_tree_store_set_value (GTK_TREE_STORE (model), iter, 0, &value);
- g_value_unset (&value);
-
- return iter;
-}
-
-static void
-glade_signal_editor_dialog_load_signals (GladeSignalEditor *editor, GtkWidget *view)
-{
- GtkTreeStore *lst_model;
- gchar *type;
- GtkTreeIter *parent = NULL;
- GList *list = NULL;
- GladeWidgetClassSignal *signal;
-
- type = "";
- lst_model = GTK_TREE_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (view)));
-
- for (list = editor->class->signals; list; list = list->next)
- {
- signal = (GladeWidgetClassSignal *) list->data;
-
- if (strcmp (type, signal->type))
- {
- parent = glade_signal_editor_dialog_append_signal (lst_model, signal->type, NULL);
- type = signal->type;
- }
- glade_signal_editor_dialog_append_signal (lst_model, signal->name, parent);
- }
-}
+ COLUMN_VISIBLE,
+ COLUMN_SLOT,
+ NUM_COLUMNS
+};
static void
-glade_signal_editor_dialog_cb (GtkButton *button, GladeSignalEditor *editor)
+after_toggled (GtkCellRendererToggle *cell,
+ gchar *path_str,
+ gpointer data)
{
- GtkWidget *dialog;
- GtkWidget *view;
- gint response;
-
- g_return_if_fail (editor->class->signals != NULL);
-
- dialog = glade_signal_editor_dialog_construct (editor, &view);
- glade_signal_editor_dialog_load_signals (editor, view);
+ GladeSignalEditor *editor = (GladeSignalEditor*) data;
+ GtkTreeModel *model = GTK_TREE_MODEL (editor->model);
+ GtkTreeIter iter;
+ GtkTreeIter iter_parent;
+ char *handler;
+ char *signal_name;
+ GladeSignal *old_signal;
+ GList *lsignal;
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+ gboolean after;
- response = gtk_dialog_run (GTK_DIALOG (dialog));
- if (response == GTK_RESPONSE_OK)
+ /* get toggled iter */
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter, COLUMN_SIGNAL, &signal_name, COLUMN_HANDLER, &handler, COLUMN_AFTER, &after, -1);
+ if (signal_name == NULL)
{
- GValue value = { 0, };
- GtkTreeIter iter;
- GtkTreeModel *model;
- GtkTreeSelection *selection;
-
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (view));
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
+ if (!gtk_tree_model_iter_parent (model, &iter_parent, &iter))
+ g_assert (FALSE);
- if (gtk_tree_selection_get_selected (selection, &model, &iter))
- {
- gtk_tree_model_get_value (model, &iter, 0, &value);
- gtk_entry_set_text (GTK_ENTRY (editor->signal_name_entry),
- g_value_get_string (&value));
- g_value_unset (&value);
- }
+ gtk_tree_model_get (model, &iter_parent, COLUMN_SIGNAL, &signal_name, -1);
+ g_assert (signal_name != NULL);
}
- gtk_widget_destroy (dialog);
-}
-
-/**
- * glade_signal_editor_update_signal_view () will add a 'signal' to the list of
- * signals displayed by the signal editor if 'iter' is NULL, otherwise it will
- * update the item at position 'iter' to the value of 'signal'
- */
-static void
-glade_signal_editor_update_signal_view (GladeSignalEditor *editor,
- GladeSignal *signal,
- GtkTreeIter *iter)
-{
- GValue value = { 0, };
-
- if (!iter)
- {
- iter = g_new0 (GtkTreeIter, 1);
- gtk_tree_store_append (editor->model, iter, NULL);
- }
+ old_signal = glade_signal_new (signal_name, handler, after);
+ lsignal = glade_widget_find_signal (editor->widget, old_signal);
- g_value_init (&value, G_TYPE_STRING);
+ after = !after;
+ ((GladeSignal*) lsignal->data)->after = after;
- g_value_set_string (&value, signal->name);
- gtk_tree_store_set_value (editor->model, iter, 0, &value);
+ /* set new value */
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_AFTER, after, -1);
- g_value_set_string (&value, signal->handler);
- gtk_tree_store_set_value (editor->model, iter, 1, &value);
-
- if (signal->after == TRUE)
- g_value_set_string (&value, _("Yes"));
- else
- g_value_set_string (&value, _("No"));
- gtk_tree_store_set_value (editor->model, iter, 2, &value);
-
- g_value_unset (&value);
+ /* clean up */
+ gtk_tree_path_free (path);
}
static gboolean
-glade_signal_editor_list_select_cb (GtkTreeSelection *lst_select,
- GtkTreeModel *lst_model,
- GtkTreePath *lst_path,
- gboolean path_selected,
- GladeSignalEditor *editor)
+is_valid_identifier (const char *text)
{
- GtkTreeIter iter;
- GValue value = { 0, };
-
- gtk_tree_model_get_iter (lst_model, &iter, lst_path);
+ char ch;
- gtk_tree_model_get_value (lst_model, &iter, 0, &value);
- gtk_entry_set_text (GTK_ENTRY (editor->signal_name_entry),
- g_value_get_string (&value));
- g_value_unset (&value);
+ if (text == NULL)
+ return FALSE;
- gtk_tree_model_get_value (lst_model, &iter, 1, &value);
- gtk_entry_set_text (GTK_ENTRY (editor->signal_handler_entry),
- g_value_get_string (&value));
- g_value_unset (&value);
+ ch = *text++;
+ if (!(ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z')))
+ return FALSE;
- gtk_tree_model_get_value (lst_model, &iter, 2, &value);
- if (!strcmp (_("Yes"), g_value_get_string (&value)))
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->signal_after_button), TRUE);
- else
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->signal_after_button), FALSE);
- g_value_unset (&value);
+ while ((ch = *text++) != 0)
+ if (!(ch == '_' || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')))
+ return FALSE;
return TRUE;
}
static void
-glade_signal_editor_after_cb (GtkToggleButton *button, GladeSignalEditor *editor)
-{
- if (gtk_toggle_button_get_active (button))
- g_object_set (G_OBJECT (button), "label", _("Yes"), NULL);
- else
- g_object_set (G_OBJECT (button), "label", _("No"), NULL);
-}
-
-static GladeSignal *
-glade_signal_editor_validate_entries (GladeSignalEditor *editor)
+cell_edited (GtkCellRendererText *cell,
+ const gchar *path_str,
+ const gchar *new_text,
+ gpointer data)
{
- GtkWidget *dialog;
- const gchar *name;
- const gchar *handler;
- gboolean after;
- guint sig_id;
+ GladeSignalEditor *editor = (GladeSignalEditor*) data;
+ GtkTreeModel *model = GTK_TREE_MODEL (editor->model);
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
+ GtkTreeIter iter;
+ GtkTreeIter iter_parent;
+ GtkTreeIter iter_new_slot;
+ GtkTreeIter *iter2;
+ GladeSignal *old_signal;
GladeSignal *signal;
+ GList *lsignal;
+ gchar *signal_name;
+ gboolean after;
+ char *old_handler;
+ gboolean child = TRUE;
- name = gtk_entry_get_text (GTK_ENTRY (editor->signal_name_entry));
+ gtk_tree_model_get_iter (model, &iter, path);
+ iter2 = gtk_tree_iter_copy (&iter);
- /* check that signal exists */
- sig_id = g_signal_lookup (name, editor->widget->class->type);
- if (sig_id == 0)
+ gtk_tree_model_get (model, &iter, COLUMN_SIGNAL, &signal_name, COLUMN_HANDLER, &old_handler, COLUMN_AFTER, &after, -1);
+ if (signal_name == NULL)
{
- dialog = gtk_message_dialog_new (NULL,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CLOSE,
- _("Please enter a valid signal name"));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- return NULL;
- }
+ if (!gtk_tree_model_iter_parent (model, &iter_parent, &iter))
+ g_assert (FALSE);
- handler = gtk_entry_get_text (GTK_ENTRY (editor->signal_handler_entry));
-
- /* check hadler is not empty */
- if (!strcmp (handler, ""))
- {
- dialog = gtk_message_dialog_new (NULL,
- GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_MESSAGE_INFO,
- GTK_BUTTONS_CLOSE,
- _("Please enter a signal handler"));
- gtk_dialog_run (GTK_DIALOG (dialog));
- gtk_widget_destroy (dialog);
- return NULL;
+ gtk_tree_model_get (model, &iter_parent, COLUMN_SIGNAL, &signal_name, -1);
+ g_assert (signal_name != NULL);
}
-
- after = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (editor->signal_after_button));
-
- signal = glade_signal_new (name, handler, after);
-
- return signal;
-}
-
-static void
-glade_signal_editor_clear_entries (GladeSignalEditor *editor)
-{
- gtk_entry_set_text (GTK_ENTRY (editor->signal_name_entry), "");
- gtk_entry_set_text (GTK_ENTRY (editor->signal_handler_entry), "");
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (editor->signal_after_button), FALSE);
-}
-
-/**
- * Note that this function returns a newly allocated GladeSignal,
- * which the caller shuold take care of freeing.
- */
-static GladeSignal *
-glade_signal_editor_get_signal_at_iter (GladeSignalEditor *editor,
- GtkTreeIter *iter)
-{
- GladeSignal *signal;
- gchar *name;
- gchar *handler;
- gchar *after_label;
- gboolean after;
-
- gtk_tree_model_get (GTK_TREE_MODEL (editor->model), iter,
- 0, &name, 1, &handler, 2, &after_label, -1);
-
- if (!strcmp (after_label, _("Yes")))
- after = TRUE;
else
- after = FALSE;
-
- signal = glade_signal_new (name, handler, after);
-
- g_free (name);
- g_free (handler);
- g_free (after_label);
-
- return signal;
-}
-
-static void
-glade_signal_editor_add_cb (GtkButton *button, GladeSignalEditor *editor)
-{
- GladeSignal *signal;
-
- g_return_if_fail (GLADE_IS_SIGNAL_EDITOR (editor));
- g_return_if_fail (GLADE_IS_WIDGET (editor->widget));
-
- signal = glade_signal_editor_validate_entries (editor);
- if (!signal)
- return;
-
- glade_widget_add_signal (editor->widget, signal);
- glade_editor_add_signal (editor->editor, g_signal_lookup (signal->name,
- editor->widget->class->type), signal->handler);
-
- glade_signal_editor_update_signal_view (editor, signal, NULL);
- glade_signal_editor_clear_entries (editor);
-}
-
-static void
-glade_signal_editor_update_cb (GtkButton *button, GladeSignalEditor *editor)
-{
- GtkTreeIter iter;
- GtkTreeSelection *select;
- GtkTreeModel *model;
- GladeSignal *updated_sig;
-
- g_return_if_fail (GLADE_IS_SIGNAL_EDITOR (editor));
- g_return_if_fail (GLADE_IS_WIDGET (editor->widget));
-
- updated_sig = glade_signal_editor_validate_entries (editor);
- if (!updated_sig)
- return;
-
- model = GTK_TREE_MODEL (editor->model);
- select = gtk_tree_view_get_selection (GTK_TREE_VIEW (editor->signals_list));
-
- if (gtk_tree_selection_get_selected (select, &model, &iter) == TRUE)
+ iter_parent = iter;
+
+ old_signal = glade_signal_new (signal_name, old_handler, after);
+ lsignal = glade_widget_find_signal (editor->widget, old_signal);
+ signal = lsignal ? lsignal->data : NULL;
+
+ /* check that the new_text is a valid identifier. TODO: I don't like that! We're throwing away the text of the user
+ * without even giving him an explanation. We should keep the text and say him that it's invalid, and why. The
+ * text should be marked specially (maybe in red) and not added to the list of signals, but we want to keep it just
+ * in case it was just a little typo. Otherwise he will write its signal handler, make the type, and lost the whole
+ * string because it got substituted by <Type...> stuff */
+ if (is_valid_identifier (new_text))
{
- GladeSignal *signal;
- GList *found;
-
- signal = glade_signal_editor_get_signal_at_iter (editor, &iter);
- found = glade_widget_find_signal (editor->widget, signal);
- glade_signal_free (signal);
-
- if (found)
+ if (signal == NULL)
+ {
+ /* we're adding a new signal */
+ signal = glade_signal_copy (old_signal);
+ g_free (signal->handler);
+ signal->handler = g_strdup (new_text);
+
+ glade_widget_add_signal (editor->widget, signal);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, signal->handler, COLUMN_VISIBLE, TRUE, COLUMN_SLOT, FALSE, -1);
+
+ /* TODO: Add the <Type...> item */
+ gtk_tree_store_append (GTK_TREE_STORE (model), &iter_new_slot, &iter_parent);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter_new_slot,
+ COLUMN_HANDLER, _("<Type the signal's handler here>"),
+ COLUMN_AFTER, FALSE,
+ COLUMN_VISIBLE, FALSE,
+ COLUMN_SLOT, TRUE, -1);
+ }
+ else
{
- glade_signal_free (GLADE_SIGNAL (found->data));
- found->data = updated_sig;
- glade_signal_editor_update_signal_view (editor, updated_sig, &iter);
+ /* we're editing a signal */
+ g_free (signal->handler);
+ signal->handler = g_strdup (new_text);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, signal->handler, -1);
}
}
-}
-
-static void
-glade_signal_editor_remove_cb (GtkButton *button, GladeSignalEditor *editor)
-{
- GtkTreeIter iter;
- GtkTreeSelection *select;
- GtkTreeModel *model;
- GladeSignal *signal;
-
- g_return_if_fail (GLADE_IS_SIGNAL_EDITOR (editor));
- g_return_if_fail (GLADE_IS_WIDGET (editor->widget));
-
- model = GTK_TREE_MODEL (editor->model);
- select = gtk_tree_view_get_selection (GTK_TREE_VIEW (editor->signals_list));
-
- if (gtk_tree_selection_get_selected (select, &model, &iter) == TRUE)
+ else
{
- signal = glade_signal_editor_get_signal_at_iter (editor, &iter);
-
- glade_widget_remove_signal (editor->widget, signal);
-
- gtk_tree_store_remove (GTK_TREE_STORE (editor->model), &iter);
- glade_signal_editor_clear_entries (editor);
+ if (signal == NULL)
+ {
+ /* we've erased a <Type...> item, so we reput the "<Type...>" text */
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, _("<Type the signal's handler here>"),
+ COLUMN_AFTER, FALSE, COLUMN_VISIBLE, FALSE, COLUMN_SLOT, TRUE, -1);
+ }
+ else
+ {
+ /* we're erasing a signal */
+ glade_widget_remove_signal (editor->widget, signal);
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter, COLUMN_HANDLER, _("<Type the signal's handler here>"),
+ COLUMN_AFTER, FALSE, COLUMN_VISIBLE, FALSE, COLUMN_SLOT, TRUE, -1);
+ }
}
-}
-
-static void
-glade_signal_editor_clear_cb (GtkButton *button, GladeSignalEditor *editor)
-{
- g_return_if_fail (GLADE_IS_SIGNAL_EDITOR (editor));
- glade_signal_editor_clear_entries (editor);
+ gtk_tree_iter_free (iter2);
+ gtk_tree_path_free (path);
+ glade_signal_free (old_signal);
}
static GtkWidget *
glade_signal_editor_construct_signals_list (GladeSignalEditor *editor)
{
- GtkTreeSelection *selection;
GtkTreeView *view;
GtkWidget *view_widget;
-
- editor->model = gtk_tree_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+ GtkTreeModel *model;
- view_widget = gtk_tree_view_new_with_model (GTK_TREE_MODEL (editor->model));
+ editor->model = gtk_tree_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN);
+ model = GTK_TREE_MODEL (editor->model);
+
+ view_widget = gtk_tree_view_new_with_model (model);
view = GTK_TREE_VIEW (view_widget);
/* the view now holds a reference, we can get rid of our own */
g_object_unref (G_OBJECT (editor->model));
- glade_signal_editor_append_column (view, 0, _("Signal"));
- glade_signal_editor_append_column (view, 1, _("Handler"));
- glade_signal_editor_append_column (view, 2, _("After"));
-
- selection = gtk_tree_view_get_selection (view);
- gtk_tree_selection_set_select_function (selection,
- (GtkTreeSelectionFunc) glade_signal_editor_list_select_cb,
- editor, NULL);
-
- return view_widget;
-}
-
-static void
-glade_signal_editor_table_append_label (GtkWidget *table, const gchar *name, gint pos)
-{
- GtkWidget *label;
-
- label = gtk_label_new (name);
- gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
- gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, pos, pos + 1);
-}
-
-static GtkWidget *
-glade_signal_editor_table_append_entry (GtkWidget *table,
- GtkWidget *hbox,
- gint pos)
-{
- GtkWidget *entry;
-
- entry = gtk_entry_new ();
- gtk_box_pack_start_defaults (GTK_BOX (hbox), entry);
- gtk_table_attach_defaults (GTK_TABLE (table), hbox, 1, 2, pos, pos + 1);
+ /* signal column */
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (G_OBJECT (renderer), "editable", TRUE, NULL);
+ column = gtk_tree_view_column_new_with_attributes (_("Signal"), renderer, "text", COLUMN_SIGNAL, NULL);
+ gtk_tree_view_append_column (view, column);
- return entry;
-}
+ /* handler column */
+ renderer = gtk_cell_renderer_text_new ();
+ g_object_set (G_OBJECT (renderer), "editable", TRUE, "style", PANGO_STYLE_ITALIC, "foreground", "Gray", NULL);
+ g_signal_connect (renderer, "edited", G_CALLBACK (cell_edited), editor);
+ column = gtk_tree_view_column_new_with_attributes (_("Handler"), renderer, "text", COLUMN_HANDLER, "style_set", COLUMN_SLOT, "foreground_set", COLUMN_SLOT, NULL);
+ gtk_tree_view_append_column (view, column);
-static GtkWidget *
-glade_signal_editor_construct_table (GladeSignalEditor *editor)
-{
- GtkWidget *table;
- GtkWidget *hbox;
- GtkWidget *button;
-
- table = gtk_table_new (3, 2, FALSE);
-
- glade_signal_editor_table_append_label (table, _("Signal :"), 0);
- glade_signal_editor_table_append_label (table, _("Handler :"), 1);
- glade_signal_editor_table_append_label (table, _("After :"), 2);
-
- hbox = gtk_hbox_new (FALSE, 0);
- editor->signal_name_entry =
- glade_signal_editor_table_append_entry (table, hbox, 0);
-
- /* The "..." button */
- button = gtk_button_new_with_label ("...");
- g_signal_connect (G_OBJECT (button), "clicked",
- G_CALLBACK (glade_signal_editor_dialog_cb), editor);
- gtk_box_pack_start_defaults (GTK_BOX (hbox), button);
-
- hbox = gtk_hbox_new (FALSE, 0);
- editor->signal_handler_entry =
- glade_signal_editor_table_append_entry (table, hbox, 1);
-
- /* The Yes/No button */
- hbox = gtk_hbox_new (FALSE, 0);
- button = gtk_toggle_button_new_with_label (_("No"));
- g_signal_connect (G_OBJECT (button), "toggled",
- G_CALLBACK (glade_signal_editor_after_cb), editor);
- gtk_box_pack_start_defaults (GTK_BOX (hbox), button);
- gtk_table_attach_defaults (GTK_TABLE (table), hbox, 1, 2, 2, 3);
- editor->signal_after_button = button;
-
- return table;
-}
+ /* after column */
+ renderer = gtk_cell_renderer_toggle_new ();
+ g_signal_connect (renderer, "toggled", G_CALLBACK (after_toggled), editor);
+ column = gtk_tree_view_column_new_with_attributes (_("After"), renderer, "active", COLUMN_AFTER, "visible", COLUMN_VISIBLE, NULL);
+ gtk_tree_view_append_column (view, column);
-static GtkWidget *
-glade_signal_editor_construct_buttons (GladeSignalEditor *editor)
-{
- GtkWidget *hbuttonbox;
-
- hbuttonbox = gtk_hbutton_box_new ();
-
- editor->add_button = gtk_button_new_from_stock (GTK_STOCK_ADD);
- editor->update_button = gtk_button_new_with_mnemonic (_("_Update"));
- editor->remove_button = gtk_button_new_from_stock (GTK_STOCK_REMOVE);
- editor->clear_button = gtk_button_new_from_stock (GTK_STOCK_CLEAR);
-
- g_signal_connect (G_OBJECT (editor->add_button), "clicked",
- G_CALLBACK (glade_signal_editor_add_cb), editor);
- g_signal_connect (G_OBJECT (editor->update_button), "clicked",
- G_CALLBACK (glade_signal_editor_update_cb), editor);
- g_signal_connect (G_OBJECT (editor->remove_button), "clicked",
- G_CALLBACK (glade_signal_editor_remove_cb), editor);
- g_signal_connect (G_OBJECT (editor->clear_button), "clicked",
- G_CALLBACK (glade_signal_editor_clear_cb), editor);
-
- gtk_container_add (GTK_CONTAINER (hbuttonbox), editor->add_button);
- gtk_container_add (GTK_CONTAINER (hbuttonbox), editor->update_button);
- gtk_container_add (GTK_CONTAINER (hbuttonbox), editor->remove_button);
- gtk_container_add (GTK_CONTAINER (hbuttonbox), editor->clear_button);
-
- return hbuttonbox;
+ return view_widget;
}
static void
glade_signal_editor_construct (GladeSignalEditor *editor)
{
GtkWidget *vbox;
- GtkWidget *hbox;
GtkWidget *scroll;
- GtkWidget *table;
vbox = gtk_vbox_new (FALSE, 0);
editor->main_window = vbox;
@@ -604,12 +258,6 @@ glade_signal_editor_construct (GladeSignalEditor *editor)
gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
- table = glade_signal_editor_construct_table (editor);
- gtk_box_pack_start (GTK_BOX (vbox), table, FALSE, FALSE, 0);
-
- hbox = glade_signal_editor_construct_buttons (editor);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
-
gtk_widget_show_all (editor->main_window);
}
@@ -640,6 +288,12 @@ glade_signal_editor_load_widget (GladeSignalEditor *editor,
GladeWidget *widget)
{
GList *list;
+ const char *last_type = "";
+ GtkTreeIter iter;
+ GtkTreeIter parent_class;
+ GtkTreeIter parent_signal;
+ GtkTreePath *path_first;
+ GList *signals;
g_return_if_fail (GLADE_IS_SIGNAL_EDITOR (editor));
g_return_if_fail (widget == NULL || GLADE_IS_WIDGET (widget));
@@ -649,17 +303,55 @@ glade_signal_editor_load_widget (GladeSignalEditor *editor,
editor->widget = widget;
editor->class = widget ? widget->class : NULL;
- glade_signal_editor_clear_entries (editor);
-
if (!widget)
return;
- for (list = widget->signals; list; list = list->next)
+ for (list = editor->class->signals; list; list = list->next)
{
- GladeSignal *signal;
+ GladeWidgetClassSignal *signal = (GladeWidgetClassSignal *) list->data;
+
+ if (strcmp(last_type, signal->type))
+ {
+ gtk_tree_store_append (editor->model, &parent_class, NULL);
+ gtk_tree_store_set (editor->model, &parent_class, COLUMN_SIGNAL, signal->type, COLUMN_VISIBLE, FALSE, COLUMN_SLOT, FALSE, -1);
+ last_type = signal->type;
+ }
- signal = list->data;
- glade_signal_editor_update_signal_view (editor, signal, NULL);
+ gtk_tree_store_append (editor->model, &parent_signal, &parent_class);
+ signals = glade_widget_find_signals_by_name (widget, signal->name);
+
+ if (!signals)
+ gtk_tree_store_set (editor->model, &parent_signal,
+ COLUMN_SIGNAL, signal->name,
+ COLUMN_HANDLER, _("<Type the signal's handler here>"),
+ COLUMN_AFTER, FALSE,
+ COLUMN_VISIBLE, FALSE,
+ COLUMN_SLOT, TRUE, -1);
+ else
+ {
+ GladeSignal *widget_signal = (GladeSignal*) signals->data;
+
+ gtk_tree_store_set (editor->model, &parent_signal,
+ COLUMN_SIGNAL, signal->name,
+ COLUMN_HANDLER, widget_signal->handler,
+ COLUMN_AFTER, widget_signal->after,
+ COLUMN_VISIBLE, TRUE,
+ COLUMN_SLOT, FALSE, -1);
+ for (signals = signals->next; signals; signals = signals->next)
+ {
+ widget_signal = (GladeSignal*) signals->data;
+ gtk_tree_store_append (editor->model, &iter, &parent_signal);
+ gtk_tree_store_set (editor->model, &iter,
+ COLUMN_HANDLER, widget_signal->handler,
+ COLUMN_AFTER, widget_signal->after,
+ COLUMN_VISIBLE, TRUE,
+ COLUMN_SLOT, FALSE, -1);
+ }
+ }
}
+
+ path_first = gtk_tree_path_new_first ();
+ gtk_tree_view_expand_row (GTK_TREE_VIEW (editor->signals_list), path_first, FALSE);
+ gtk_tree_path_free (path_first);
}
diff --git a/src/glade-signal-editor.h b/src/glade-signal-editor.h
index 5c1a3191..7028b7f1 100644
--- a/src/glade-signal-editor.h
+++ b/src/glade-signal-editor.h
@@ -22,16 +22,7 @@ struct _GladeSignalEditor
GtkWidget *signals_list;
GtkTreeStore *model;
-
- GtkWidget *signal_name_entry;
- GtkWidget *signal_handler_entry;
- GtkWidget *signal_after_button;
-
- /* Buttons */
- GtkWidget *add_button;
- GtkWidget *update_button;
- GtkWidget *remove_button;
- GtkWidget *clear_button;
+ GtkTreeView *tree_view;
};
diff --git a/src/glade-signal.c b/src/glade-signal.c
index 05f97def..268523d8 100644
--- a/src/glade-signal.c
+++ b/src/glade-signal.c
@@ -66,6 +66,12 @@ glade_signal_compare (GladeSignal *sig1, GladeSignal *sig2)
return ret;
}
+GladeSignal *
+glade_signal_copy (GladeSignal *signal)
+{
+ return glade_signal_new (signal->name, signal->handler, signal->after);
+}
+
GladeXmlNode *
glade_signal_write (GladeXmlContext *context, GladeSignal *signal)
{
diff --git a/src/glade-signal.h b/src/glade-signal.h
index 6a95bbbc..583422f1 100644
--- a/src/glade-signal.h
+++ b/src/glade-signal.h
@@ -19,7 +19,7 @@ struct _GladeSignal
GladeSignal *glade_signal_new (const gchar *name,
const gchar *handler,
gboolean after);
-
+GladeSignal *glade_signal_copy (GladeSignal *signal);
void glade_signal_free (GladeSignal *signal);
gboolean glade_signal_compare (GladeSignal *sig1, GladeSignal *sig2);
diff --git a/src/glade-widget.c b/src/glade-widget.c
index 5e7fdaaf..93e4b496 100644
--- a/src/glade-widget.c
+++ b/src/glade-widget.c
@@ -104,7 +104,7 @@ glade_widget_new (GladeWidgetClass *class, GladeProject *project)
widget->properties = glade_widget_properties_from_list (class->properties, widget);
/* we don't have packing properties until we container add the widget */
widget->packing_properties = NULL;
- widget->signals = NULL;
+ widget->signals = g_hash_table_new (g_str_hash, g_str_equal);
return widget;
}
@@ -435,6 +435,20 @@ glade_widget_connect_other_signals (GladeWidget *widget)
}
}
+static gboolean
+glade_widget_free_signals (gpointer key, gpointer value, gpointer user_data)
+{
+ GList *signals = (GList*) value;
+
+ if (signals)
+ {
+ g_list_foreach (signals, (GFunc) glade_signal_free, NULL);
+ g_list_free (signals);
+ }
+
+ return TRUE;
+}
+
/**
* Free the GladeWidget associated to a widget. Note that this is
* connected to the destroy event of the corresponding GtkWidget so
@@ -457,8 +471,7 @@ glade_widget_free (GladeWidget *widget)
g_list_free (widget->properties);
g_list_foreach(widget->packing_properties, (GFunc) glade_property_free, NULL);
g_list_free (widget->packing_properties);
- g_list_foreach(widget->signals, (GFunc) glade_signal_free, NULL);
- g_list_free (widget->signals);
+ g_hash_table_foreach_remove (widget->signals, (GHRFunc) glade_widget_free_signals, NULL);
g_free (widget);
}
@@ -1027,6 +1040,12 @@ glade_widget_replace_with_placeholder (GladeWidget *widget,
}
}
+GList *
+glade_widget_find_signals_by_name (GladeWidget *widget, const char *name)
+{
+ return g_hash_table_lookup (widget->signals, name);
+}
+
/**
* glade_widget_find_signal:
* @widget
@@ -1040,10 +1059,11 @@ glade_widget_find_signal (GladeWidget *widget, GladeSignal *signal)
{
GList *list;
- for (list = widget->signals; list; list = list->next) {
- GladeSignal *tmp = GLADE_SIGNAL (list->data);
- if (glade_signal_compare (tmp, signal))
- return list;
+ for (list = glade_widget_find_signals_by_name (widget, signal->name);
+ list; list = list->next)
+ {
+ if (glade_signal_compare (GLADE_SIGNAL (list->data), signal))
+ return list;
}
/* not found... */
@@ -1061,17 +1081,26 @@ void
glade_widget_add_signal (GladeWidget *widget, GladeSignal *signal)
{
GList *found;
+ GList *old_signals;
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_return_if_fail (GLADE_IS_SIGNAL (signal));
found = glade_widget_find_signal (widget, signal);
- if (found) {
+ if (found)
+ {
glade_signal_free (signal);
return;
}
- widget->signals = g_list_append (widget->signals, signal);
+ old_signals = glade_widget_find_signals_by_name (widget, signal->name);
+ if (old_signals)
+ {
+ g_hash_table_insert (widget->signals, signal->name, g_list_append (old_signals, signal));
+ return;
+ }
+
+ g_hash_table_insert(widget->signals, signal->name, g_list_append (NULL, signal));
return;
}
@@ -1086,26 +1115,54 @@ void
glade_widget_remove_signal (GladeWidget *widget, GladeSignal *signal)
{
GList *found;
+ char *signal_name;
g_return_if_fail (GLADE_IS_WIDGET (widget));
g_return_if_fail (GLADE_IS_SIGNAL (signal));
+ signal_name = g_strdup (signal->name);
found = glade_widget_find_signal (widget, signal);
- if (found) {
- g_list_remove_link (widget->signals, found);
+ if (found)
+ {
glade_signal_free (GLADE_SIGNAL (found->data));
- g_list_free_1 (found);
+ g_hash_table_insert (widget->signals, signal_name, g_list_delete_link (found, found));
}
+ g_free (signal_name);
}
static GladeXmlNode *
glade_widget_write_child (GladeXmlContext *context, GtkWidget *gtk_widget);
+typedef struct _WriteSignalsContext
+{
+ GladeXmlContext *context;
+ GladeXmlNode *node;
+} WriteSignalsContext;
+
+static void
+glade_widget_write_signals (gpointer key, gpointer value, gpointer user_data)
+{
+ WriteSignalsContext *write_signals_context = (WriteSignalsContext *) user_data;
+ GladeXmlNode *child;
+
+ GList *list = (GList *) value;
+ for (; list; list = list->next)
+ {
+ GladeSignal *signal = list->data;
+ child = glade_signal_write (write_signals_context->context, signal);
+ if (!child)
+ continue;
+
+ glade_xml_node_append_child (write_signals_context->node, child);
+ }
+}
+
GladeXmlNode *
glade_widget_write (GladeXmlContext *context, GladeWidget *widget)
{
GladeXmlNode *node;
GladeXmlNode *child;
+ WriteSignalsContext write_signals_context;
GList *list;
g_return_val_if_fail (GLADE_XML_IS_CONTEXT (context), NULL);
@@ -1130,15 +1187,9 @@ glade_widget_write (GladeXmlContext *context, GladeWidget *widget)
}
/* Signals */
- list = widget->signals;
- for (; list; list = list->next) {
- GladeSignal *signal = list->data;
- child = glade_signal_write (context, signal);
- if (!child) {
- continue;
- }
- glade_xml_node_append_child (node, child);
- }
+ write_signals_context.node = node;
+ write_signals_context.context = context;
+ g_hash_table_foreach (widget->signals, glade_widget_write_signals, &write_signals_context);
/* Children */
if (GTK_IS_CONTAINER (widget->widget)) {
diff --git a/src/glade-widget.h b/src/glade-widget.h
index 67642392..51eee0c3 100644
--- a/src/glade-widget.h
+++ b/src/glade-widget.h
@@ -58,7 +58,7 @@ struct _GladeWidget
* GladeWidgetClass.
*/
- GList *signals; /* A list of GladeSignals */
+ GHashTable *signals; /* A table with a list of GladeSignals, indexed by its name */
};
@@ -101,6 +101,7 @@ GladeWidget *glade_widget_get_parent (GladeWidget *widget);
/* Widget signal*/
GList *glade_widget_find_signal (GladeWidget *widget, GladeSignal *signal);
+GList *glade_widget_find_signals_by_name (GladeWidget *widget, const char *name);
void glade_widget_add_signal (GladeWidget *widget, GladeSignal *signal);
void glade_widget_remove_signal (GladeWidget *widget, GladeSignal *signal);