]> git.0d.be Git - empathy.git/blobdiff - src/empathy-ft-manager.c
Merge branch 'irc-dialog-579800'
[empathy.git] / src / empathy-ft-manager.c
index fb1473a599138fd594b3887efe2e32e4fe81f294..98e58d4f318ce7d632b2bd1cb3938eef56182e06 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <glib/gi18n.h>
 #include <gtk/gtk.h>
-#include <libgnomeui/libgnomeui.h>
 
 #define DEBUG_FLAG EMPATHY_DEBUG_FT
 #include <libempathy/empathy-debug.h>
@@ -47,6 +46,8 @@
 
 #include "empathy-ft-manager.h"
 
+#include "extensions/extensions.h"
+
 /**
  * SECTION:empathy-ft-manager
  * @short_description: File transfer dialog
@@ -95,6 +96,8 @@ enum
 
 G_DEFINE_TYPE (EmpathyFTManager, empathy_ft_manager, G_TYPE_OBJECT);
 
+static EmpathyFTManager *manager_singleton = NULL;
+
 static gchar *
 ft_manager_format_interval (gint interval)
 {
@@ -107,8 +110,10 @@ ft_manager_format_interval (gint interval)
   secs = interval;
 
   if (hours > 0)
+    /* Translators: time left, when it is more than one hour */
     return g_strdup_printf (_("%u:%02u.%02u"), hours, mins, secs);
   else
+    /* Translators: time left, when is is less than one hour */
     return g_strdup_printf (_("%02u.%02u"), mins, secs);
 }
 
@@ -126,7 +131,7 @@ ft_manager_update_buttons (EmpathyFTManager *ft_manager)
   GtkTreeModel *model;
   GtkTreeIter iter;
   EmpathyTpFile *tp_file;
-  EmpFileTransferState state;
+  TpFileTransferState state;
   gboolean open_enabled = FALSE;
   gboolean abort_enabled = FALSE;
 
@@ -138,12 +143,12 @@ ft_manager_update_buttons (EmpathyFTManager *ft_manager)
       state = empathy_tp_file_get_state (tp_file, NULL);
 
       /* I can open the file if the transfer is completed and was incoming */
-      open_enabled = (state == EMP_FILE_TRANSFER_STATE_COMPLETED &&
+      open_enabled = (state == TP_FILE_TRANSFER_STATE_COMPLETED &&
         empathy_tp_file_is_incoming (tp_file));
 
       /* I can abort if the transfer is not already finished */
-      abort_enabled = (state != EMP_FILE_TRANSFER_STATE_CANCELLED &&
-        state != EMP_FILE_TRANSFER_STATE_COMPLETED);
+      abort_enabled = (state != TP_FILE_TRANSFER_STATE_CANCELLED &&
+        state != TP_FILE_TRANSFER_STATE_COMPLETED);
 
       g_object_unref (tp_file);
     }
@@ -153,21 +158,21 @@ ft_manager_update_buttons (EmpathyFTManager *ft_manager)
 }
 
 static const gchar *
-ft_manager_state_change_reason_to_string (EmpFileTransferStateChangeReason reason)
+ft_manager_state_change_reason_to_string (TpFileTransferStateChangeReason reason)
 {
   switch (reason)
     {
-      case EMP_FILE_TRANSFER_STATE_CHANGE_REASON_NONE:
+      case TP_FILE_TRANSFER_STATE_CHANGE_REASON_NONE:
         return _("No reason was specified");
-      case EMP_FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED:
+      case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REQUESTED:
         return _("The change in state was requested");      
-      case EMP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_STOPPED:
+      case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_STOPPED:
         return _("You canceled the file transfer");
-      case EMP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_STOPPED:
+      case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_STOPPED:
         return _("The other participant canceled the file transfer");
-      case EMP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_ERROR:
+      case TP_FILE_TRANSFER_STATE_CHANGE_REASON_LOCAL_ERROR:
         return _("Error while trying to transfer the file");
-      case EMP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_ERROR:
+      case TP_FILE_TRANSFER_STATE_CHANGE_REASON_REMOTE_ERROR:
         return _("The other participant is unable to transfer the file");
     }
   return _("Unknown reason");
@@ -192,8 +197,8 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager,
   guint64 total_size;
   gint remaining = -1;
   gint percent;
-  EmpFileTransferState state;
-  EmpFileTransferStateChangeReason reason;
+  TpFileTransferState state;
+  TpFileTransferStateChangeReason reason;
   gboolean incoming;
 
   row_ref = ft_manager_get_row_from_tp_file (ft_manager, tp_file);
@@ -208,14 +213,14 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager,
 
   switch (state)
     {
-      case EMP_FILE_TRANSFER_STATE_NONE:
+      case TP_FILE_TRANSFER_STATE_NONE:
         /* This should never happen, the CM is broken. But we avoid warning
          * because it's not our fault. */
         DEBUG ("State is NONE, probably a broken CM");
         break;
-      case EMP_FILE_TRANSFER_STATE_PENDING:
-      case EMP_FILE_TRANSFER_STATE_OPEN:
-      case EMP_FILE_TRANSFER_STATE_ACCEPTED:
+      case TP_FILE_TRANSFER_STATE_PENDING:
+      case TP_FILE_TRANSFER_STATE_OPEN:
+      case TP_FILE_TRANSFER_STATE_ACCEPTED:
         if (incoming)
           /* translators: first %s is filename, second %s is the contact name */
           first_line_format = _("Receiving \"%s\" from %s");
@@ -225,16 +230,13 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager,
 
         first_line = g_strdup_printf (first_line_format, filename, contact_name);
 
-        if (state == EMP_FILE_TRANSFER_STATE_OPEN || incoming)
+        if (state == TP_FILE_TRANSFER_STATE_OPEN || incoming)
           {
             gchar *total_size_str;
             gchar *transferred_bytes_str;
 
             if (total_size == EMPATHY_TP_FILE_UNKNOWN_SIZE)
-              /* translators: the text before the "|" is context to
-               * help you decide on the correct translation. You MUST
-               * OMIT it in the translated string. */
-              total_size_str = g_strdup (Q_("file size|Unknown"));
+              total_size_str = g_strdup (C_("file size", "Unknown"));
             else
               total_size_str = g_format_size_for_display (total_size);
 
@@ -249,12 +251,12 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager,
 
           }
         else
-          second_line = g_strdup (_("Waiting the other participant's response"));
+          second_line = g_strdup (_("Waiting for the other participant's response"));
 
       remaining = empathy_tp_file_get_remaining_time (tp_file);
       break;
 
-    case EMP_FILE_TRANSFER_STATE_COMPLETED:
+    case TP_FILE_TRANSFER_STATE_COMPLETED:
       if (incoming)
         /* translators: first %s is filename, second %s
          * is the contact name */
@@ -272,7 +274,7 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager,
 
       break;
 
-    case EMP_FILE_TRANSFER_STATE_CANCELLED:
+    case TP_FILE_TRANSFER_STATE_CANCELLED:
       if (incoming)
         /* translators: first %s is filename, second %s
          * is the contact name */
@@ -299,12 +301,9 @@ ft_manager_update_ft_row (EmpathyFTManager *ft_manager,
 
   if (remaining < 0)
     {
-      if (state != EMP_FILE_TRANSFER_STATE_COMPLETED &&
-          state != EMP_FILE_TRANSFER_STATE_CANCELLED)
-        /* translators: the text before the "|" is context to
-         * help you decide on the correct translation. You
-         * MUST OMIT it in the translated string. */
-        remaining_str = g_strdup (Q_("remaining time|Unknown"));
+      if (state != TP_FILE_TRANSFER_STATE_COMPLETED &&
+          state != TP_FILE_TRANSFER_STATE_CANCELLED)
+        remaining_str = g_strdup (C_("remaining time", "Unknown"));
     }
   else
     remaining_str = ft_manager_format_interval (remaining);
@@ -364,10 +363,7 @@ ft_manager_progress_cell_data_func (GtkTreeViewColumn *col,
   if (percent < 0)
     {
       percent = 0;
-      /* Translators: The text before the "|" is context to help you
-       * decide on the correct translation. You MUST OMIT it in the
-       * translated string. */
-      text = Q_("file transfer percent|Unknown");
+      text = C_("file transfer percent", "Unknown");
     }
 
   g_object_set (renderer, "text", text, "value", percent, NULL);
@@ -444,6 +440,8 @@ ft_manager_remove_file_from_model (EmpathyFTManager *ft_manager,
 
   if (update_selection)
     gtk_tree_selection_select_iter (selection, &iter);
+
+  empathy_tp_file_close (tp_file);
 }
 
 static gboolean
@@ -453,11 +451,11 @@ remove_finished_transfer_foreach (gpointer key,
 {
   EmpathyTpFile *tp_file = EMPATHY_TP_FILE (key);
   EmpathyFTManager *self = EMPATHY_FT_MANAGER (user_data);
-  EmpFileTransferState state;
+  TpFileTransferState state;
 
   state = empathy_tp_file_get_state (tp_file, NULL);
-  if (state == EMP_FILE_TRANSFER_STATE_COMPLETED ||
-      state == EMP_FILE_TRANSFER_STATE_CANCELLED)
+  if (state == TP_FILE_TRANSFER_STATE_COMPLETED ||
+      state == TP_FILE_TRANSFER_STATE_CANCELLED)
     {
       ft_manager_remove_file_from_model (self, tp_file);
       return TRUE;
@@ -472,7 +470,7 @@ ft_manager_state_changed_cb (EmpathyTpFile *tp_file,
                              EmpathyFTManager *ft_manager)
 {
   if (empathy_tp_file_get_state (tp_file, NULL) ==
-      EMP_FILE_TRANSFER_STATE_COMPLETED)
+      TP_FILE_TRANSFER_STATE_COMPLETED)
     {
       GtkRecentManager *manager;
       const gchar *uri;
@@ -486,56 +484,6 @@ ft_manager_state_changed_cb (EmpathyTpFile *tp_file,
     ft_manager_update_ft_row (ft_manager, tp_file);
 }
 
-static void
-ft_manager_add_tp_file_to_list (EmpathyFTManager *ft_manager,
-                                EmpathyTpFile *tp_file)
-{
-  GtkTreeRowReference *row_ref;
-  GtkTreeIter iter;
-  GtkTreeSelection *selection;
-  GtkTreePath *path;
-  GtkIconTheme *theme;
-  gchar *icon_name;
-  const gchar *content_type;
-
-  /* Get the icon name from the mime-type of the file.
-   * FIXME: Use g_content_type_get_icon instead of gnome_icon_lookup and drop
-   * libgnomeui. We need the "gicon" property on GtkCellRendererPixbuf which is
-   * in GTK+ 2.14 */
-  content_type = empathy_tp_file_get_content_type (tp_file);
-  theme = gtk_icon_theme_get_default ();
-  icon_name = gnome_icon_lookup (theme, NULL, NULL, NULL, NULL,
-      content_type, GNOME_ICON_LOOKUP_FLAGS_NONE, NULL);
-
-  /* Append the ft in the store */
-  gtk_list_store_insert_with_values (GTK_LIST_STORE (ft_manager->priv->model),
-      &iter, G_MAXINT, COL_FT_OBJECT, tp_file, COL_ICON, icon_name, -1);
-
-  /* Insert the new row_ref in the hash table  */
-  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ft_manager->priv->model),
-      &iter);
-  row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (
-      ft_manager->priv->model), path);
-  gtk_tree_path_free (path);
-  g_hash_table_insert (ft_manager->priv->tp_file_to_row_ref,
-      g_object_ref (tp_file), row_ref);
-
-  /* Select the new row */
-  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (
-      ft_manager->priv->treeview));
-  gtk_tree_selection_select_iter (selection, &iter);
-
-  /* Update the row with the initial values, and keep track of changes */
-  ft_manager_update_ft_row (ft_manager, tp_file);
-  g_signal_connect (tp_file, "notify::state",
-      G_CALLBACK (ft_manager_state_changed_cb), ft_manager);
-  g_signal_connect (tp_file, "notify::transferred-bytes",
-      G_CALLBACK (ft_manager_transferred_bytes_changed_cb), ft_manager);
-
-  gtk_window_present (GTK_WINDOW (ft_manager->priv->window));
-  g_free (icon_name);
-}
-
 static void
 ft_manager_clear (EmpathyFTManager *ft_manager)
 {
@@ -565,7 +513,7 @@ ft_manager_open (EmpathyFTManager *ft_manager)
 
   uri = g_object_get_data (G_OBJECT (tp_file), "uri");
   DEBUG ("Opening URI: %s", uri);
-  empathy_url_show (uri);
+  empathy_url_show (GTK_WIDGET (ft_manager->priv->window), uri);
   g_object_unref (tp_file);
 }
 
@@ -633,13 +581,16 @@ static void
 ft_manager_destroy_cb (GtkWidget *widget,
                        EmpathyFTManager *ft_manager)
 {
-  g_object_unref (ft_manager);
+  ft_manager->priv->window = NULL;
+  if (ft_manager->priv->save_geometry_id != 0)
+    g_source_remove (ft_manager->priv->save_geometry_id);
+  g_hash_table_remove_all (ft_manager->priv->tp_file_to_row_ref);
 }
 
 static void
 ft_manager_build_ui (EmpathyFTManager *ft_manager)
 {
-  GladeXML *glade;
+  GtkBuilder *gui;
   gint x, y, w, h;
   GtkTreeView *view;
   GtkListStore *liststore;
@@ -648,9 +599,11 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
   GtkTreeSelection *selection;
   gchar *filename;
 
-  filename = empathy_file_lookup ("empathy-ft-manager.glade", "src");
-  glade = empathy_glade_get_file (filename,
-      "ft_manager_dialog", NULL,
+  if (ft_manager->priv->window != NULL)
+    return;
+
+  filename = empathy_file_lookup ("empathy-ft-manager.ui", "src");
+  gui = empathy_builder_get_file (filename,
       "ft_manager_dialog", &ft_manager->priv->window,
       "ft_list", &ft_manager->priv->treeview,
       "open_button", &ft_manager->priv->open_button,
@@ -658,14 +611,14 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
       NULL);
   g_free (filename);
 
-  empathy_glade_connect (glade, ft_manager,
+  empathy_builder_connect (gui, ft_manager,
       "ft_manager_dialog", "destroy", ft_manager_destroy_cb,
       "ft_manager_dialog", "response", ft_manager_response_cb,
       "ft_manager_dialog", "delete-event", ft_manager_delete_event_cb,
       "ft_manager_dialog", "configure-event", ft_manager_configure_event_cb,
       NULL);
 
-  g_object_unref (glade);
+  g_object_unref (gui);
 
   /* Window geometry. */
   empathy_geometry_load ("ft-manager", &x, &y, &w, &h);
@@ -679,7 +632,7 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
 
   if (w > 0 && h > 0)
     {
-      /* Use the defaults from the glade file if we don't have
+      /* Use the defaults from the ui file if we don't have
        * good w, h geometry. */
       gtk_window_resize (GTK_WINDOW (ft_manager->priv->window), w, h);
     }
@@ -696,7 +649,7 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
   /* Setup the model */
   liststore = gtk_list_store_new (5,
       G_TYPE_INT,     /* percent */
-      G_TYPE_STRING,  /* icon */
+      G_TYPE_ICON,    /* icon */
       G_TYPE_STRING,  /* message */
       G_TYPE_STRING,  /* remaining */
       G_TYPE_OBJECT); /* ft_file */
@@ -730,7 +683,7 @@ ft_manager_build_ui (EmpathyFTManager *ft_manager)
       "stock-size", GTK_ICON_SIZE_DND, NULL);
   gtk_tree_view_column_pack_start (column, renderer, FALSE);
   gtk_tree_view_column_set_attributes (column, renderer,
-      "icon-name", COL_ICON, NULL);
+      "gicon", COL_ICON, NULL);
 
   renderer = gtk_cell_renderer_text_new ();
   g_object_set (renderer, "ellipsize", PANGO_ELLIPSIZE_END, NULL);
@@ -758,10 +711,10 @@ empathy_ft_manager_finalize (GObject *object)
 
   DEBUG ("%p", object);
 
-  g_hash_table_destroy (ft_manager->priv->tp_file_to_row_ref);
+  if (ft_manager->priv->window)
+    gtk_widget_destroy (ft_manager->priv->window);
 
-  if (ft_manager->priv->save_geometry_id != 0)
-    g_source_remove (ft_manager->priv->save_geometry_id);
+  g_hash_table_destroy (ft_manager->priv->tp_file_to_row_ref);
 
   G_OBJECT_CLASS (empathy_ft_manager_parent_class)->finalize (object);
 }
@@ -779,8 +732,29 @@ empathy_ft_manager_init (EmpathyFTManager *ft_manager)
   priv->tp_file_to_row_ref = g_hash_table_new_full (g_direct_hash,
       g_direct_equal, (GDestroyNotify) g_object_unref,
       (GDestroyNotify) gtk_tree_row_reference_free);
+}
 
-  ft_manager_build_ui (ft_manager);
+static GObject *
+empathy_ft_manager_constructor (GType type,
+                                guint n_props,
+                                GObjectConstructParam *props)
+{
+  GObject *retval;
+
+  if (manager_singleton)
+    {
+      retval = g_object_ref (manager_singleton);
+    }
+  else
+    {
+      retval = G_OBJECT_CLASS (empathy_ft_manager_parent_class)->constructor
+          (type, n_props, props);
+
+      manager_singleton = EMPATHY_FT_MANAGER (retval);
+      g_object_add_weak_pointer (retval, (gpointer) &manager_singleton);
+    }
+
+  return retval;
 }
 
 static void
@@ -789,30 +763,22 @@ empathy_ft_manager_class_init (EmpathyFTManagerClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
   object_class->finalize = empathy_ft_manager_finalize;
+  object_class->constructor = empathy_ft_manager_constructor;
 
   g_type_class_add_private (object_class, sizeof (EmpathyFTManagerPriv));
 }
 
 /**
- * empathy_ft_manager_get_default:
+ * empathy_ft_manager_dup_singleton:
  *
- * Returns a new #EmpathyFTManager if there is not already one, or the existing
- * one if it exists.
+ * Returns a reference to the #EmpathyFTManager singleton object.
  *
  * Returns: a #EmpathyFTManager
  */
 EmpathyFTManager *
-empathy_ft_manager_get_default (void)
+empathy_ft_manager_dup_singleton (void)
 {
-  static EmpathyFTManager *manager_p = NULL;
-
-  if (!manager_p)
-    {
-      manager_p = g_object_new (EMPATHY_TYPE_FT_MANAGER, NULL);
-      g_object_add_weak_pointer (G_OBJECT (manager_p), (gpointer) &manager_p);
-    }
-
-  return manager_p;
+  return g_object_new (EMPATHY_TYPE_FT_MANAGER, NULL);
 }
 
 /**
@@ -828,9 +794,58 @@ empathy_ft_manager_get_dialog (EmpathyFTManager *ft_manager)
 {
   g_return_val_if_fail (EMPATHY_IS_FT_MANAGER (ft_manager), NULL);
 
+  ft_manager_build_ui (ft_manager);
+
   return ft_manager->priv->window;
 }
 
+static void
+ft_manager_add_tp_file_to_list (EmpathyFTManager *ft_manager,
+                                EmpathyTpFile *tp_file)
+{
+  GtkTreeRowReference *row_ref;
+  GtkTreeIter iter;
+  GtkTreeSelection *selection;
+  GtkTreePath *path;
+  GIcon *icon;
+  const gchar *content_type;
+
+  ft_manager_build_ui (ft_manager);
+
+  /* Get the icon name from the mime-type of the file. */
+  content_type = empathy_tp_file_get_content_type (tp_file);
+  icon = g_content_type_get_icon (content_type);
+
+  /* Append the ft in the store */
+  gtk_list_store_insert_with_values (GTK_LIST_STORE (ft_manager->priv->model),
+      &iter, G_MAXINT, COL_FT_OBJECT, tp_file, COL_ICON, icon, -1);
+
+  g_object_unref (icon);
+
+  /* Insert the new row_ref in the hash table  */
+  path = gtk_tree_model_get_path (GTK_TREE_MODEL (ft_manager->priv->model),
+      &iter);
+  row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (
+      ft_manager->priv->model), path);
+  gtk_tree_path_free (path);
+  g_hash_table_insert (ft_manager->priv->tp_file_to_row_ref,
+      g_object_ref (tp_file), row_ref);
+
+  /* Select the new row */
+  selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (
+      ft_manager->priv->treeview));
+  gtk_tree_selection_select_iter (selection, &iter);
+
+  /* Update the row with the initial values, and keep track of changes */
+  ft_manager_update_ft_row (ft_manager, tp_file);
+  g_signal_connect (tp_file, "notify::state",
+      G_CALLBACK (ft_manager_state_changed_cb), ft_manager);
+  g_signal_connect (tp_file, "notify::transferred-bytes",
+      G_CALLBACK (ft_manager_transferred_bytes_changed_cb), ft_manager);
+
+  gtk_window_present (GTK_WINDOW (ft_manager->priv->window));
+}
+
 typedef struct {
   EmpathyFTManager *ft_manager;
   EmpathyTpFile *tp_file;
@@ -1003,6 +1018,7 @@ ft_manager_display_accept_dialog (EmpathyFTManager *ft_manager,
 
   gtk_message_dialog_format_secondary_text
       (GTK_MESSAGE_DIALOG (dialog),
+       /* Translators: the first %s is the file name, the second %s is the file size */
        _("Do you want to accept the file \"%s\" (%s)?"),
        filename, size_str);
 
@@ -1056,7 +1072,7 @@ void
 empathy_ft_manager_add_tp_file (EmpathyFTManager *ft_manager,
                                 EmpathyTpFile *tp_file)
 {
-  EmpFileTransferState state;
+  TpFileTransferState state;
 
   g_return_if_fail (EMPATHY_IS_FT_MANAGER (ft_manager));
   g_return_if_fail (EMPATHY_IS_TP_FILE (tp_file));
@@ -1067,7 +1083,7 @@ empathy_ft_manager_add_tp_file (EmpathyFTManager *ft_manager,
       empathy_contact_get_name (empathy_tp_file_get_contact (tp_file)),
       empathy_tp_file_get_filename (tp_file), state);
 
-  if (state == EMP_FILE_TRANSFER_STATE_PENDING &&
+  if (state == TP_FILE_TRANSFER_STATE_PENDING &&
       empathy_tp_file_is_incoming (tp_file))
     ft_manager_display_accept_dialog (ft_manager, tp_file);
   else