#ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include #include #include #include "claws.h" #include "version.h" #include "main.h" #include "plugin.h" #include "utils.h" #include "mimeview.h" #include "messageview.h" #include "prefs_common.h" #include "log.h" #include "codeconv.h" #include "menu.h" #include "defs.h" #ifdef USE_PTHREAD #include #endif #define FAIL(msg) \ do { fprintf (stderr, "FAIL: %s\n", msg); exit (-1); } while (0) struct _PopplerViewer { MimeViewer mimeviewer; GtkWidget *pdf_view; GtkWidget *scrollwin; PopplerDocument *pdf_doc; PopplerPage *pdf_page; gchar *filename; gchar *fsname; double width; double height; MimeInfo *mimeinfo; MimeInfo *to_load; GMutex *mutex; }; typedef struct _PopplerViewer PopplerViewer; static MimeViewerFactory poppler_viewer_factory; static GtkWidget *poppler_get_widget(MimeViewer *_viewer) { PopplerViewer *viewer = (PopplerViewer *) _viewer; debug_print("poppler_get_widget: %p\n", viewer->scrollwin); return GTK_WIDGET(viewer->scrollwin); } static gint poppler_show_mimepart_real(MimeViewer *_viewer) { PopplerViewer *viewer = (PopplerViewer *) _viewer; gchar buf[4096]; const gchar *charset = NULL; MessageView *messageview = ((MimeViewer *)viewer)->mimeview ? ((MimeViewer *)viewer)->mimeview->messageview : NULL; MimeInfo *partinfo = viewer->to_load; memset(buf, 0, sizeof(buf)); messageview->updating = TRUE; debug_print("poppler_show_mimepart\n"); if (viewer->filename != NULL) { g_unlink(viewer->filename); g_free(viewer->filename); viewer->filename = NULL; } viewer->mimeinfo = NULL; if (messageview) { NoticeView *noticeview = messageview->noticeview; noticeview_hide(noticeview); } if (partinfo) { viewer->filename = procmime_get_tmp_file_name(partinfo); viewer->fsname = g_strconcat("file://", viewer->filename, NULL); } if (partinfo && !(procmime_get_part(viewer->filename, partinfo) < 0)) { if (_viewer && _viewer->mimeview && _viewer->mimeview->messageview->forced_charset) charset = _viewer->mimeview->messageview->forced_charset; else charset = procmime_mimeinfo_get_parameter(partinfo, "charset"); if (charset == NULL) charset = conv_get_locale_charset_str(); debug_print("using charset %s\n", charset); viewer->mimeinfo = partinfo; } g_mutex_lock(viewer->mutex); g_mutex_unlock(viewer->mutex); messageview->updating = TRUE; return FALSE; } static void poppler_pdf_view_new(MimeViewer *_viewer) { PopplerViewer *viewer = (PopplerViewer *) _viewer; GError *error; GtkImage *im; GdkPixbuf *pb; error = NULL; viewer->pdf_doc = poppler_document_new_from_file( viewer->fsname, NULL, &error); if (viewer->pdf_doc == NULL) FAIL (error->message); viewer->pdf_page = poppler_document_get_page_by_label (viewer->pdf_doc, "1"); if (viewer->pdf_page == NULL) FAIL ("Page not found"); poppler_page_get_size(viewer->pdf_page, &viewer->width, &viewer->height); //pb = gdk_pixbuf_new_from_file("/opt/media/pics/Linside.jpg",NULL); pb = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, 220, 220); gdk_pixbuf_fill (pb, 0x00106000); poppler_page_render_to_pixbuf (viewer->pdf_page, 100, 100, 200, 200, 1, 0, pb); viewer->pdf_view = gtk_image_new_from_pixbuf(pb); } static void poppler_show_mimepart(MimeViewer *_viewer, const gchar *infile, MimeInfo *partinfo) { PopplerViewer *viewer = (PopplerViewer *) _viewer; viewer->to_load = partinfo; gtk_timeout_add(5, (GtkFunction)poppler_show_mimepart_real, viewer); } static void poppler_clear_viewer(MimeViewer *_viewer) { PopplerViewer *viewer = (PopplerViewer *) _viewer; GtkAdjustment *vadj; debug_print("poppler_clear_viewer\n"); viewer->to_load = NULL; vadj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(viewer->scrollwin)); vadj->value = 0.0; g_signal_emit_by_name(G_OBJECT(vadj), "value-changed", 0); } static void poppler_destroy_viewer(MimeViewer *_viewer) { PopplerViewer *viewer = (PopplerViewer *) _viewer; debug_print("poppler_destroy_viewer\n"); gtk_widget_unref(GTK_WIDGET(viewer->pdf_view)); gtk_widget_unref(GTK_WIDGET(viewer->scrollwin)); g_unlink(viewer->filename); g_free(viewer->filename); g_free(viewer); } static MimeViewer *poppler_viewer_create(void) { PopplerViewer *viewer; debug_print("poppler_viewer_create\n"); viewer = g_new0(PopplerViewer, 1); viewer->mimeviewer.factory = &poppler_viewer_factory; viewer->mimeviewer.get_widget = poppler_get_widget; viewer->mimeviewer.show_mimepart = poppler_show_mimepart; viewer->mimeviewer.clear_viewer = poppler_clear_viewer; viewer->mimeviewer.destroy_viewer = poppler_destroy_viewer; viewer->scrollwin = gtk_scrolled_window_new(NULL, NULL); viewer->mimeinfo = NULL; viewer->pdf_view = poppler_pdf_view_new; viewer->mutex = g_mutex_new(); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(viewer->scrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(viewer->scrollwin), GTK_SHADOW_IN); gtk_container_add( GTK_CONTAINER(viewer->scrollwin), viewer->pdf_view); gtk_widget_show(GTK_WIDGET(viewer->scrollwin)); gtk_widget_ref(GTK_WIDGET(viewer->scrollwin)); gtk_widget_show(GTK_WIDGET(viewer->pdf_view)); gtk_widget_ref(GTK_WIDGET(viewer->pdf_view)); viewer->filename = NULL; return (MimeViewer *) viewer; } static gchar *content_types[] = {"application/pdf", NULL}; static MimeViewerFactory poppler_viewer_factory = { content_types, 0, poppler_viewer_create, }; gint plugin_init(gchar **error) { if (!check_plugin_version(MAKE_NUMERIC_VERSION(2, 7, 2, 2), VERSION_NUMERIC, "PDF Viewer", error)) return -1; mimeview_register_viewer_factory(&poppler_viewer_factory); return 0; } void plugin_done(void) { mimeview_unregister_viewer_factory(&poppler_viewer_factory); } const gchar *plugin_name(void) { return ("PDF Viewer"); } const gchar *plugin_desc(void) { return ("This plugin renders PDF attachments in mails using the poppler lib..\n" "The extended name is Red Poppler PDF Viewer" ); } const gchar *plugin_type(void) { return "GTK2"; } const gchar *plugin_licence(void) { return "GPL"; } const gchar *plugin_version(void) { return PLUGINVERSION; } struct PluginFeature *plugin_provides(void) { static struct PluginFeature features[] = { {PLUGIN_MIMEVIEWER, "application/pdf"}, {PLUGIN_NOTHING, NULL} }; return features; }