diff options
Diffstat (limited to 'libempathy-gtk/empathy-ui-utils.c')
-rw-r--r-- | libempathy-gtk/empathy-ui-utils.c | 253 |
1 files changed, 251 insertions, 2 deletions
diff --git a/libempathy-gtk/empathy-ui-utils.c b/libempathy-gtk/empathy-ui-utils.c index 69b50e266..088518c94 100644 --- a/libempathy-gtk/empathy-ui-utils.c +++ b/libempathy-gtk/empathy-ui-utils.c @@ -664,6 +664,20 @@ empathy_pixbuf_protocol_from_contact_scaled (EmpathyContact *contact, return pixbuf; } +struct SendData +{ + GFile *file; + GFile *destination; + GCancellable *cancellable; + EmpathyContact *contact; + GtkWidget *dialog; + GtkProgressBar *progress; + GtkLabel *progress_label; + GtkLabel *filename_label; + gboolean dialog_shown; + gint64 last_notify; +}; + void empathy_url_show (GtkWidget *parent, const char *url) @@ -701,8 +715,8 @@ empathy_url_show (GtkWidget *parent, g_free (real_url); } -void -empathy_send_file (EmpathyContact *contact, +static void +send_file (EmpathyContact *contact, GFile *file) { EmpathyFTFactory *factory; @@ -725,6 +739,226 @@ empathy_send_file (EmpathyContact *contact, g_object_unref (factory); } +static void +send_data_free (struct SendData *send_data) +{ + g_clear_object (&(send_data->file)); + g_clear_object (&(send_data->destination)); + g_clear_object (&(send_data->contact)); + g_clear_object (&(send_data->cancellable)); + if (send_data->dialog != NULL) + gtk_widget_destroy (send_data->dialog); + g_free (send_data); +} + +static void +send_file_autoar_decide_dest_cb (AutoarCreate *arcreate, + GFile *destination, + struct SendData *send_data) +{ + send_data->destination = g_object_ref (destination); +} + +static void +send_file_autoar_dialog_response_cb (GtkDialog *dialog, + gint response_id, + struct SendData *send_data) +{ + if (response_id == GTK_RESPONSE_CANCEL) + g_cancellable_cancel (send_data->cancellable); +} + +static void +send_file_autoar_create_dialog (struct SendData *send_data) +{ + GtkWidget *content; + GtkBox *vbox; + char *str, *filename, *destname; + + send_data->dialog = gtk_dialog_new_with_buttons ( + _("Creating Archives…"), NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + _("Cancel"), GTK_RESPONSE_CANCEL, + NULL); + send_data->progress = GTK_PROGRESS_BAR (gtk_progress_bar_new ()); + send_data->progress_label = GTK_LABEL (gtk_label_new (NULL)); + + str = g_strdup_printf ("%s -> %s", + filename = autoar_common_g_file_get_name (send_data->file), + destname = autoar_common_g_file_get_name (send_data->destination)); + send_data->filename_label = GTK_LABEL (gtk_label_new (str)); + + vbox = GTK_BOX (gtk_box_new (GTK_ORIENTATION_VERTICAL, 5)); + gtk_box_pack_start (vbox, GTK_WIDGET (send_data->filename_label), + FALSE, FALSE, 0); + gtk_box_pack_start (vbox, GTK_WIDGET (send_data->progress), + FALSE, FALSE, 0); + gtk_box_pack_start (vbox, GTK_WIDGET (send_data->progress_label), + FALSE, FALSE, 0); + content = gtk_dialog_get_content_area (GTK_DIALOG (send_data->dialog)); + gtk_container_add (GTK_CONTAINER (content), GTK_WIDGET (vbox)); + + g_signal_connect (send_data->dialog, "response", + G_CALLBACK (send_file_autoar_dialog_response_cb), send_data); + + g_free (str); + g_free (filename); + g_free (destname); +} + +static void +send_file_autoar_progress_cb (AutoarCreate *arcreate, + guint64 completed_size, + guint completed_files, + struct SendData *send_data) +{ + gint64 mtime; + + DEBUG ("%s: size = %" G_GUINT64_FORMAT ", files = %u", + __func__, completed_size, completed_files); + + mtime = g_get_monotonic_time (); + if (mtime - send_data->last_notify < 200000) + return; + + send_data->last_notify = mtime; + + if (!(send_data->dialog_shown)) + { + if (send_data->dialog == NULL) + send_file_autoar_create_dialog (send_data); + gtk_widget_show_all (send_data->dialog); + send_data->dialog_shown = TRUE; + } + + if (send_data->progress != NULL) + gtk_progress_bar_pulse (send_data->progress); + + if (send_data->progress_label != NULL) + { + gchar *msg, *size; + msg = g_strdup_printf ( + _("%u files (%s) are archived"), + completed_files, size = g_format_size (completed_size)); + gtk_label_set_text (send_data->progress_label, msg); + g_free (msg); + g_free (size); + } +} + +static void +send_file_autoar_cancelled_cb (AutoarCreate *arcreate, + struct SendData *send_data) +{ + send_data_free (send_data); +} + +static void +send_file_autoar_completed_cb (AutoarCreate *arcreate, + struct SendData *send_data) +{ + send_file (send_data->contact, send_data->destination); + send_data_free (send_data); +} + +static void +send_file_autoar_error_cb (AutoarCreate *arcreate, + GError *error, + struct SendData *send_data) +{ + GtkWidget *error_dialog; + char *filename; + + error_dialog = gtk_message_dialog_new_with_markup ( + NULL, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, + "<big><b>%s</b></big>", + filename = autoar_common_g_file_get_name (send_data->file)); + gtk_message_dialog_format_secondary_text ( + GTK_MESSAGE_DIALOG (error_dialog), "%s", error->message); + gtk_widget_show_all (error_dialog); + g_signal_connect_swapped (error_dialog, "response", + G_CALLBACK (gtk_widget_destroy), error_dialog); + + send_data_free (send_data); + g_free (filename); +} + +static void +send_file_info_ready_cb (GFile *file, + GAsyncResult *res, + EmpathyContact *contact) +{ + GFileInfo *file_info; + GFileType file_type; + + file_info = g_file_query_info_finish (file, res, NULL); + if (file_info == NULL) + return; + + file_type = g_file_info_get_file_type (file_info); + g_object_unref (file_info); + + if (file_type == G_FILE_TYPE_DIRECTORY) + { + struct SendData *send_data; + AutoarPref *arpref; + AutoarCreate *arcreate; + gchar *template; + GFile *archive_dir; + gchar *archive_dir_path; + + arpref = g_object_get_data (G_OBJECT (contact), "autoar-pref"); + template = g_strdup_printf ("empathy-%s-XXXXXX", g_get_user_name ()); + archive_dir_path = g_dir_make_tmp (template, NULL); + if (archive_dir_path == NULL) + { + g_free (template); + return; + } + + DEBUG ("tmpdir = %s", archive_dir_path); + archive_dir = g_file_new_for_path (archive_dir_path); + arcreate = autoar_create_new_file (arpref, archive_dir, file, NULL); + send_data = g_new0 (struct SendData, 1); + send_data->contact = g_object_ref (contact); + send_data->file = g_object_ref (file); + send_data->cancellable = g_cancellable_new (); + send_data->last_notify = g_get_monotonic_time (); + + g_signal_connect (arcreate, "decide-dest", + G_CALLBACK (send_file_autoar_decide_dest_cb), send_data); + g_signal_connect (arcreate, "progress", + G_CALLBACK (send_file_autoar_progress_cb), send_data); + g_signal_connect (arcreate, "cancelled", + G_CALLBACK (send_file_autoar_cancelled_cb), send_data); + g_signal_connect (arcreate, "completed", + G_CALLBACK (send_file_autoar_completed_cb), send_data); + g_signal_connect (arcreate, "error", + G_CALLBACK (send_file_autoar_error_cb), send_data); + autoar_create_start_async (arcreate, send_data->cancellable); + + g_free (template); + g_free (archive_dir_path); + g_object_unref (archive_dir); + g_object_unref (arcreate); + } + else + { + send_file (contact, file); + } +} + +void +empathy_send_file (EmpathyContact *contact, + GFile *file) +{ + g_file_query_info_async (file, + G_FILE_ATTRIBUTE_STANDARD_TYPE, + G_FILE_QUERY_INFO_NONE, G_PRIORITY_DEFAULT, + NULL, (GAsyncReadyCallback) send_file_info_ready_cb, contact); +} + void empathy_send_file_from_uri_list (EmpathyContact *contact, const gchar *uri_list) @@ -764,11 +998,20 @@ file_manager_send_file_response_cb (GtkDialog *widget, EmpathyContact *contact) { GFile *file; + GtkWidget *format; + AutoarPref *arpref; + int arformat, arfilter; if (response_id == GTK_RESPONSE_OK || response_id == EMPATHY_RESPONSE_SEND) { file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (widget)); + arpref = g_object_get_data (G_OBJECT (contact), "autoar-pref"); + format = g_object_get_data (G_OBJECT (contact), "autoar-format"); + autoar_gtk_format_filter_simple_get (format, &arformat, &arfilter); + autoar_pref_set_default_format (arpref, arformat); + autoar_pref_set_default_filter (arpref, arfilter); + empathy_send_file (contact, file); g_object_unref (file); @@ -860,8 +1103,14 @@ empathy_send_file_with_file_chooser (EmpathyContact *contact) g_signal_connect (widget, "response", G_CALLBACK (file_manager_send_file_response_cb), g_object_ref (contact)); + g_object_set_data_full (G_OBJECT (contact), "autoar-pref", + g_object_ref (arpref), g_object_unref); + g_object_set_data_full (G_OBJECT (contact), "autoar-format", + g_object_ref (format_combo), g_object_unref); gtk_widget_show (widget); + g_object_unref (settings); + g_object_unref (arpref); } static void |