diff options
Diffstat (limited to 'tests/poppler/glib/demo/attachments.c')
-rw-r--r-- | tests/poppler/glib/demo/attachments.c | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/tests/poppler/glib/demo/attachments.c b/tests/poppler/glib/demo/attachments.c new file mode 100644 index 00000000..63565dd8 --- /dev/null +++ b/tests/poppler/glib/demo/attachments.c @@ -0,0 +1,353 @@ +/* + * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <gtk/gtk.h> + +#include "attachments.h" +#include "utils.h" + +enum { + ATTACHMENTS_NAME_COLUMN, + ATTACHMENTS_DESCRIPTION_COLUMN, + ATTACHMENTS_SIZE_COLUMN, + ATTACHMENTS_CTIME_COLUMN, + ATTACHMENTS_MTIME_COLUMN, + ATTACHMENTS_ATTACHMENT_COLUMN, + N_COLUMNS +}; + +static void +pgd_attachments_fill_model (GtkListStore *model, + PopplerDocument *document) +{ + GList *list, *l; + + list = poppler_document_get_attachments (document); + + for (l = list; l && l->data; l = g_list_next (l)) { + PopplerAttachment *attachment = POPPLER_ATTACHMENT (l->data); + GtkTreeIter iter; + gchar *size; + gchar *ctime, *mtime; + + size = g_strdup_printf ("%" G_GSIZE_FORMAT, attachment->size); + ctime = pgd_format_date (attachment->ctime); + mtime = pgd_format_date (attachment->mtime); + + gtk_list_store_append (model, &iter); + gtk_list_store_set (model, &iter, + ATTACHMENTS_NAME_COLUMN, + attachment->name ? attachment->name : "Unknown", + ATTACHMENTS_DESCRIPTION_COLUMN, + attachment->description ? attachment->description : "Unknown", + ATTACHMENTS_SIZE_COLUMN, + size ? size : "Unknown", + ATTACHMENTS_CTIME_COLUMN, + ctime ? ctime : "Unknown", + ATTACHMENTS_MTIME_COLUMN, + mtime ? mtime : "Unknown", + ATTACHMENTS_ATTACHMENT_COLUMN, attachment, + -1); + + g_free (size); + g_free (ctime); + g_free (mtime); + + g_object_unref (attachment); + } + + g_list_free (list); +} + +static GtkWidget * +pgd_attachments_create_list (GtkTreeModel *model) +{ + GtkWidget *treeview; + GtkCellRenderer *renderer; + + treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), TRUE); + gtk_tree_view_set_rules_hint (GTK_TREE_VIEW (treeview), TRUE); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + 0, "Name", + renderer, + "text", ATTACHMENTS_NAME_COLUMN, + NULL); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + 1, "Description", + renderer, + "text", ATTACHMENTS_DESCRIPTION_COLUMN, + NULL); + g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL); + g_object_set (G_OBJECT (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 1)), + "expand", TRUE, NULL); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + 2, "Size", + renderer, + "text", ATTACHMENTS_SIZE_COLUMN, + NULL); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + 3, "Creation Date", + renderer, + "text", ATTACHMENTS_CTIME_COLUMN, + NULL); + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + 4, "Modification Date", + renderer, + "text", ATTACHMENTS_MTIME_COLUMN, + NULL); + return treeview; +} + +static void +pgd_attachments_save_dialog_response (GtkFileChooser *file_chooser, + gint response, + PopplerAttachment *attachment) +{ + gchar *filename; + GError *error = NULL; + + if (response != GTK_RESPONSE_ACCEPT) { + g_object_unref (attachment); + gtk_widget_destroy (GTK_WIDGET (file_chooser)); + return; + } + + filename = gtk_file_chooser_get_filename (file_chooser); + if (!poppler_attachment_save (attachment, filename, &error)) { + g_warning ("%s", error->message); + g_error_free (error); + } + g_free (filename); + g_object_unref (attachment); + gtk_widget_destroy (GTK_WIDGET (file_chooser)); +} + +static void +pgd_attachments_save_button_clicked (GtkButton *button, + GtkTreeView *treeview) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + GtkWidget *file_chooser; + PopplerAttachment *attachment; + + selection = gtk_tree_view_get_selection (treeview); + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + + gtk_tree_model_get (model, &iter, + ATTACHMENTS_ATTACHMENT_COLUMN, &attachment, + -1); + + if (!attachment) + return; + + file_chooser = gtk_file_chooser_dialog_new ("Save attachment", + GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (treeview))), + GTK_FILE_CHOOSER_ACTION_SAVE, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT, + NULL); + gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (file_chooser), attachment->name); + g_signal_connect (G_OBJECT (file_chooser), "response", + G_CALLBACK (pgd_attachments_save_dialog_response), + (gpointer) attachment); + gtk_widget_show (file_chooser); + +} + +static gboolean +attachment_save_callback (const gchar *buf, + gsize count, + gpointer data, + GError **error) +{ + GChecksum *cs = (GChecksum *)data; + + g_checksum_update (cs, buf, count); + + return TRUE; +} + +static void +message_dialog_run (GtkWindow *parent, + const gchar *message) +{ + GtkWidget *dialog; + + dialog = gtk_message_dialog_new (parent, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_CLOSE, + "%s", message); + gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_destroy (dialog); +} + +static void +pgd_attachments_validate_button_clicked (GtkButton *button, + GtkTreeView *treeview) +{ + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + GChecksum *cs; + guint8 *digest; + gsize digest_len; + PopplerAttachment *attachment; + gboolean valid = TRUE; + + selection = gtk_tree_view_get_selection (treeview); + if (!gtk_tree_selection_get_selected (selection, &model, &iter)) + return; + + gtk_tree_model_get (model, &iter, + ATTACHMENTS_ATTACHMENT_COLUMN, &attachment, + -1); + + if (!attachment) + return; + + if (attachment->checksum->len == 0) { + message_dialog_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (treeview))), + "Impossible to validate attachment: checksum is not available"); + g_object_unref (attachment); + + return; + } + + cs = g_checksum_new (G_CHECKSUM_MD5); + poppler_attachment_save_to_callback (attachment, attachment_save_callback, + (gpointer)cs, NULL); + digest_len = g_checksum_type_get_length (G_CHECKSUM_MD5); + digest = (guint8 *) g_malloc (digest_len); + g_checksum_get_digest (cs, digest, &digest_len); + g_checksum_free (cs); + + if (attachment->checksum->len == digest_len) { + gint i; + + for (i = 0; i < digest_len; i++) { + if ((guint8)attachment->checksum->str[i] != digest[i]) { + valid = FALSE; + break; + } + } + } + + if (valid) { + message_dialog_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (treeview))), + "Attachment is valid"); + } else { + message_dialog_run (GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (treeview))), + "Attachment is not valid: the checksum does not match"); + } + + g_free (digest); + g_object_unref (attachment); +} + +GtkWidget * +pgd_attachments_create_widget (PopplerDocument *document) +{ + GtkWidget *vbox; + GtkWidget *treeview; + GtkListStore *model; + GtkWidget *swindow; + GtkWidget *hbox, *button; + gboolean has_attachments; + + vbox = gtk_vbox_new (FALSE, 12); + + swindow = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow), + GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + + has_attachments = poppler_document_has_attachments (document); + if (has_attachments) { + model = gtk_list_store_new (N_COLUMNS, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_STRING, + G_TYPE_STRING, G_TYPE_STRING, + G_TYPE_OBJECT); + pgd_attachments_fill_model (model, document); + treeview = pgd_attachments_create_list (GTK_TREE_MODEL (model)); + } else { + GtkCellRenderer *renderer; + GtkTreeIter iter; + gchar *markup; + + model = gtk_list_store_new (1, G_TYPE_STRING); + gtk_list_store_append (model, &iter); + markup = g_strdup_printf ("<span size=\"larger\" style=\"italic\">%s</span>", + "The document doesn't contain attachments"); + gtk_list_store_set (model, &iter, 0, markup, -1); + g_free (markup); + + treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); + + renderer = gtk_cell_renderer_text_new (); + gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), + 0, "Name", + renderer, + "markup", 0, + NULL); + } + g_object_unref (model); + + gtk_container_add (GTK_CONTAINER (swindow), treeview); + gtk_widget_show (treeview); + + gtk_box_pack_start (GTK_BOX (vbox), swindow, TRUE, TRUE, 0); + gtk_widget_show (swindow); + + if (!has_attachments) + return vbox; + + hbox = gtk_hbutton_box_new (); + gtk_button_box_set_layout (GTK_BUTTON_BOX (hbox), GTK_BUTTONBOX_SPREAD); + + button = gtk_button_new_with_label ("Save"); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (pgd_attachments_save_button_clicked), + (gpointer)treeview); + + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + button = gtk_button_new_with_label ("Validate"); + g_signal_connect (G_OBJECT (button), "clicked", + G_CALLBACK (pgd_attachments_validate_button_clicked), + (gpointer)treeview); + + gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 6); + gtk_widget_show (hbox); + + return vbox; +} |