#define GET_PRIV(obj) EMPATHY_GET_PRIV (obj, EmpathyDebugDialog)
typedef struct
{
- GtkWidget *filter;
- GtkWidget *view;
+ /* Toolbar items */
GtkWidget *cm_chooser;
+ GtkToolItem *save_button;
+ GtkToolItem *copy_button;
+ GtkToolItem *clear_button;
+ GtkToolItem *pause_button;
+ GtkToolItem *level_label;
+ GtkWidget *level_filter;
+
+ /* TreeView */
GtkListStore *store;
GtkTreeModel *store_filter;
+ GtkWidget *view;
+ GtkWidget *scrolled_win;
+ GtkWidget *not_supported_label;
+ gboolean view_visible;
+
+ /* Connection */
+ TpDBusDaemon *dbus;
TpProxy *proxy;
- TpProxySignalConnection *signal_connection;
+ TpProxySignalConnection *new_debug_message_signal;
+ TpProxySignalConnection *name_owner_changed_signal;
+
+ /* Whether NewDebugMessage will be fired */
gboolean paused;
+
+ /* CM chooser store */
GtkListStore *cms;
+
+ /* Misc. */
gboolean dispose_run;
} EmpathyDebugDialogPriv;
tp_g_value_slice_free (val);
}
+static void
+debug_dialog_set_toolbar_sensitivity (EmpathyDebugDialog *debug_dialog,
+ gboolean sensitive)
+{
+ EmpathyDebugDialogPriv *priv = GET_PRIV (debug_dialog);
+ GtkWidget *vbox = GTK_DIALOG (debug_dialog)->vbox;
+
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->save_button), sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->copy_button), sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->clear_button), sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->pause_button), sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->level_label), sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->level_filter), sensitive);
+ gtk_widget_set_sensitive (GTK_WIDGET (priv->view), sensitive);
+
+ if (sensitive && !priv->view_visible)
+ {
+ /* Add view and remove label */
+ gtk_container_remove (GTK_CONTAINER (vbox), priv->not_supported_label);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->scrolled_win, TRUE, TRUE, 0);
+ priv->view_visible = TRUE;
+ }
+ else if (!sensitive && priv->view_visible)
+ {
+ /* Add label and remove view */
+ gtk_container_remove (GTK_CONTAINER (vbox), priv->scrolled_win);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->not_supported_label,
+ TRUE, TRUE, 0);
+ priv->view_visible = FALSE;
+ }
+}
+
static void
debug_dialog_get_messages_cb (TpProxy *proxy,
const GPtrArray *messages,
if (error != NULL)
{
DEBUG ("GetMessages failed: %s", error->message);
+ debug_dialog_set_toolbar_sensitivity (debug_dialog, FALSE);
return;
}
+ debug_dialog_set_toolbar_sensitivity (debug_dialog, TRUE);
+
for (i = 0; i < messages->len; i++)
{
GValueArray *values = g_ptr_array_index (messages, i);
}
/* Connect to NewDebugMessage */
- priv->signal_connection = emp_cli_debug_connect_to_new_debug_message (
+ priv->new_debug_message_signal = emp_cli_debug_connect_to_new_debug_message (
proxy, debug_dialog_new_debug_message_cb, debug_dialog,
NULL, NULL, NULL);
TpDBusDaemon *dbus;
GError *error = NULL;
gchar *bus_name;
- TpConnection *connection;
+ TpProxy *proxy;
GtkTreeIter iter;
if (!gtk_combo_box_get_active_iter (cm_chooser, &iter))
{
DEBUG ("No CM is selected");
+ if (gtk_tree_model_iter_n_children (
+ GTK_TREE_MODEL (priv->cms), NULL) > 0)
+ {
+ gtk_combo_box_set_active (cm_chooser, 0);
+ }
return;
}
gtk_tree_model_get (GTK_TREE_MODEL (priv->cms), &iter,
COL_CM_UNIQUE_NAME, &bus_name, -1);
- connection = tp_connection_new (dbus, bus_name, DEBUG_OBJECT_PATH, &error);
+ proxy = g_object_new (TP_TYPE_PROXY,
+ "bus-name", bus_name,
+ "dbus-daemon", dbus,
+ "object-path", DEBUG_OBJECT_PATH,
+ NULL);
g_free (bus_name);
- if (error != NULL)
- {
- DEBUG ("Getting a new TpConnection failed: %s", error->message);
- g_error_free (error);
- g_object_unref (dbus);
- g_object_unref (mc);
- return;
- }
-
gtk_list_store_clear (priv->store);
/* Disable debug signalling */
debug_dialog_set_enabled (debug_dialog, FALSE);
/* Disconnect from previous NewDebugMessage signal */
- if (priv->signal_connection != NULL)
+ if (priv->new_debug_message_signal != NULL)
{
- tp_proxy_signal_connection_disconnect (priv->signal_connection);
- priv->signal_connection = NULL;
+ tp_proxy_signal_connection_disconnect (priv->new_debug_message_signal);
+ priv->new_debug_message_signal = NULL;
}
if (priv->proxy != NULL)
g_object_unref (priv->proxy);
- priv->proxy = TP_PROXY (connection);
+ priv->proxy = proxy;
tp_proxy_add_interface_by_id (priv->proxy, emp_iface_quark_debug ());
COL_CM_NAME, data->cm_name,
COL_CM_UNIQUE_NAME, out,
-1);
-
- gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cm_chooser), 0);
}
OUT:
if (error2 != NULL)
{
DEBUG ("Failed to dup TpDBusDaemon.");
+ g_error_free (error2);
return;
}
g_object_unref (dbus);
}
+static gboolean
+debug_dialog_remove_cm_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ const gchar *unique_name_to_remove = (const gchar *) user_data;
+ gchar *name;
+ gboolean found = FALSE;
+
+ gtk_tree_model_get (model, iter, COL_CM_UNIQUE_NAME, &name, -1);
+
+ if (!tp_strdiff (name, unique_name_to_remove))
+ {
+ found = TRUE;
+ gtk_list_store_remove (GTK_LIST_STORE (model), iter);
+ }
+
+ g_free (name);
+
+ return found;
+}
+
+#define CM_WELL_KNOWN_NAME_PREFIX \
+ "org.freedesktop.Telepathy.ConnectionManager."
+
+static void
+debug_dialog_name_owner_changed_cb (TpDBusDaemon *proxy,
+ const gchar *arg0,
+ const gchar *arg1,
+ const gchar *arg2,
+ gpointer user_data,
+ GObject *weak_object)
+{
+ EmpathyDebugDialogPriv *priv = GET_PRIV (user_data);
+
+ /* Wow, I hate all of this code... */
+ if (!g_str_has_prefix (arg0, CM_WELL_KNOWN_NAME_PREFIX))
+ return;
+
+ if (EMP_STR_EMPTY (arg1) && !EMP_STR_EMPTY (arg2))
+ {
+ /* A connection manager joined -- because it's guaranteed
+ * that the CM just joined (because o.fd.Tp.CM.foo
+ * just joined), we don't need to check whether the unique
+ * name is in the CM model. Hooray.
+ */
+ GtkTreeIter iter;
+ const gchar *name = arg0 + strlen (CM_WELL_KNOWN_NAME_PREFIX);
+
+ DEBUG ("Adding new CM '%s' at %s.", name, arg2);
+
+ gtk_list_store_append (priv->cms, &iter);
+ gtk_list_store_set (priv->cms, &iter,
+ COL_CM_NAME, name,
+ COL_CM_UNIQUE_NAME, arg2,
+ -1);
+ }
+ else if (!EMP_STR_EMPTY (arg1) && EMP_STR_EMPTY (arg2))
+ {
+ /* A connection manager died -- because it's guaranteed
+ * that the CM itself just died (because o.fd.Tp.CM.foo
+ * just died), we don't need to check that it was already
+ * in the model.
+ */
+ gchar *to_remove;
+
+ /* Can't pass a const into a GtkTreeModelForeachFunc. */
+ to_remove = g_strdup (arg1);
+
+ DEBUG ("Removing CM from %s.", to_remove);
+
+ gtk_tree_model_foreach (GTK_TREE_MODEL (priv->cms),
+ debug_dialog_remove_cm_foreach, to_remove);
+
+ g_free (to_remove);
+ }
+}
+
static void
debug_dialog_fill_cm_chooser (EmpathyDebugDialog *debug_dialog)
{
- TpDBusDaemon *dbus;
+ EmpathyDebugDialogPriv *priv = GET_PRIV (debug_dialog);
GError *error = NULL;
+ GtkTreeIter iter;
- dbus = tp_dbus_daemon_dup (&error);
+ priv->dbus = tp_dbus_daemon_dup (&error);
if (error != NULL)
{
return;
}
- tp_list_connection_names (dbus, debug_dialog_list_connection_names_cb,
+ /* Add empathy */
+ gtk_list_store_append (priv->cms, &iter);
+ gtk_list_store_set (priv->cms, &iter,
+ COL_CM_NAME, "empathy",
+ COL_CM_UNIQUE_NAME, "org.gnome.Empathy",
+ -1);
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cm_chooser), 0);
+
+ /* Add CMs to list */
+ tp_list_connection_names (priv->dbus, debug_dialog_list_connection_names_cb,
debug_dialog, NULL, NULL);
- g_object_unref (dbus);
+ priv->name_owner_changed_signal =
+ tp_cli_dbus_daemon_connect_to_name_owner_changed (priv->dbus,
+ debug_dialog_name_owner_changed_cb, debug_dialog, NULL, NULL, NULL);
}
static void
GtkTreeModel *filter_model;
GtkTreeIter filter_iter;
- filter_model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->filter));
- gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->filter),
+ filter_model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->level_filter));
+ gtk_combo_box_get_active_iter (GTK_COMBO_BOX (priv->level_filter),
&filter_iter);
gtk_tree_model_get (model, iter, COL_DEBUG_LEVEL_VALUE, &level, -1);
gtk_widget_show (file_chooser);
}
+static gboolean
+debug_dialog_copy_model_foreach (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gpointer user_data)
+{
+ gchar **text = (gchar **) user_data;
+ gchar *tmp;
+ gchar *domain, *category, *message, *level_str, *level_upper;
+ gdouble timestamp;
+ gchar *line;
+
+ gtk_tree_model_get (model, iter,
+ COL_DEBUG_TIMESTAMP, ×tamp,
+ COL_DEBUG_DOMAIN, &domain,
+ COL_DEBUG_CATEGORY, &category,
+ COL_DEBUG_LEVEL_STRING, &level_str,
+ COL_DEBUG_MESSAGE, &message,
+ -1);
+
+ level_upper = g_ascii_strup (level_str, -1);
+
+ line = g_strdup_printf ("%s%s%s-%s: %e: %s\n",
+ domain, EMP_STR_EMPTY (category) ? "" : "/",
+ category, level_upper, timestamp, message);
+
+ tmp = g_strconcat (*text, line, NULL);
+
+ g_free (*text);
+ g_free (line);
+ g_free (level_upper);
+ g_free (level_str);
+ g_free (domain);
+ g_free (category);
+ g_free (message);
+
+ *text = tmp;
+
+ return FALSE;
+}
+
+static void
+debug_dialog_copy_clicked_cb (GtkToolButton *tool_button,
+ EmpathyDebugDialog *debug_dialog)
+{
+ EmpathyDebugDialogPriv *priv = GET_PRIV (debug_dialog);
+ GtkClipboard *clipboard;
+ gchar *text;
+
+ text = g_strdup ("");
+
+ gtk_tree_model_foreach (priv->store_filter,
+ debug_dialog_copy_model_foreach, &text);
+
+ clipboard = gtk_clipboard_get_for_display (
+ gtk_widget_get_display (GTK_WIDGET (tool_button)),
+ GDK_SELECTION_CLIPBOARD);
+
+ DEBUG ("Copying text to clipboard (length: %" G_GSIZE_FORMAT ")",
+ strlen (text));
+
+ gtk_clipboard_set_text (clipboard, text, -1);
+
+ g_free (text);
+}
+
static GObject *
debug_dialog_constructor (GType type,
guint n_construct_params,
GtkWidget *label;
GtkToolItem *item;
GtkCellRenderer *renderer;
- GtkWidget *scrolled_win;
GtkListStore *level_store;
GtkTreeIter iter;
gtk_widget_show (GTK_WIDGET (item));
gtk_container_add (GTK_CONTAINER (item), priv->cm_chooser);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
- debug_dialog_fill_cm_chooser (EMPATHY_DEBUG_DIALOG (object));
g_signal_connect (priv->cm_chooser, "changed",
G_CALLBACK (debug_dialog_cm_chooser_changed_cb), object);
gtk_widget_show (GTK_WIDGET (priv->cm_chooser));
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
/* Save */
- item = gtk_tool_button_new_from_stock (GTK_STOCK_SAVE);
- g_signal_connect (item, "clicked",
+ priv->save_button = gtk_tool_button_new_from_stock (GTK_STOCK_SAVE);
+ g_signal_connect (priv->save_button, "clicked",
G_CALLBACK (debug_dialog_save_clicked_cb), object);
- gtk_widget_show (GTK_WIDGET (item));
- gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+ gtk_widget_show (GTK_WIDGET (priv->save_button));
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->save_button), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->save_button, -1);
+
+ /* Copy */
+ priv->copy_button = gtk_tool_button_new_from_stock (GTK_STOCK_COPY);
+ g_signal_connect (priv->copy_button, "clicked",
+ G_CALLBACK (debug_dialog_copy_clicked_cb), object);
+ gtk_widget_show (GTK_WIDGET (priv->copy_button));
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->copy_button), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->copy_button, -1);
/* Clear */
- item = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR);
- g_signal_connect (item, "clicked",
+ priv->clear_button = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR);
+ g_signal_connect (priv->clear_button, "clicked",
G_CALLBACK (debug_dialog_clear_clicked_cb), object);
- gtk_widget_show (GTK_WIDGET (item));
- gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+ gtk_widget_show (GTK_WIDGET (priv->clear_button));
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->clear_button), TRUE);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->clear_button, -1);
item = gtk_separator_tool_item_new ();
gtk_widget_show (GTK_WIDGET (item));
image = gtk_image_new_from_stock (GTK_STOCK_MEDIA_PAUSE,
GTK_ICON_SIZE_MENU);
gtk_widget_show (image);
- item = gtk_toggle_tool_button_new ();
- gtk_toggle_tool_button_set_active (GTK_TOGGLE_TOOL_BUTTON (item),
- priv->paused);
- g_signal_connect (item, "toggled",
+ priv->pause_button = gtk_toggle_tool_button_new ();
+ gtk_toggle_tool_button_set_active (
+ GTK_TOGGLE_TOOL_BUTTON (priv->pause_button), priv->paused);
+ g_signal_connect (priv->pause_button, "toggled",
G_CALLBACK (debug_dialog_pause_toggled_cb), object);
- gtk_widget_show (GTK_WIDGET (item));
- gtk_tool_item_set_is_important (GTK_TOOL_ITEM (item), TRUE);
- gtk_tool_button_set_label (GTK_TOOL_BUTTON (item), _("Pause"));
- gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (item), image);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+ gtk_widget_show (GTK_WIDGET (priv->pause_button));
+ gtk_tool_item_set_is_important (GTK_TOOL_ITEM (priv->pause_button), TRUE);
+ gtk_tool_button_set_label (GTK_TOOL_BUTTON (priv->pause_button), _("Pause"));
+ gtk_tool_button_set_icon_widget (
+ GTK_TOOL_BUTTON (priv->pause_button), image);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->pause_button, -1);
item = gtk_separator_tool_item_new ();
gtk_widget_show (GTK_WIDGET (item));
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
/* Level */
- item = gtk_tool_item_new ();
- gtk_widget_show (GTK_WIDGET (item));
+ priv->level_label = gtk_tool_item_new ();
+ gtk_widget_show (GTK_WIDGET (priv->level_label));
label = gtk_label_new (_("Level "));
gtk_widget_show (label);
- gtk_container_add (GTK_CONTAINER (item), label);
- gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+ gtk_container_add (GTK_CONTAINER (priv->level_label), label);
+ gtk_toolbar_insert (GTK_TOOLBAR (toolbar), priv->level_label, -1);
- priv->filter = gtk_combo_box_new_text ();
- gtk_widget_show (priv->filter);
+ priv->level_filter = gtk_combo_box_new_text ();
+ gtk_widget_show (priv->level_filter);
item = gtk_tool_item_new ();
gtk_widget_show (GTK_WIDGET (item));
- gtk_container_add (GTK_CONTAINER (item), priv->filter);
+ gtk_container_add (GTK_CONTAINER (item), priv->level_filter);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
level_store = gtk_list_store_new (NUM_COLS_LEVEL,
G_TYPE_STRING, G_TYPE_UINT);
- gtk_combo_box_set_model (GTK_COMBO_BOX (priv->filter),
+ gtk_combo_box_set_model (GTK_COMBO_BOX (priv->level_filter),
GTK_TREE_MODEL (level_store));
gtk_list_store_append (level_store, &iter);
COL_LEVEL_VALUE, EMP_DEBUG_LEVEL_ERROR,
-1);
- gtk_combo_box_set_active (GTK_COMBO_BOX (priv->filter), 0);
- g_signal_connect (priv->filter, "changed",
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->level_filter), 0);
+ g_signal_connect (priv->level_filter, "changed",
G_CALLBACK (debug_dialog_filter_changed_cb), object);
/* Debug treeview */
gtk_tree_view_set_model (GTK_TREE_VIEW (priv->view), priv->store_filter);
/* Scrolled window */
- scrolled_win = gtk_scrolled_window_new (NULL, NULL);
- gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
+ priv->scrolled_win = g_object_ref (gtk_scrolled_window_new (NULL, NULL));
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_win),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_widget_show (priv->view);
- gtk_container_add (GTK_CONTAINER (scrolled_win), priv->view);
+ gtk_container_add (GTK_CONTAINER (priv->scrolled_win), priv->view);
+
+ gtk_widget_show (priv->scrolled_win);
- gtk_widget_show (scrolled_win);
- gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
+ /* Not supported label */
+ priv->not_supported_label = g_object_ref (gtk_label_new (
+ _("The selected connection manager does not support the remote "
+ "debugging extension.")));
+ gtk_widget_show (priv->not_supported_label);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->not_supported_label, TRUE, TRUE, 0);
+ priv->view_visible = FALSE;
+
+ debug_dialog_set_toolbar_sensitivity (EMPATHY_DEBUG_DIALOG (object), FALSE);
+ debug_dialog_fill_cm_chooser (EMPATHY_DEBUG_DIALOG (object));
gtk_widget_show (GTK_WIDGET (object));
return object;
if (priv->store != NULL)
g_object_unref (priv->store);
+ if (priv->name_owner_changed_signal != NULL)
+ tp_proxy_signal_connection_disconnect (priv->name_owner_changed_signal);
+
if (priv->proxy != NULL)
{
debug_dialog_set_enabled (EMPATHY_DEBUG_DIALOG (object), FALSE);
g_object_unref (priv->proxy);
}
- if (priv->signal_connection != NULL)
- tp_proxy_signal_connection_disconnect (priv->signal_connection);
+ if (priv->new_debug_message_signal != NULL)
+ tp_proxy_signal_connection_disconnect (priv->new_debug_message_signal);
if (priv->cms != NULL)
g_object_unref (priv->cms);
+ if (priv->dbus != NULL)
+ g_object_unref (priv->dbus);
+
(G_OBJECT_CLASS (empathy_debug_dialog_parent_class)->dispose) (object);
}