static void ft_transfer_operation_callback (EmpathyTpFile *tp_file, const GError *error, gpointer user_data) { EmpathyFTHandler *handler = user_data; EmpathyFTHandlerPriv *priv = GET_PRIV (handler); DEBUG ("Transfer operation callback, error %p", error); if (error != NULL) { emit_error_signal (handler, error); } else { priv->is_completed = TRUE; g_signal_emit (handler, signals[TRANSFER_DONE], 0, tp_file); empathy_tp_file_close (tp_file); if (empathy_ft_handler_is_incoming (handler) && priv->use_hash) { check_hash_incoming (handler); } } }
static void ft_handler_hashing_started_cb (EmpathyFTHandler *handler, EmpathyFTManager *manager) { char *message, *first_line, *second_line; GtkTreeRowReference *row_ref; DEBUG ("Hashing started"); g_signal_connect (handler, "hashing-progress", G_CALLBACK (ft_handler_hashing_progress_cb), manager); g_signal_connect (handler, "hashing-done", G_CALLBACK (ft_handler_hashing_done_cb), manager); row_ref = ft_manager_get_row_from_handler (manager, handler); g_return_if_fail (row_ref != NULL); first_line = ft_manager_format_contact_info (handler); if (empathy_ft_handler_is_incoming (handler)) second_line = g_strdup_printf (_("Checking integrity of “%s”"), empathy_ft_handler_get_filename (handler)); else second_line = g_strdup_printf (_("Hashing “%s”"), empathy_ft_handler_get_filename (handler)); message = g_strdup_printf ("%s\n%s", first_line, second_line); ft_manager_update_handler_message (manager, row_ref, message); g_free (first_line); g_free (second_line); g_free (message); }
static void ft_manager_start_transfer (EmpathyFTManager *manager, EmpathyFTHandler *handler) { gboolean is_outgoing; is_outgoing = !empathy_ft_handler_is_incoming (handler); DEBUG ("Start transfer, is outgoing %s", is_outgoing ? "True" : "False"); /* now connect the signals */ g_signal_connect (handler, "transfer-error", G_CALLBACK (ft_handler_transfer_error_cb), manager); if (is_outgoing && empathy_ft_handler_get_use_hash (handler)) { g_signal_connect (handler, "hashing-started", G_CALLBACK (ft_handler_hashing_started_cb), manager); } else { /* either incoming or outgoing without hash */ g_signal_connect (handler, "transfer-started", G_CALLBACK (ft_handler_transfer_started_cb), manager); } empathy_ft_handler_start_transfer (handler); }
static void ft_handler_hashing_done_cb (EmpathyFTHandler *handler, EmpathyFTManager *manager) { GtkTreeRowReference *row_ref; char *first_line, *second_line, *message; DEBUG ("Hashing done"); /* update the message */ if (empathy_ft_handler_is_incoming (handler)) { do_real_transfer_done (manager, handler); return; } row_ref = ft_manager_get_row_from_handler (manager, handler); g_return_if_fail (row_ref != NULL); first_line = ft_manager_format_contact_info (handler); second_line = g_strdup (_("Waiting for the other participant’s response")); message = g_strdup_printf ("%s\n%s", first_line, second_line); ft_manager_update_handler_message (manager, row_ref, message); g_free (message); g_free (first_line); g_free (second_line); g_signal_connect (handler, "transfer-started", G_CALLBACK (ft_handler_transfer_started_cb), manager); }
static void ft_handler_hashing_progress_cb (EmpathyFTHandler *handler, guint64 current_bytes, guint64 total_bytes, EmpathyFTManager *manager) { char *first_line, *second_line, *message; GtkTreeRowReference *row_ref; row_ref = ft_manager_get_row_from_handler (manager, handler); g_return_if_fail (row_ref != NULL); if (empathy_ft_handler_is_incoming (handler)) first_line = g_strdup_printf (_("Checking integrity of “%s”"), empathy_ft_handler_get_filename (handler)); else first_line = g_strdup_printf (_("Hashing “%s”"), empathy_ft_handler_get_filename (handler)); second_line = ft_manager_format_progress_bytes_and_percentage (current_bytes, total_bytes, -1, NULL); message = g_strdup_printf ("%s\n%s", first_line, second_line); ft_manager_update_handler_message (manager, row_ref, message); g_free (message); g_free (first_line); g_free (second_line); }
static void ft_transfer_state_cb (TpFileTransferChannel *channel, GParamSpec *pspec, EmpathyFTHandler *handler) { EmpathyFTHandlerPriv *priv = handler->priv; TpFileTransferStateChangeReason reason; TpFileTransferState state = tp_file_transfer_channel_get_state ( channel, &reason); (void)pspec; /* suppress unused-parameter warning */ if (state == TP_FILE_TRANSFER_STATE_COMPLETED) { priv->is_completed = TRUE; g_signal_emit (handler, signals[TRANSFER_DONE], 0, channel); tp_channel_close_async (TP_CHANNEL (channel), NULL, NULL); if (empathy_ft_handler_is_incoming (handler) && priv->use_hash) { check_hash_incoming (handler); } } else if (state == TP_FILE_TRANSFER_STATE_CANCELLED) { GError *error = error_from_state_change_reason (reason); emit_error_signal (handler, error); g_clear_error (&error); } }
static void do_real_transfer_done (EmpathyFTManager *manager, EmpathyFTHandler *handler) { const char *contact_name; const char *filename; char *first_line, *second_line, *message; char *uri; gboolean incoming; GtkTreeRowReference *row_ref; GtkRecentManager *recent_manager; GFile *file; row_ref = ft_manager_get_row_from_handler (manager, handler); g_return_if_fail (row_ref != NULL); incoming = empathy_ft_handler_is_incoming (handler); contact_name = empathy_contact_get_alias (empathy_ft_handler_get_contact (handler)); filename = empathy_ft_handler_get_filename (handler); if (incoming) /* translators: first %s is filename, second %s * is the contact name */ first_line = g_strdup_printf (_("“%s” received from %s"), filename, contact_name); else /* translators: first %s is filename, second %s * is the contact name */ first_line = g_strdup_printf (_("“%s” sent to %s"), filename, contact_name); second_line = g_strdup (_("File transfer completed")); message = g_strdup_printf ("%s\n%s", first_line, second_line); ft_manager_update_handler_message (manager, row_ref, message); ft_manager_clear_handler_time (manager, row_ref); /* update buttons */ ft_manager_update_buttons (manager); g_free (message); g_free (first_line); g_free (second_line); recent_manager = gtk_recent_manager_get_default (); file = empathy_ft_handler_get_gfile (handler); uri = g_file_get_uri (file); gtk_recent_manager_add_item (recent_manager, uri); g_free (uri); }
static void ft_manager_update_buttons (EmpathyFTManager *manager) { GtkTreeSelection *selection; GtkTreeModel *model; GtkTreeIter iter; EmpathyFTHandler *handler; gboolean open_enabled = FALSE; gboolean abort_enabled = FALSE; gboolean clear_enabled = FALSE; gboolean is_completed, is_cancelled; GHashTableIter hash_iter; EmpathyFTManagerPriv *priv = GET_PRIV (manager); selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); if (gtk_tree_selection_get_selected (selection, &model, &iter)) { gtk_tree_model_get (model, &iter, COL_FT_OBJECT, &handler, -1); is_completed = empathy_ft_handler_is_completed (handler); is_cancelled = empathy_ft_handler_is_cancelled (handler); /* I can open the file if the transfer is completed and was incoming */ open_enabled = (is_completed && empathy_ft_handler_is_incoming (handler)); /* I can abort if the transfer is not already finished */ abort_enabled = (is_cancelled == FALSE && is_completed == FALSE); g_object_unref (handler); } g_hash_table_iter_init (&hash_iter, priv->ft_handler_to_row_ref); while (g_hash_table_iter_next (&hash_iter, (gpointer *) &handler, NULL)) { if (empathy_ft_handler_is_completed (handler) || empathy_ft_handler_is_cancelled (handler)) clear_enabled = TRUE; if (clear_enabled) break; } gtk_widget_set_sensitive (priv->open_button, open_enabled); gtk_widget_set_sensitive (priv->abort_button, abort_enabled); if (clear_enabled) gtk_widget_set_sensitive (priv->clear_button, TRUE); }
static gchar * ft_manager_format_error_message (EmpathyFTHandler *handler, const GError *error) { const char *contact_name, *filename; EmpathyContact *contact; char *first_line, *message; gboolean incoming; contact_name = NULL; incoming = empathy_ft_handler_is_incoming (handler); contact = empathy_ft_handler_get_contact (handler); if (contact) contact_name = empathy_contact_get_alias (contact); filename = empathy_ft_handler_get_filename (handler); if (incoming) /* filename/contact_name here are either both NULL or both valid */ if (filename && contact_name) /* translators: first %s is filename, second %s * is the contact name */ first_line = g_strdup_printf (_("Error receiving “%s” from %s"), filename, contact_name); else first_line = g_strdup (_("Error receiving a file")); else /* translators: first %s is filename, second %s * is the contact name */ if (filename && contact_name) first_line = g_strdup_printf (_("Error sending “%s” to %s"), filename, contact_name); else first_line = g_strdup (_("Error sending a file")); message = g_strdup_printf ("%s\n%s", first_line, error->message); g_free (first_line); return message; }
static void ft_handler_transfer_done_cb (EmpathyFTHandler *handler, TpFileTransferChannel *channel, EmpathyFTManager *manager) { if (empathy_ft_handler_is_incoming (handler) && empathy_ft_handler_get_use_hash (handler)) { DEBUG ("Transfer done, waiting for hashing-started"); /* connect to the signal and return early */ g_signal_connect (handler, "hashing-started", G_CALLBACK (ft_handler_hashing_started_cb), manager); return; } DEBUG ("Transfer done, no hashing"); do_real_transfer_done (manager, handler); }
static gchar * ft_manager_format_contact_info (EmpathyFTHandler *handler) { gboolean incoming; const char *filename, *contact_name, *first_line_format; char *retval; incoming = empathy_ft_handler_is_incoming (handler); contact_name = empathy_contact_get_alias (empathy_ft_handler_get_contact (handler)); filename = empathy_ft_handler_get_filename (handler); if (incoming) /* translators: first %s is filename, second %s is the contact name */ first_line_format = _("Receiving “%s” from %s"); else /* translators: first %s is filename, second %s is the contact name */ first_line_format = _("Sending “%s” to %s"); retval = g_strdup_printf (first_line_format, filename, contact_name); return retval; }
static gboolean hash_job_done (gpointer user_data) { HashingData *hash_data = user_data; EmpathyFTHandler *handler = hash_data->handler; EmpathyFTHandlerPriv *priv; GError *error = NULL; DEBUG ("Closing stream after hashing."); priv = GET_PRIV (handler); if (hash_data->error != NULL) { error = hash_data->error; hash_data->error = NULL; goto cleanup; } DEBUG ("Got file hash %s", g_checksum_get_string (hash_data->checksum)); if (empathy_ft_handler_is_incoming (handler)) { if (g_strcmp0 (g_checksum_get_string (hash_data->checksum), priv->content_hash)) { DEBUG ("Hash mismatch when checking incoming handler: " "received %s, calculated %s", priv->content_hash, g_checksum_get_string (hash_data->checksum)); error = g_error_new_literal (EMPATHY_FT_ERROR_QUARK, EMPATHY_FT_ERROR_HASH_MISMATCH, _("File transfer completed, but the file was corrupted")); goto cleanup; } else { DEBUG ("Hash verification matched, received %s, calculated %s", priv->content_hash, g_checksum_get_string (hash_data->checksum)); } } else { /* set the checksum in the request... * org.freedesktop.Telepathy.Channel.Type.FileTransfer.ContentHash */ tp_asv_set_string (priv->request, TP_PROP_CHANNEL_TYPE_FILE_TRANSFER_CONTENT_HASH, g_checksum_get_string (hash_data->checksum)); } cleanup: if (error != NULL) { emit_error_signal (handler, error); g_clear_error (&error); } else { g_signal_emit (handler, signals[HASHING_DONE], 0); if (!empathy_ft_handler_is_incoming (handler)) /* the request is complete now, push it to the dispatcher */ ft_handler_push_to_dispatcher (handler); } hash_data_free (hash_data); return FALSE; }
static void ft_manager_add_handler_to_list (EmpathyFTManager *manager, EmpathyFTHandler *handler, const GError *error) { GtkTreeRowReference *row_ref; GtkTreeIter iter; GtkTreeSelection *selection; GtkTreePath *path; GIcon *icon; const char *content_type, *second_line; char *first_line, *message; EmpathyFTManagerPriv *priv = GET_PRIV (manager); icon = NULL; /* get the icon name from the mime-type of the file. */ content_type = empathy_ft_handler_get_content_type (handler); if (content_type != NULL) icon = g_content_type_get_icon (content_type); /* append the handler in the store */ gtk_list_store_insert_with_values (GTK_LIST_STORE (priv->model), &iter, G_MAXINT, COL_FT_OBJECT, handler, COL_ICON, icon, -1); if (icon != NULL) g_object_unref (icon); /* insert the new row_ref in the hash table */ path = gtk_tree_model_get_path (GTK_TREE_MODEL (priv->model), &iter); row_ref = gtk_tree_row_reference_new (GTK_TREE_MODEL (priv->model), path); gtk_tree_path_free (path); g_hash_table_insert (priv->ft_handler_to_row_ref, g_object_ref (handler), row_ref); /* select the new row */ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); gtk_tree_selection_select_iter (selection, &iter); if (error != NULL) { message = ft_manager_format_error_message (handler, error); ft_manager_update_handler_message (manager, row_ref, message); g_free (message); return; } /* update the row with the initial values. * the only case where we postpone this is in case we're managing * an outgoing+hashing transfer, as the hashing started signal will * take care of updating the information. */ if (empathy_ft_handler_is_incoming (handler) || !empathy_ft_handler_get_use_hash (handler)) { first_line = ft_manager_format_contact_info (handler); second_line = _("Waiting for the other participant’s response"); message = g_strdup_printf ("%s\n%s", first_line, second_line); ft_manager_update_handler_message (manager, row_ref, message); g_free (first_line); g_free (message); } /* hook up the signals and start the transfer */ ft_manager_start_transfer (manager, handler); }