void purple_xfer_update_progress(PurpleXfer *xfer) { PurpleXferUiOps *ui_ops; g_return_if_fail(xfer != NULL); ui_ops = purple_xfer_get_ui_ops(xfer); if (ui_ops != NULL && ui_ops->update_progress != NULL) ui_ops->update_progress(xfer, purple_xfer_get_progress(xfer)); }
void purple_xfer_set_completed(PurpleXfer *xfer, gboolean completed) { PurpleXferUiOps *ui_ops; g_return_if_fail(xfer != NULL); if (completed == TRUE) { char *msg = NULL; PurpleConversation *conv; purple_xfer_set_status(xfer, PURPLE_XFER_STATUS_DONE); if (purple_xfer_get_filename(xfer) != NULL) { char *filename = g_markup_escape_text(purple_xfer_get_filename(xfer), -1); if (purple_xfer_get_local_filename(xfer) && purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) { char *local = g_markup_escape_text(purple_xfer_get_local_filename(xfer), -1); msg = g_strdup_printf(_("Transfer of file <A HREF=\"file://%s\">%s</A> complete"), local, filename); g_free(local); } else msg = g_strdup_printf(_("Transfer of file %s complete"), filename); g_free(filename); } else msg = g_strdup(_("File transfer complete")); conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_IM, xfer->who, purple_xfer_get_account(xfer)); if (conv != NULL) purple_conversation_write(conv, NULL, msg, PURPLE_MESSAGE_SYSTEM, time(NULL)); g_free(msg); } ui_ops = purple_xfer_get_ui_ops(xfer); if (ui_ops != NULL && ui_ops->update_progress != NULL) ui_ops->update_progress(xfer, purple_xfer_get_progress(xfer)); }
static void do_transfer(PurpleXfer *xfer) { PurpleXferUiOps *ui_ops; guchar *buffer = NULL; gssize r = 0; ui_ops = purple_xfer_get_ui_ops(xfer); if (xfer->type == PURPLE_XFER_RECEIVE) { r = purple_xfer_read(xfer, &buffer); if (r > 0) { size_t wc; if (ui_ops && ui_ops->ui_write) wc = ui_ops->ui_write(xfer, buffer, r); else wc = fwrite(buffer, 1, r, xfer->dest_fp); if (wc != r) { purple_debug_error("filetransfer", "Unable to write whole buffer.\n"); purple_xfer_cancel_local(xfer); g_free(buffer); return; } if ((purple_xfer_get_size(xfer) > 0) && ((purple_xfer_get_bytes_sent(xfer)+r) >= purple_xfer_get_size(xfer))) purple_xfer_set_completed(xfer, TRUE); } else if(r < 0) { purple_xfer_cancel_remote(xfer); g_free(buffer); return; } } else if (xfer->type == PURPLE_XFER_SEND) { size_t result = 0; size_t s = MIN(purple_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size); PurpleXferPrivData *priv = g_hash_table_lookup(xfers_data, xfer); gboolean read = TRUE; /* this is so the prpl can keep the connection open if it needs to for some odd reason. */ if (s == 0) { if (xfer->watcher) { purple_input_remove(xfer->watcher); xfer->watcher = 0; } return; } if (priv->buffer) { if (priv->buffer->len < s) { s -= priv->buffer->len; read = TRUE; } else { read = FALSE; } } if (read) { if (ui_ops && ui_ops->ui_read) { gssize tmp = ui_ops->ui_read(xfer, &buffer, s); if (tmp == 0) { /* * The UI claimed it was ready, but didn't have any data for * us... It will call purple_xfer_ui_ready when ready, which * sets back up this watcher. */ if (xfer->watcher != 0) { purple_input_remove(xfer->watcher); xfer->watcher = 0; } /* Need to indicate the prpl is still ready... */ priv->ready |= PURPLE_XFER_READY_PRPL; g_return_if_reached(); } else if (tmp < 0) { purple_debug_error("filetransfer", "Unable to read whole buffer.\n"); purple_xfer_cancel_local(xfer); return; } result = tmp; } else { buffer = g_malloc(s); result = fread(buffer, 1, s, xfer->dest_fp); if (result != s) { purple_debug_error("filetransfer", "Unable to read whole buffer.\n"); purple_xfer_cancel_local(xfer); g_free(buffer); return; } } } if (priv->buffer) { g_byte_array_append(priv->buffer, buffer, result); g_free(buffer); buffer = priv->buffer->data; result = priv->buffer->len; } r = purple_xfer_write(xfer, buffer, result); if (r == -1) { purple_xfer_cancel_remote(xfer); if (!priv->buffer) /* We don't free buffer if priv->buffer is set, because in that case buffer doesn't belong to us. */ g_free(buffer); return; } else if (r == result) { /* * We managed to write the entire buffer. This means our * network is fast and our buffer is too small, so make it * bigger. */ purple_xfer_increase_buffer_size(xfer); } else { if (ui_ops && ui_ops->data_not_sent) ui_ops->data_not_sent(xfer, buffer + r, result - r); } if (priv->buffer) { /* * Remove what we wrote * If we wrote the whole buffer the byte array will be empty * Otherwise we'll keep what wasn't sent for next time. */ buffer = NULL; g_byte_array_remove_range(priv->buffer, 0, r); } } if (r > 0) { if (purple_xfer_get_size(xfer) > 0) xfer->bytes_remaining -= r; xfer->bytes_sent += r; if (xfer->ops.ack != NULL) xfer->ops.ack(xfer, buffer, r); g_free(buffer); if (ui_ops != NULL && ui_ops->update_progress != NULL) ui_ops->update_progress(xfer, purple_xfer_get_progress(xfer)); } if (purple_xfer_is_completed(xfer)) purple_xfer_end(xfer); }
static void do_transfer(PurpleXfer *xfer) { PurpleXferUiOps *ui_ops; guchar *buffer = NULL; gssize r = 0; ui_ops = purple_xfer_get_ui_ops(xfer); if (xfer->type == PURPLE_XFER_RECEIVE) { r = purple_xfer_read(xfer, &buffer); if (r > 0) { size_t wc; if (ui_ops && ui_ops->ui_write) wc = ui_ops->ui_write(xfer, buffer, r); else wc = fwrite(buffer, 1, r, xfer->dest_fp); if (wc != r) { purple_debug_error("filetransfer", "Unable to write whole buffer.\n"); purple_xfer_cancel_local(xfer); g_free(buffer); return; } if ((purple_xfer_get_size(xfer) > 0) && ((purple_xfer_get_bytes_sent(xfer)+r) >= purple_xfer_get_size(xfer))) purple_xfer_set_completed(xfer, TRUE); } else if(r < 0) { purple_xfer_cancel_remote(xfer); g_free(buffer); return; } } else if (xfer->type == PURPLE_XFER_SEND) { size_t result; size_t s = MIN(purple_xfer_get_bytes_remaining(xfer), xfer->current_buffer_size); /* this is so the prpl can keep the connection open if it needs to for some odd reason. */ if (s == 0) { if (xfer->watcher) { purple_input_remove(xfer->watcher); xfer->watcher = 0; } return; } if (ui_ops && ui_ops->ui_read) { gssize tmp = ui_ops->ui_read(xfer, &buffer, s); if (tmp == 0) { /* * UI isn't ready to send data. It will call * purple_xfer_ui_ready when ready, which sets back up this * watcher. */ if (xfer->watcher != 0) { purple_timeout_remove(xfer->watcher); xfer->watcher = 0; } return; } else if (tmp < 0) { purple_debug_error("filetransfer", "Unable to read whole buffer.\n"); purple_xfer_cancel_local(xfer); return; } result = tmp; } else { buffer = g_malloc0(s); result = fread(buffer, 1, s, xfer->dest_fp); if (result != s) { purple_debug_error("filetransfer", "Unable to read whole buffer.\n"); purple_xfer_cancel_local(xfer); g_free(buffer); return; } } /* Write as much as we're allowed to. */ r = purple_xfer_write(xfer, buffer, result); if (r == -1) { purple_xfer_cancel_remote(xfer); g_free(buffer); return; } else if (r < result) { if (ui_ops == NULL || (ui_ops->ui_read == NULL && ui_ops->ui_write == NULL)) { /* We have to seek back in the file now. */ fseek(xfer->dest_fp, r - s, SEEK_CUR); } else { ui_ops->data_not_sent(xfer, buffer + r, result - r); } } else { /* * We managed to write the entire buffer. This means our * network is fast and our buffer is too small, so make it * bigger. */ purple_xfer_increase_buffer_size(xfer); } } if (r > 0) { if (purple_xfer_get_size(xfer) > 0) xfer->bytes_remaining -= r; xfer->bytes_sent += r; if (xfer->ops.ack != NULL) xfer->ops.ack(xfer, buffer, r); g_free(buffer); if (ui_ops != NULL && ui_ops->update_progress != NULL) ui_ops->update_progress(xfer, purple_xfer_get_progress(xfer)); } if (purple_xfer_is_completed(xfer)) purple_xfer_end(xfer); }
void finch_xfer_dialog_update_xfer(PurpleXfer *xfer) { PurpleGntXferUiData *data; char *size_str, *remaining_str; time_t current_time; char prog_str[5]; double kb_sent; double kbps = 0.0; time_t elapsed, now; char *kbsec; gboolean send; if ((now = purple_xfer_get_end_time(xfer)) == 0) now = time(NULL); kb_sent = purple_xfer_get_bytes_sent(xfer) / 1024.0; elapsed = (purple_xfer_get_start_time(xfer) > 0 ? now - purple_xfer_get_start_time(xfer) : 0); kbps = (elapsed > 0 ? (kb_sent / elapsed) : 0); g_return_if_fail(xfer_dialog != NULL); g_return_if_fail(xfer != NULL); if ((data = FINCHXFER(xfer)) == NULL) return; if (data->in_list == FALSE || data->notified) return; current_time = time(NULL); if (((current_time - data->last_updated_time) == 0) && (!purple_xfer_is_completed(xfer))) { /* Don't update the window more than once per second */ return; } data->last_updated_time = current_time; send = (purple_xfer_get_type(xfer) == PURPLE_XFER_SEND); size_str = purple_str_size_to_units(purple_xfer_get_size(xfer)); remaining_str = purple_str_size_to_units(purple_xfer_get_bytes_remaining(xfer)); kbsec = g_strdup_printf(_("%.2f KiB/s"), kbps); gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_PROGRESS, g_ascii_dtostr(prog_str, sizeof(prog_str), purple_xfer_get_progress(xfer) * 100.)); gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_SIZE, size_str); gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_REMAINING, remaining_str); gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_SPEED, kbsec); g_free(size_str); g_free(remaining_str); g_free(kbsec); if (purple_xfer_is_completed(xfer)) { gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_STATUS, send ? _("Sent") : _("Received")); gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_REMAINING, _("Finished")); if (!send) { char *msg = g_strdup_printf(_("The file was saved as %s."), purple_xfer_get_local_filename(xfer)); purple_xfer_conversation_write(xfer, msg, FALSE); g_free(msg); } data->notified = TRUE; } else { gnt_tree_change_text(GNT_TREE(xfer_dialog->tree), xfer, COLUMN_STATUS, send ? _("Sending") : _("Receiving")); } update_title_progress(); if (purple_xfer_is_completed(xfer) && xfer_dialog->auto_clear) finch_xfer_dialog_remove_xfer(xfer); }
static void update_detailed_info(PidginXferDialog *dialog, PurpleXfer *xfer) { PidginXferUiData *data; char *kbsec, *time_elapsed, *time_remaining; char *status, *utf8; if (dialog == NULL || xfer == NULL) return; data = PIDGINXFER(xfer); get_xfer_info_strings(xfer, &kbsec, &time_elapsed, &time_remaining); status = g_strdup_printf("%d%% (%" G_GSIZE_FORMAT " of %" G_GSIZE_FORMAT " bytes)", (int)(purple_xfer_get_progress(xfer)*100), purple_xfer_get_bytes_sent(xfer), purple_xfer_get_size(xfer)); if (purple_xfer_is_completed(xfer)) { GdkPixbuf *pixbuf = NULL; pixbuf = gtk_widget_render_icon(xfer_dialog->window, PIDGIN_STOCK_FILE_DONE, GTK_ICON_SIZE_MENU, NULL); gtk_list_store_set(GTK_LIST_STORE(xfer_dialog->model), &data->iter, COLUMN_STATUS, pixbuf, -1); g_object_unref(pixbuf); } if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) { gtk_label_set_markup(GTK_LABEL(dialog->local_user_desc_label), _("<b>Receiving As:</b>")); gtk_label_set_markup(GTK_LABEL(dialog->remote_user_desc_label), _("<b>Receiving From:</b>")); } else { gtk_label_set_markup(GTK_LABEL(dialog->remote_user_desc_label), _("<b>Sending To:</b>")); gtk_label_set_markup(GTK_LABEL(dialog->local_user_desc_label), _("<b>Sending As:</b>")); } gtk_label_set_text(GTK_LABEL(dialog->local_user_label), purple_account_get_username(xfer->account)); gtk_label_set_text(GTK_LABEL(dialog->remote_user_label), xfer->who); gtk_label_set_text(GTK_LABEL(dialog->protocol_label), purple_account_get_protocol_name(xfer->account)); if (purple_xfer_get_type(xfer) == PURPLE_XFER_RECEIVE) { gtk_label_set_text(GTK_LABEL(dialog->filename_label), purple_xfer_get_filename(xfer)); } else { char *tmp; tmp = g_path_get_basename(purple_xfer_get_local_filename(xfer)); utf8 = g_filename_to_utf8(tmp, -1, NULL, NULL, NULL); g_free(tmp); gtk_label_set_text(GTK_LABEL(dialog->filename_label), utf8); g_free(utf8); } utf8 = g_filename_to_utf8((purple_xfer_get_local_filename(xfer)), -1, NULL, NULL, NULL); gtk_label_set_text(GTK_LABEL(dialog->localfile_label), utf8); g_free(utf8); gtk_label_set_text(GTK_LABEL(dialog->status_label), status); gtk_label_set_text(GTK_LABEL(dialog->speed_label), kbsec); gtk_label_set_text(GTK_LABEL(dialog->time_elapsed_label), time_elapsed); gtk_label_set_text(GTK_LABEL(dialog->time_remaining_label), time_remaining); gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(dialog->progress), purple_xfer_get_progress(xfer)); g_free(kbsec); g_free(time_elapsed); g_free(time_remaining); g_free(status); }
void pidgin_xfer_dialog_update_xfer(PidginXferDialog *dialog, PurpleXfer *xfer) { PidginXferUiData *data; char *size_str, *remaining_str; GtkTreeSelection *selection; time_t current_time; GtkTreeIter iter; gboolean valid; g_return_if_fail(dialog != NULL); g_return_if_fail(xfer != NULL); if ((data = PIDGINXFER(xfer)) == NULL) return; if (data->in_list == FALSE) return; current_time = time(NULL); if (((current_time - data->last_updated_time) == 0) && (!purple_xfer_is_completed(xfer))) { /* Don't update the window more than once per second */ return; } data->last_updated_time = current_time; size_str = purple_str_size_to_units(purple_xfer_get_size(xfer)); remaining_str = purple_str_size_to_units(purple_xfer_get_bytes_remaining(xfer)); gtk_list_store_set(xfer_dialog->model, &data->iter, COLUMN_PROGRESS, purple_xfer_get_progress(xfer), COLUMN_SIZE, size_str, COLUMN_REMAINING, remaining_str, -1); g_free(size_str); g_free(remaining_str); if (purple_xfer_is_completed(xfer)) { GdkPixbuf *pixbuf; pixbuf = gtk_widget_render_icon(dialog->window, PIDGIN_STOCK_FILE_DONE, GTK_ICON_SIZE_MENU, NULL); gtk_list_store_set(GTK_LIST_STORE(xfer_dialog->model), &data->iter, COLUMN_STATUS, pixbuf, COLUMN_REMAINING, _("Finished"), -1); g_object_unref(pixbuf); } selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(xfer_dialog->tree)); update_title_progress(dialog); if (xfer == dialog->selected_xfer) update_detailed_info(xfer_dialog, xfer); if (purple_xfer_is_completed(xfer) && dialog->auto_clear) pidgin_xfer_dialog_remove_xfer(dialog, xfer); else update_buttons(dialog, xfer); /* * If all transfers are finished, and the pref is set, then * close the dialog. Otherwise just exit this function. */ if (dialog->keep_open) return; valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(dialog->model), &iter); while (valid) { GValue val; PurpleXfer *next; val.g_type = 0; gtk_tree_model_get_value(GTK_TREE_MODEL(dialog->model), &iter, COLUMN_DATA, &val); next = g_value_get_pointer(&val); if (!purple_xfer_is_completed(next)) return; valid = gtk_tree_model_iter_next(GTK_TREE_MODEL(dialog->model), &iter); } /* If we got to this point then we know everything is finished */ pidgin_xfer_dialog_hide(dialog); }