]> git.0d.be Git - empathy.git/blobdiff - src/empathy-debug-window.c
Updated Polish translation
[empathy.git] / src / empathy-debug-window.c
index bdf215efb4c87fe117e3440fc8c730d0cf332231..6c0c9c69eecd8fc84da3d8e58aff44afb9258470 100644 (file)
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
 #include <gio/gio.h>
+#include <gdk/gdkkeysyms.h>
 
 #define DEBUG_FLAG EMPATHY_DEBUG_OTHER
 #include <libempathy/empathy-debug.h>
 #include <libempathy/empathy-utils.h>
 
 #include <libempathy-gtk/empathy-account-chooser.h>
+#include <libempathy-gtk/empathy-geometry.h>
 
 #include <telepathy-glib/dbus.h>
+#include <telepathy-glib/interfaces.h>
 #include <telepathy-glib/util.h>
 #include <telepathy-glib/proxy-subclass.h>
 
@@ -96,6 +99,7 @@ typedef struct
   TpProxy *proxy;
   TpProxySignalConnection *new_debug_message_signal;
   TpProxySignalConnection *name_owner_changed_signal;
+  gulong invalid_signal_id;
 
   /* Whether NewDebugMessage will be fired */
   gboolean paused;
@@ -112,23 +116,23 @@ log_level_to_string (guint level)
 {
   switch (level)
     {
-    case EMP_DEBUG_LEVEL_ERROR:
-      return _("Error");
+    case TP_DEBUG_LEVEL_ERROR:
+      return "Error";
       break;
-    case EMP_DEBUG_LEVEL_CRITICAL:
-      return _("Critical");
+    case TP_DEBUG_LEVEL_CRITICAL:
+      return "Critical";
       break;
-    case EMP_DEBUG_LEVEL_WARNING:
-      return _("Warning");
+    case TP_DEBUG_LEVEL_WARNING:
+      return "Warning";
       break;
-    case EMP_DEBUG_LEVEL_MESSAGE:
-      return _("Message");
+    case TP_DEBUG_LEVEL_MESSAGE:
+      return "Message";
       break;
-    case EMP_DEBUG_LEVEL_INFO:
-      return _("Info");
+    case TP_DEBUG_LEVEL_INFO:
+      return "Info";
       break;
-    case EMP_DEBUG_LEVEL_DEBUG:
-      return _("Debug");
+    case TP_DEBUG_LEVEL_DEBUG:
+      return "Debug";
       break;
     default:
       g_assert_not_reached ();
@@ -169,6 +173,15 @@ debug_message_free (DebugMessage *dm)
   g_slice_free (DebugMessage, dm);
 }
 
+static void
+debug_message_list_free (gpointer data)
+{
+  GList *list = data;
+
+  g_list_foreach (list, (GFunc) debug_message_free, NULL);
+  g_list_free (list);
+}
+
 static void
 debug_window_cache_new_message (EmpathyDebugWindow *debug_window,
     gdouble timestamp,
@@ -269,7 +282,7 @@ debug_window_set_enabled (EmpathyDebugWindow *debug_window,
 
   val = tp_g_value_slice_new_boolean (enabled);
 
-  tp_cli_dbus_properties_call_set (priv->proxy, -1, EMP_IFACE_DEBUG,
+  tp_cli_dbus_properties_call_set (priv->proxy, -1, TP_IFACE_DEBUG,
       "Enabled", val, NULL, NULL, NULL, NULL);
 
   tp_g_value_slice_free (val);
@@ -319,7 +332,7 @@ debug_window_get_messages_cb (TpProxy *proxy,
   GtkTreeIter iter;
   gchar *name;
   GList *old_messages;
-  gint i;
+  guint i;
 
   if (error != NULL)
     {
@@ -343,8 +356,7 @@ debug_window_get_messages_cb (TpProxy *proxy,
   if (old_messages != NULL)
     {
       g_hash_table_remove (priv->all_cms, name);
-      g_list_foreach (old_messages, (GFunc) debug_message_free, NULL);
-      g_list_free (old_messages);
+      debug_message_list_free (old_messages);
     }
 
   for (i = 0; i < messages->len; i++)
@@ -391,6 +403,19 @@ debug_window_add_log_messages_from_cache (EmpathyDebugWindow *debug_window,
     }
 }
 
+static void
+proxy_invalidated_cb (TpProxy *proxy,
+    guint domain,
+    gint code,
+    gchar *msg,
+    EmpathyDebugWindowPriv *self)
+{
+  EmpathyDebugWindowPriv *priv = GET_PRIV (self);
+
+  /* Proxy has been invalidated so we can't disconnect the signal any more */
+  priv->new_debug_message_signal = NULL;
+}
+
 static void
 debug_window_cm_chooser_changed_cb (GtkComboBox *cm_chooser,
     EmpathyDebugWindow *debug_window)
@@ -456,7 +481,10 @@ debug_window_cm_chooser_changed_cb (GtkComboBox *cm_chooser,
     }
 
   if (priv->proxy != NULL)
-    g_object_unref (priv->proxy);
+    {
+      g_signal_handler_disconnect (priv->proxy, priv->invalid_signal_id);
+      g_object_unref (priv->proxy);
+    }
 
   priv->proxy = proxy;
 
@@ -465,6 +493,9 @@ debug_window_cm_chooser_changed_cb (GtkComboBox *cm_chooser,
   emp_cli_debug_call_get_messages (priv->proxy, -1,
       debug_window_get_messages_cb, debug_window, NULL, NULL);
 
+  priv->invalid_signal_id = g_signal_connect (proxy, "invalidated",
+      G_CALLBACK (proxy_invalidated_cb), debug_window);
+
   g_object_unref (dbus);
 }
 
@@ -639,11 +670,11 @@ debug_window_name_owner_changed_cb (TpDBusDaemon *proxy,
        * 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);
 
       if (!g_hash_table_lookup (priv->all_cms, name))
         {
+          GtkTreeIter iter;
           DEBUG ("Adding new CM '%s' at %s.", name, arg2);
 
           gtk_list_store_append (priv->cms, &iter);
@@ -715,8 +746,8 @@ debug_window_fill_cm_chooser (EmpathyDebugWindow *debug_window)
   /* 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",
+      COL_CM_NAME, _(PACKAGE_NAME),
+      COL_CM_UNIQUE_NAME, "org.gnome."PACKAGE_NAME,
       -1);
   gtk_combo_box_set_active (GTK_COMBO_BOX (priv->cm_chooser), 0);
 
@@ -724,6 +755,13 @@ debug_window_fill_cm_chooser (EmpathyDebugWindow *debug_window)
   tp_list_connection_names (priv->dbus, debug_window_list_connection_names_cb,
       debug_window, NULL, NULL);
 
+  /* add Mission Control */
+  gtk_list_store_append (priv->cms, &iter);
+  gtk_list_store_set (priv->cms, &iter,
+      COL_CM_NAME, "misson-control",
+      COL_CM_UNIQUE_NAME, "org.freedesktop.Telepathy.MissionControl5",
+      -1);
+
   priv->name_owner_changed_signal =
       tp_cli_dbus_daemon_connect_to_name_owner_changed (priv->dbus,
       debug_window_name_owner_changed_cb, debug_window, NULL, NULL, NULL);
@@ -852,6 +890,8 @@ debug_window_show_menu (gpointer user_data)
 
   gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
      data->button, data->time);
+  g_object_ref_sink (menu);
+  g_object_unref (menu);
 
   g_slice_free (MenuPopupData, user_data);
 
@@ -879,6 +919,48 @@ debug_window_button_press_event_cb (GtkTreeView *view,
   return FALSE;
 }
 
+static gchar *
+debug_window_format_timestamp (gdouble timestamp)
+{
+  struct tm *tstruct;
+  char time_str[32];
+  gint ms;
+  time_t sec;
+  gchar *text;
+
+  ms = (int) ((timestamp - (int) timestamp)*1e6);
+  sec = (long) timestamp;
+  tstruct = localtime ((time_t *) &sec);
+  if (!strftime (time_str, sizeof (time_str), "%x %T", tstruct))
+    {
+      DEBUG ("Failed to format timestamp: %e", timestamp);
+      time_str[0] = '\0';
+    }
+
+  text = g_strdup_printf ("%s.%d", time_str, ms);
+
+  return text;
+}
+
+static void
+debug_window_time_formatter (GtkTreeViewColumn *tree_column,
+    GtkCellRenderer *cell,
+    GtkTreeModel *tree_model,
+    GtkTreeIter *iter,
+    gpointer data)
+{
+  gdouble timestamp;
+  gchar *time_str;
+
+  gtk_tree_model_get (tree_model, iter, COL_DEBUG_TIMESTAMP, &timestamp, -1);
+
+  time_str = debug_window_format_timestamp (timestamp);
+
+  g_object_set (G_OBJECT (cell), "text", time_str, NULL);
+
+  g_free (time_str);
+}
+
 static gboolean
 debug_window_store_filter_foreach (GtkTreeModel *model,
     GtkTreePath *path,
@@ -888,7 +970,7 @@ debug_window_store_filter_foreach (GtkTreeModel *model,
   GFileOutputStream *output_stream = (GFileOutputStream *) user_data;
   gchar *domain, *category, *message, *level_str, *level_upper;
   gdouble timestamp;
-  gchar *line;
+  gchar *line, *time_str;
   GError *error = NULL;
   gboolean out = FALSE;
 
@@ -902,9 +984,13 @@ debug_window_store_filter_foreach (GtkTreeModel *model,
 
   level_upper = g_ascii_strup (level_str, -1);
 
-  line = g_strdup_printf ("%s%s%s-%s: %e: %s\n",
+  time_str = debug_window_format_timestamp (timestamp);
+
+  line = g_strdup_printf ("%s%s%s-%s: %s: %s\n",
       domain, EMP_STR_EMPTY (category) ? "" : "/",
-      category, level_upper, timestamp, message);
+      category, level_upper, time_str, message);
+
+  g_free (time_str);
 
   g_output_stream_write (G_OUTPUT_STREAM (output_stream), line,
       strlen (line), NULL, &error);
@@ -1004,7 +1090,7 @@ debug_window_copy_model_foreach (GtkTreeModel *model,
   gchar *tmp;
   gchar *domain, *category, *message, *level_str, *level_upper;
   gdouble timestamp;
-  gchar *line;
+  gchar *line, *time_str;
 
   gtk_tree_model_get (model, iter,
       COL_DEBUG_TIMESTAMP, &timestamp,
@@ -1016,9 +1102,13 @@ debug_window_copy_model_foreach (GtkTreeModel *model,
 
   level_upper = g_ascii_strup (level_str, -1);
 
-  line = g_strdup_printf ("%s%s%s-%s: %e: %s\n",
+  time_str = debug_window_format_timestamp (timestamp);
+
+  line = g_strdup_printf ("%s%s%s-%s: %s: %s\n",
       domain, EMP_STR_EMPTY (category) ? "" : "/",
-      category, level_upper, timestamp, message);
+      category, level_upper, time_str, message);
+
+  g_free (time_str);
 
   tmp = g_strconcat (*text, line, NULL);
 
@@ -1060,6 +1150,52 @@ debug_window_copy_clicked_cb (GtkToolButton *tool_button,
   g_free (text);
 }
 
+static gboolean
+debug_window_key_press_event_cb (GtkWidget *widget,
+    GdkEventKey *event,
+    gpointer user_data)
+{
+  if ((event->state & GDK_CONTROL_MASK && event->keyval == GDK_w)
+      || event->keyval == GDK_Escape)
+    {
+      gtk_widget_destroy (widget);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+tree_view_search_equal_func_cb (GtkTreeModel *model,
+    gint column,
+    const gchar *key,
+    GtkTreeIter *iter,
+    gpointer search_data)
+{
+  gchar *str;
+  gint key_len;
+  gint len;
+  gint i;
+  gboolean ret = TRUE; /* The return value is counter-intuitive */
+
+  gtk_tree_model_get (model, iter, column, &str, -1);
+
+  key_len = strlen (key);
+  len = strlen (str) - key_len;
+
+  for (i = 0; i <= len; ++i)
+    {
+      if (!g_ascii_strncasecmp (key, str + i, key_len))
+        {
+          ret = FALSE;
+          break;
+        }
+    }
+
+  g_free (str);
+  return ret;
+}
+
 static GObject *
 debug_window_constructor (GType type,
     guint n_construct_params,
@@ -1082,6 +1218,10 @@ debug_window_constructor (GType type,
 
   gtk_window_set_title (GTK_WINDOW (object), _("Debug Window"));
   gtk_window_set_default_size (GTK_WINDOW (object), 800, 400);
+  empathy_geometry_bind (GTK_WINDOW (object), "debug-window");
+
+  g_signal_connect (object, "key-press-event",
+      G_CALLBACK (debug_window_key_press_event_cb), NULL);
 
   vbox = gtk_vbox_new (FALSE, 0);
   gtk_container_add (GTK_CONTAINER (object), vbox);
@@ -1189,37 +1329,37 @@ debug_window_constructor (GType type,
   gtk_list_store_append (level_store, &iter);
   gtk_list_store_set (level_store, &iter,
       COL_LEVEL_NAME, _("Debug"),
-      COL_LEVEL_VALUE, EMP_DEBUG_LEVEL_DEBUG,
+      COL_LEVEL_VALUE, TP_DEBUG_LEVEL_DEBUG,
       -1);
 
   gtk_list_store_append (level_store, &iter);
   gtk_list_store_set (level_store, &iter,
       COL_LEVEL_NAME, _("Info"),
-      COL_LEVEL_VALUE, EMP_DEBUG_LEVEL_INFO,
+      COL_LEVEL_VALUE, TP_DEBUG_LEVEL_INFO,
       -1);
 
   gtk_list_store_append (level_store, &iter);
   gtk_list_store_set (level_store, &iter,
       COL_LEVEL_NAME, _("Message"),
-      COL_LEVEL_VALUE, EMP_DEBUG_LEVEL_MESSAGE,
+      COL_LEVEL_VALUE, TP_DEBUG_LEVEL_MESSAGE,
       -1);
 
   gtk_list_store_append (level_store, &iter);
   gtk_list_store_set (level_store, &iter,
       COL_LEVEL_NAME, _("Warning"),
-      COL_LEVEL_VALUE, EMP_DEBUG_LEVEL_WARNING,
+      COL_LEVEL_VALUE, TP_DEBUG_LEVEL_WARNING,
       -1);
 
   gtk_list_store_append (level_store, &iter);
   gtk_list_store_set (level_store, &iter,
       COL_LEVEL_NAME, _("Critical"),
-      COL_LEVEL_VALUE, EMP_DEBUG_LEVEL_CRITICAL,
+      COL_LEVEL_VALUE, TP_DEBUG_LEVEL_CRITICAL,
       -1);
 
   gtk_list_store_append (level_store, &iter);
   gtk_list_store_set (level_store, &iter,
       COL_LEVEL_NAME, _("Error"),
-      COL_LEVEL_VALUE, EMP_DEBUG_LEVEL_ERROR,
+      COL_LEVEL_VALUE, TP_DEBUG_LEVEL_ERROR,
       -1);
 
   gtk_combo_box_set_active (GTK_COMBO_BOX (priv->level_filter), 0);
@@ -1236,8 +1376,9 @@ debug_window_constructor (GType type,
   renderer = gtk_cell_renderer_text_new ();
   g_object_set (renderer, "yalign", 0, NULL);
 
-  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view),
-      -1, _("Time"), renderer, "text", COL_DEBUG_TIMESTAMP, NULL);
+  gtk_tree_view_insert_column_with_data_func (GTK_TREE_VIEW (priv->view),
+      -1, _("Time"), renderer,
+      (GtkTreeCellDataFunc) debug_window_time_formatter, NULL, NULL);
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view),
       -1, _("Domain"), renderer, "text", COL_DEBUG_DOMAIN, NULL);
   gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (priv->view),
@@ -1263,6 +1404,11 @@ debug_window_constructor (GType type,
 
   gtk_tree_view_set_model (GTK_TREE_VIEW (priv->view), priv->store_filter);
 
+  gtk_tree_view_set_search_column (GTK_TREE_VIEW (priv->view),
+      COL_DEBUG_MESSAGE);
+  gtk_tree_view_set_search_equal_func (GTK_TREE_VIEW (priv->view),
+      tree_view_search_equal_func_cb, NULL, NULL);
+
   /* Scrolled window */
   priv->scrolled_win = g_object_ref (gtk_scrolled_window_new (NULL, NULL));
   gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (priv->scrolled_win),
@@ -1345,8 +1491,7 @@ debug_window_finalize (GObject *object)
   while (g_hash_table_iter_next (&iter, (gpointer *) &key,
           (gpointer *) &values))
     {
-      g_list_foreach (values, (GFunc) debug_message_free, NULL);
-      g_list_free (values);
+      debug_message_list_free (values);
     }
 
   g_hash_table_destroy (priv->all_cms);
@@ -1374,6 +1519,7 @@ debug_window_dispose (GObject *object)
   if (priv->proxy != NULL)
     {
       debug_window_set_enabled (EMPATHY_DEBUG_WINDOW (object), FALSE);
+      g_signal_handler_disconnect (priv->proxy, priv->invalid_signal_id);
       g_object_unref (priv->proxy);
     }
 
@@ -1406,7 +1552,7 @@ empathy_debug_window_class_init (EmpathyDebugWindowClass *klass)
 GtkWidget *
 empathy_debug_window_new (GtkWindow *parent)
 {
-  g_return_val_if_fail (GTK_IS_WINDOW (parent), NULL);
+  g_return_val_if_fail (parent == NULL || GTK_IS_WINDOW (parent), NULL);
 
   return GTK_WIDGET (g_object_new (EMPATHY_TYPE_DEBUG_WINDOW,
       "transient-for", parent, NULL));