/* * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client * Copyright (C) 1999-2007 the Claws Mail Team * This file Copyright (C) 2007 Salvatore De Paolis * * * 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 of the License, 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. */ #ifdef HAVE_CONFIG_H # include "config.h" #endif #include #include #include #include #include "gettext.h" #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" #include "gtkutils.h" #include "alertpanel.h" #include "first_arrow.xpm" #include "last_arrow.xpm" #include "left_arrow.xpm" #include "right_arrow.xpm" #include "zoom_fit.xpm" #include "zoom_in.xpm" #include "zoom_out.xpm" #include "zoom_width.xpm" #include "rotate_right.xpm" #include "rotate_left.xpm" #include "doc_info.xpm" #include "doc_index.xpm" #ifdef USE_PTHREAD #include #endif #define ZOOM_FACTOR 0.3 #define ROTATION 90 static void poppler_pdf_view_update(MimeViewer *_viewer, gboolean reload_file, int page_num); static gchar *msg = NULL; struct _PopplerTextSearch { GList *text_found; int page_id; }; typedef struct _PopplerTextSearch PopplerTextSearch; struct _PopplerViewer { MimeViewer mimeviewer; GtkWidget *buttons_table; GtkWidget *vbox; GtkWidget *hbox; GtkWidget *frame_index; GtkWidget *pdf_view; GtkWidget *scrollwin; GtkWidget *scrollwin_index; GtkWidget *icon_type; GdkPixmap *icon_pixmap; GdkBitmap *icon_bitmap; GtkWidget *doc_label; GtkWidget *cur_page; GtkWidget *doc_index_pane; GtkWidget *index_list; /* begin GtkButtons */ GtkWidget *first_page; GtkWidget *last_page; GtkWidget *prev_page; GtkWidget *next_page; GtkWidget *zoom_in; GtkWidget *zoom_out; GtkWidget *zoom_fit; GtkWidget *zoom_width; GtkWidget *rotate_left; GtkWidget *rotate_right; GtkWidget *doc_info; GtkWidget *doc_index; /* end GtkButtons */ GtkTable *table_doc_info; GtkTooltips *button_bar_tips; PopplerDocument *pdf_doc; PopplerPage *pdf_page; PopplerIndexIter *pdf_index; PopplerRectangle *text_found_coord; GtkTreeModel *index_model; PopplerTextSearch **text_found; const gchar *last_search; gboolean search_first; gchar *target_filename; gchar *filename; gchar *fsname; gchar *doc_info_text; gint rotate; gint num_pages; double zoom; double width; double height; MimeInfo *mimeinfo; MimeInfo *to_load; }; typedef enum { TYPE_UNKNOWN, TYPE_PDF, TYPE_PS } FileType; enum { INDEX_NAME, INDEX_PAGE, INDEX_TOP, N_INDEX_COLUMNS }; 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->vbox); return GTK_WIDGET(viewer->vbox); } /** Hide the index panel */ static void poppler_hide_index_pane(PopplerViewer *viewer) { if(viewer->pdf_index) { poppler_index_iter_free(viewer->pdf_index); viewer->pdf_index = NULL; gtk_widget_hide(GTK_WIDGET(viewer->frame_index)); } } static void poppler_search_render(GtkWidget *spin, PopplerTextSearch **tf, PopplerRectangle *rect, gboolean direction, gboolean first) { if( (first && direction) || (first && !direction) ) gtk_spin_button_spin(GTK_SPIN_BUTTON(spin),GTK_SPIN_HOME, 1); if(!first && direction) gtk_spin_button_spin(GTK_SPIN_BUTTON(spin),GTK_SPIN_STEP_FORWARD, 1); if(!first && !direction) gtk_spin_button_spin(GTK_SPIN_BUTTON(spin),GTK_SPIN_STEP_BACKWARD, 1); } static void poppler_text_search_init(PopplerDocument *doc, PopplerPage *page, PopplerTextSearch **tf, gint pages, GtkWidget *c_page, const gchar *str) { gint i; gint j = 0; /* Dynamically allocate memory PopplerTextSearch */ if (!(tf = (PopplerTextSearch **)malloc(pages * sizeof(PopplerTextSearch)))) { g_printf("Error. Unable to allocate text_found struct.\n"); exit(1); } /* Fill the PopplerTextSearch structure*/ main_window_cursor_wait(mainwindow_get_mainwindow()); if(!c_page){ debug_print("page not initialized\n"); exit(1); } i = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(c_page)); while (i < pages) { debug_print("STR: %s\n", str); page = poppler_document_get_page_by_label(doc, g_strdup_printf("%d",i)); debug_print("STR2: %s\n", str); if(poppler_page_find_text(page, str)) { tf[j]->text_found = poppler_page_find_text(page, str); tf[j]->page_id = i; j += 1; } i += 1; } debug_print("end of loop\n"); main_window_cursor_normal(mainwindow_get_mainwindow()); } static void poppler_text_search_destroy(PopplerTextSearch **pts, gboolean first) { /* Free PopplerTextSearch struct */ debug_print("viewer->text_found free\n"); free(pts); first = FALSE; } static gboolean poppler_text_search (MimeViewer *_viewer, gboolean backward, const gchar *str, gboolean case_sens) { PopplerViewer *viewer = (PopplerViewer *)_viewer; /* Search navigation */ if(!viewer->search_first) { poppler_text_search_init(viewer->pdf_doc, viewer->pdf_page, viewer->text_found, viewer->num_pages, viewer->cur_page, str); poppler_search_render(viewer->cur_page, viewer->text_found, viewer->text_found_coord, TRUE, FALSE); viewer->search_first = TRUE; } if (backward) poppler_search_render(viewer->cur_page, viewer->text_found, viewer->text_found_coord, FALSE, FALSE); else poppler_search_render(viewer->cur_page, viewer->text_found, viewer->text_found_coord, TRUE, FALSE); return TRUE; } static void poppler_get_document_index(PopplerViewer *viewer, PopplerIndexIter *index_iter, GtkTreeIter *parentiter) { PopplerAction *action; PopplerIndexIter *child; GtkTreeIter childiter; do { gint page_num = 0; action = poppler_index_iter_get_action (index_iter); if (action->type != POPPLER_ACTION_GOTO_DEST) { poppler_action_free(action); continue; } if (action->goto_dest.dest->type == POPPLER_DEST_XYZ) page_num = action->goto_dest.dest->page_num; #ifdef HAVE_POPPLER_DEST_NAMED else if (action->goto_dest.dest->type == POPPLER_DEST_NAMED) { PopplerDest *dest = poppler_document_find_dest( viewer->pdf_doc, action->goto_dest.dest->named_dest); if (dest->type != POPPLER_DEST_XYZ) { g_warning("couldn't figure out link\n"); poppler_dest_free(dest); continue; } page_num = dest->page_num; poppler_dest_free(dest); } #endif else { #ifdef HAVE_POPPLER_DEST_NAMED g_warning("unhandled link type %d\nplease contact developers\n", action->goto_dest.dest->type); #else g_warning("unhandled link type %d\nplease upgrade libpoppler-glib to 0.5.4\n", action->goto_dest.dest->type); #endif continue; } gtk_tree_store_append(GTK_TREE_STORE(viewer->index_model), &childiter, parentiter); gtk_tree_store_set(GTK_TREE_STORE(viewer->index_model), &childiter, INDEX_NAME, action->named.title, INDEX_PAGE, page_num, INDEX_TOP, action->goto_dest.dest->top, -1); poppler_action_free (action); child = poppler_index_iter_get_child (index_iter); if (child) { poppler_get_document_index (viewer, child, &childiter); poppler_index_iter_free (child); } } while (poppler_index_iter_next (index_iter)); } static void poppler_index_row_activated(GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer data) { GtkTreeIter iter; GtkTreeModel *model = gtk_tree_view_get_model(tree_view); PopplerViewer *viewer = (PopplerViewer *)data; gint page_num = 0; if (!gtk_tree_model_get_iter(model, &iter, path)) return; gtk_tree_model_get(model, &iter, INDEX_PAGE, &page_num, -1); if (page_num > 0) { gtk_spin_button_set_value(GTK_SPIN_BUTTON(viewer->cur_page), (gdouble)page_num); debug_print("Page num: %d\n", page_num); } GTK_EVENTS_FLUSH(); } /** Disable the index button if the document doesn't have an index */ static void poppler_set_index_button_sensitive(PopplerViewer *viewer) { viewer->pdf_index = poppler_index_iter_new(viewer->pdf_doc); if (viewer->pdf_index) { if(!GTK_WIDGET_IS_SENSITIVE(viewer->doc_index)) gtk_widget_set_sensitive(viewer->doc_index, TRUE); } else { gtk_widget_set_sensitive(viewer->doc_index, FALSE); } poppler_index_iter_free(viewer->pdf_index); viewer->pdf_index = NULL; } static char * poppler_get_document_format_data(GTime utime) { time_t time = (time_t) utime; struct tm t; char s[256]; const char *fmt_hack = "%c"; size_t len; if (time == 0 || !localtime_r (&time, &t)) return NULL; len = strftime (s, sizeof (s), fmt_hack, &t); if (len == 0 || s[0] == '\0') return NULL; return g_locale_to_utf8 (s, -1, NULL, NULL, NULL); } #define ADD_TO_TABLE(LABEL, VALUE) \ label = gtk_label_new(LABEL); \ gtk_misc_set_alignment(GTK_MISC(label), 1, 0.5); \ gtk_misc_set_padding(GTK_MISC(label), 4, 0); \ gtk_table_attach(viewer->table_doc_info, label, 0, 1, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); \ \ label = gtk_label_new(VALUE); \ gtk_misc_set_alignment(GTK_MISC(label), 0, 0.5); \ gtk_misc_set_padding(GTK_MISC(label), 4, 0); \ gtk_table_attach(viewer->table_doc_info, label, 1, 2, row, row+1, GTK_EXPAND | GTK_FILL, 0, 0, 0); \ row++; static GtkTable * poppler_fill_info_table(PopplerViewer *viewer) { GtkWidget *label; gchar *title, *format, *author, *subject, *keywords, *creator, *producer, *linearized, *tmp; gint row = 0; GTime creation_date, mod_date; PopplerPageLayout layout; PopplerPageMode mode; PopplerPermissions permissions; PopplerViewerPreferences view_prefs; g_object_get (viewer->pdf_doc, "title", &title, "format", &format, "author", &author, "subject", &subject, "keywords", &keywords, "creation-date", &creation_date, "permissions", &permissions, "mod-date", &mod_date, "creator", &creator, "producer", &producer, "linearized", &linearized, "page-mode", &mode, "page-layout", &layout, "viewer-preferences", &view_prefs, NULL); viewer->table_doc_info = GTK_TABLE(gtk_table_new(13, 2, FALSE)); ADD_TO_TABLE(_("Filename:"), viewer->target_filename) ADD_TO_TABLE(_("Size:"), to_human_readable(viewer->to_load->length)) ADD_TO_TABLE(NULL, NULL) ADD_TO_TABLE(_("Title:"), title) ADD_TO_TABLE(_("Subject:"), subject) ADD_TO_TABLE(_("Author:"), author) ADD_TO_TABLE(_("Keywords:"), keywords) ADD_TO_TABLE(_("Creator:"), creator) ADD_TO_TABLE(_("Producer:"), producer) tmp = poppler_get_document_format_data(creation_date); ADD_TO_TABLE(_("Created:"), tmp) g_free(tmp); tmp = poppler_get_document_format_data(mod_date); ADD_TO_TABLE(_("Modified:"), tmp) g_free(tmp); ADD_TO_TABLE(_("Format:"), format) ADD_TO_TABLE(_("Optimized:"), linearized) /* ADD_TO_TABLE(_("Page Mode:"), poppler_get_document_info_mode(mode)) */ /* ADD_TO_TABLE(_("Page Layout:"), poppler_get_document_info_layout(layout)) */ g_free(title); g_free(format); g_free(author); g_free(subject); g_free(keywords); g_free(creator); g_free(producer); g_free(linearized); return (GtkTable *) viewer->table_doc_info; } #undef ADD_TO_TABLE static FileType poppler_mimepart_get_type(MimeInfo *partinfo) { gchar *content_type = NULL; FileType type = TYPE_UNKNOWN; if ((partinfo->type == MIMETYPE_APPLICATION) && (!g_ascii_strcasecmp(partinfo->subtype, "octet-stream"))) { const gchar *filename; filename = procmime_mimeinfo_get_parameter(partinfo, "filename"); if (filename == NULL) filename = procmime_mimeinfo_get_parameter(partinfo, "name"); if (filename != NULL) content_type = procmime_get_mime_type(filename); } else { content_type = procmime_get_content_type_str(partinfo->type, partinfo->subtype); } if (content_type == NULL) type = TYPE_UNKNOWN; else if (!strcmp(content_type, "application/pdf")) type = TYPE_PDF; else if (!strcmp(content_type, "application/postscript")) type = TYPE_PS; else type = TYPE_UNKNOWN; g_free(content_type); return type; } /* Callbacks */ static void poppler_button_first_page_cb(GtkButton *button, PopplerViewer *viewer) { gtk_spin_button_spin(GTK_SPIN_BUTTON(viewer->cur_page), GTK_SPIN_HOME, 1); } static void poppler_button_prev_page_cb(GtkButton *button, PopplerViewer *viewer) { gtk_spin_button_spin(GTK_SPIN_BUTTON(viewer->cur_page), GTK_SPIN_STEP_BACKWARD, 1); } static void poppler_button_next_page_cb(GtkButton *button, PopplerViewer *viewer) { gtk_spin_button_spin(GTK_SPIN_BUTTON(viewer->cur_page), GTK_SPIN_STEP_FORWARD, 1); } static void poppler_button_last_page_cb(GtkButton *button, PopplerViewer *viewer) { gtk_spin_button_spin(GTK_SPIN_BUTTON(viewer->cur_page), GTK_SPIN_END, 1); } static void poppler_spin_change_page_cb(GtkSpinButton *button, PopplerViewer *viewer) { poppler_pdf_view_update((MimeViewer *)viewer, FALSE, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(viewer->cur_page))); } static void poppler_button_zoom_in_cb(GtkButton *button, PopplerViewer *viewer) { if (viewer->zoom < 4) { viewer->zoom += ZOOM_FACTOR; poppler_pdf_view_update((MimeViewer *)viewer, FALSE, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(viewer->cur_page))); } } static void poppler_button_zoom_out_cb(GtkButton *button, PopplerViewer *viewer) { if (viewer->zoom > 0.3) { viewer->zoom -= ZOOM_FACTOR; poppler_pdf_view_update((MimeViewer *)viewer, FALSE, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(viewer->cur_page))); } } static void poppler_button_zoom_fit_cb(GtkButton *button, PopplerViewer *viewer) { GtkAllocation *allocation; double xratio, yratio; allocation = &(viewer->scrollwin->allocation); debug_print("width: %d\n", allocation->width); debug_print("height: %d\n", allocation->height); xratio = allocation->width / viewer->width; yratio = allocation->height / viewer->height; if (xratio >= yratio) viewer->zoom = yratio; else { viewer->zoom = xratio; } poppler_pdf_view_update((MimeViewer *)viewer, FALSE, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(viewer->cur_page))); } static void poppler_button_zoom_width_cb(GtkButton *button, PopplerViewer *viewer) { GtkAllocation *allocation; double xratio; allocation = &(viewer->scrollwin->allocation); debug_print("width: %d\n", allocation->width); xratio = allocation->width / viewer->width; viewer->zoom = xratio; poppler_pdf_view_update((MimeViewer *)viewer, FALSE, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(viewer->cur_page))); } static void poppler_button_rotate_right_cb(GtkButton *button, PopplerViewer *viewer) { if (viewer->rotate == 360) viewer->rotate = 0; viewer->rotate += (gint) ROTATION; poppler_pdf_view_update((MimeViewer *)viewer, FALSE, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(viewer->cur_page))); } static void poppler_button_rotate_left_cb(GtkButton *button, PopplerViewer *viewer) { if (viewer->rotate == 0) viewer->rotate = 360; viewer->rotate = abs(viewer->rotate - (gint) ROTATION); poppler_pdf_view_update((MimeViewer *)viewer, FALSE, gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(viewer->cur_page))); } /* Show/Hide the index pane */ static void poppler_show_document_index_cb(GtkButton *button, PopplerViewer *viewer) { if(!viewer->pdf_index) viewer->pdf_index = poppler_index_iter_new(viewer->pdf_doc); gtk_tree_store_clear(GTK_TREE_STORE(viewer->index_model)); if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(viewer->doc_index))) { poppler_get_document_index(viewer, (PopplerIndexIter *) viewer->pdf_index, NULL); gtk_widget_show(GTK_WIDGET(viewer->frame_index)); } else { poppler_hide_index_pane(viewer); } } static void poppler_button_document_info_cb(GtkButton *button, PopplerViewer *viewer) { gchar *buf; buf = g_strdup_printf(_("PDF Viewer Plugin")); alertpanel_full(buf, NULL, GTK_STOCK_CLOSE, NULL, NULL, FALSE, (GtkWidget *) poppler_fill_info_table(viewer), ALERT_NOTICE, G_ALERTDEFAULT); g_free(buf); } /*static gboolean scrollwin_key_up_cb(GtkWidget *widg, GdkEventKey *event, PopplerViewer *viewer) { if(event != NULL && event->keyval == GDK_Up) return FALSE; } static gboolean scrollwin_key_down_cb(GtkWidget *widg, GdkEventKey *event, PopplerViewer *viewer) { if(event != NULL && event->keyval == GDK_Down) return FALSE; } static gboolean scrollwin_page_up_cb(GtkWidget *widg, GdkEventKey *event, PopplerViewer *viewer) { debug_print("key_event_press %s", event->string); if(event != NULL && event->keyval == GDK_Page_Up) { if (viewer->cur_page_int > 1) poppler_pdf_view_update((MimeViewer *)viewer, FALSE, viewer->cur_page_int - 1); } return FALSE; } static gboolean scrollwin_page_down_cb(GtkWidget *widg, GdkEventKey *event, PopplerViewer *viewer) { if(event != NULL && event->keyval == GDK_Page_Down) if (viewer->cur_page_int < viewer->num_pages_int) poppler_pdf_view_update((MimeViewer *)viewer, FALSE, viewer->cur_page_int + 1); return FALSE; } end callbacks *** static const char * poppler_get_document_info_mode(PopplerPageMode mode) { GEnumValue *enum_value; enum_value = g_enum_get_value((GEnumClass *) g_type_class_peek (POPPLER_TYPE_PAGE_MODE), mode); return (gchar *) enum_value->value_name; } static const char * poppler_get_document_info_layout(PopplerPageLayout layout) { GEnumValue *enum_value; enum_value = g_enum_get_value((GEnumClass *) g_type_class_peek (POPPLER_TYPE_PAGE_LAYOUT), layout); return (gchar *) enum_value->value_name; } */ static void poppler_show_controls(PopplerViewer *viewer, gboolean show) { if (show) { gtk_widget_show(viewer->first_page); gtk_widget_show(viewer->cur_page); gtk_widget_show(viewer->prev_page); gtk_widget_show(viewer->next_page); gtk_widget_show(viewer->last_page); gtk_widget_show(viewer->zoom_in); gtk_widget_show(viewer->zoom_out); gtk_widget_show(viewer->zoom_fit); gtk_widget_show(viewer->zoom_width); gtk_widget_show(viewer->buttons_table); gtk_widget_show(viewer->rotate_right); gtk_widget_show(viewer->rotate_left); gtk_widget_show(viewer->doc_info); gtk_widget_show(viewer->doc_index); } else { gtk_widget_hide(viewer->first_page); gtk_widget_hide(viewer->cur_page); gtk_widget_hide(viewer->prev_page); gtk_widget_hide(viewer->next_page); gtk_widget_hide(viewer->last_page); gtk_widget_hide(viewer->zoom_in); gtk_widget_hide(viewer->zoom_out); gtk_widget_hide(viewer->zoom_fit); gtk_widget_hide(viewer->zoom_width); gtk_widget_hide(viewer->buttons_table); gtk_widget_hide(viewer->rotate_right); gtk_widget_hide(viewer->rotate_left); gtk_widget_hide(viewer->doc_info); gtk_widget_hide(viewer->doc_index); } } static void poppler_pdf_view_update(MimeViewer *_viewer, gboolean reload_file, int page_num) { PopplerViewer *viewer = (PopplerViewer *) _viewer; GError *error; GdkPixbuf *pb; gchar *tmpfile = NULL; error = NULL; if (reload_file) { pb = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1); gdk_pixbuf_fill (pb, 0x00000000); gtk_image_set_from_pixbuf(GTK_IMAGE(viewer->pdf_view), pb); g_object_unref(G_OBJECT(pb)); pb = NULL; if (viewer->pdf_doc) { debug_print("viewer->pdf_doc"); g_object_unref(G_OBJECT(viewer->pdf_doc)); viewer->pdf_doc = NULL; } if (poppler_mimepart_get_type(viewer->to_load) == TYPE_PS) { stock_pixmap_gdk(viewer->hbox, STOCK_PIXMAP_MIME_PS, &viewer->icon_pixmap, &viewer->icon_bitmap); gtk_image_set_from_pixmap(GTK_IMAGE(viewer->icon_type), viewer->icon_pixmap, viewer->icon_bitmap); } else if (poppler_mimepart_get_type(viewer->to_load) == TYPE_PDF) { stock_pixmap_gdk(viewer->hbox, STOCK_PIXMAP_MIME_PDF, &viewer->icon_pixmap, &viewer->icon_bitmap); gtk_image_set_from_pixmap(GTK_IMAGE(viewer->icon_type), viewer->icon_pixmap, viewer->icon_bitmap); } else { stock_pixmap_gdk(viewer->hbox, STOCK_PIXMAP_MIME_APPLICATION, &viewer->icon_pixmap, &viewer->icon_bitmap); gtk_image_set_from_pixmap(GTK_IMAGE(viewer->icon_type), viewer->icon_pixmap, viewer->icon_bitmap); } gtk_label_set_text(GTK_LABEL(viewer->doc_label), _("Loading...")); poppler_show_controls(viewer, FALSE); main_window_cursor_wait(mainwindow_get_mainwindow()); GTK_EVENTS_FLUSH(); if (poppler_mimepart_get_type(viewer->to_load) == TYPE_PS) { gchar *cmdline = NULL, *tmp = NULL; gint result = 0; /* convert postscript to pdf */ tmpfile = get_tmp_file(); cmdline = g_strdup_printf( "gs -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=%s -c .setpdfwrite -f \"%s\"", tmpfile, viewer->filename); result = execute_command_line(cmdline, FALSE); if (result == 0) { tmp = g_strdup_printf("file://%s", tmpfile); viewer->pdf_doc = poppler_document_new_from_file( tmp, NULL, &error); g_free(tmp); } else { g_warning("gs conversion failed: %s returned %d\n", cmdline, result); tmp = g_strdup_printf("gs: err %d", result); gtk_label_set_text(GTK_LABEL(viewer->doc_label), tmp); g_free(tmp); } g_free(cmdline); g_unlink(tmpfile); g_free(tmpfile); if (result != 0) { main_window_cursor_normal(mainwindow_get_mainwindow()); return; } } else { viewer->pdf_doc = poppler_document_new_from_file( viewer->fsname, NULL, &error); } debug_print("update\n"); viewer->num_pages = poppler_document_get_n_pages(viewer->pdf_doc); gtk_spin_button_set_range(GTK_SPIN_BUTTON(viewer->cur_page), 1, (gdouble)viewer->num_pages ); gtk_label_set_text(GTK_LABEL(viewer->doc_label), (g_strdup_printf(_("%s document (%d page%s)"), poppler_mimepart_get_type(viewer->to_load) == TYPE_PDF ? "PDF":"Postscript", viewer->num_pages, viewer->num_pages > 1 ? "s":"") )); poppler_show_controls(viewer, TRUE); main_window_cursor_normal(mainwindow_get_mainwindow()); } if (viewer->pdf_doc == NULL) { strretchomp(error->message); stock_pixmap_gdk(viewer->hbox, STOCK_PIXMAP_MIME_APPLICATION, &viewer->icon_pixmap, &viewer->icon_bitmap); gtk_image_set_from_pixmap(GTK_IMAGE(viewer->icon_type), viewer->icon_pixmap, viewer->icon_bitmap); gtk_label_set_text(GTK_LABEL(viewer->doc_label), error->message); poppler_show_controls(viewer, FALSE); g_error_free(error); return; } /* check for the index if exists */ poppler_set_index_button_sensitive((PopplerViewer *) viewer); if(page_num > 0 && page_num <= viewer->num_pages) { gchar *page_str = g_strdup_printf("%d", page_num); GTK_EVENTS_FLUSH(); viewer->pdf_page = poppler_document_get_page_by_label (viewer->pdf_doc, page_str); g_free(page_str); if (viewer->pdf_page == NULL) { g_warning ("Page not found\n"); return; } if(viewer->rotate == 90 || viewer->rotate == 270) { poppler_page_get_size(viewer->pdf_page, &viewer->height, &viewer->width); } else { poppler_page_get_size(viewer->pdf_page, &viewer->width, &viewer->height); } pb = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE, 8, (int)(viewer->width * viewer->zoom), (int)(viewer->height * viewer->zoom)); poppler_page_render_to_pixbuf (viewer->pdf_page, 0, 0, (int)(viewer->width * viewer->zoom), (int)(viewer->height * viewer->zoom), viewer->zoom, viewer->rotate, pb); gtk_image_set_from_pixbuf(GTK_IMAGE(viewer->pdf_view), pb); g_object_unref(G_OBJECT(pb)); g_object_unref(G_OBJECT(viewer->pdf_page)); } } 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 (partinfo) { viewer->target_filename = procmime_get_part_file_name(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; } poppler_pdf_view_update((MimeViewer *)viewer, TRUE, 1); messageview->updating = FALSE; return FALSE; } static void poppler_show_mimepart(MimeViewer *_viewer, const gchar *infile, MimeInfo *partinfo) { PopplerViewer *viewer = (PopplerViewer *) _viewer; viewer->zoom = 1.0; viewer->rotate = 0; 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; GdkPixbuf *pb; gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(viewer->doc_index), FALSE); gtk_widget_hide(viewer->frame_index); debug_print("poppler_clear_viewer\n"); viewer->to_load = NULL; poppler_text_search_destroy(viewer->text_found, viewer->search_first); if (viewer->pdf_doc) { g_object_unref(G_OBJECT(viewer->pdf_doc)); viewer->pdf_doc = NULL; } pb = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1); gdk_pixbuf_fill (pb, 0x00000000); gtk_image_set_from_pixbuf(GTK_IMAGE(viewer->pdf_view), pb); g_object_unref(G_OBJECT(pb)); 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); vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(viewer->scrollwin_index)); vadj->value = 0.0; g_signal_emit_by_name(G_OBJECT(vadj), "value-changed", 0); gtk_tree_store_clear(GTK_TREE_STORE(viewer->index_model)); } static void poppler_destroy_viewer(MimeViewer *_viewer) { PopplerViewer *viewer = (PopplerViewer *) _viewer; debug_print("poppler_destroy_viewer\n"); if(viewer->pdf_index) poppler_index_iter_free(viewer->pdf_index); gtk_widget_unref(GTK_WIDGET(viewer->vbox)); gtk_widget_unref(GTK_WIDGET(viewer->pdf_view)); gtk_widget_unref(GTK_WIDGET(viewer->doc_index_pane)); gtk_widget_unref(GTK_WIDGET(viewer->scrollwin)); gtk_widget_unref(GTK_WIDGET(viewer->scrollwin_index)); g_unlink(viewer->filename); g_free(viewer->filename); g_free(viewer); } static gboolean poppler_scroll_page(MimeViewer *_viewer, gboolean up) { PopplerViewer *viewer = (PopplerViewer *)_viewer; GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(viewer->scrollwin)); if (viewer->pdf_view == NULL) return FALSE; if (!gtkutils_scroll_page(viewer->pdf_view, vadj, up)) { if (!up) { gtk_spin_button_spin(GTK_SPIN_BUTTON(viewer->cur_page), GTK_SPIN_STEP_FORWARD, 1); 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); return TRUE; } else if (up) { gtk_spin_button_spin(GTK_SPIN_BUTTON(viewer->cur_page), GTK_SPIN_STEP_BACKWARD, 1); vadj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(viewer->scrollwin)); vadj->value = vadj->upper - vadj->page_size; g_signal_emit_by_name(G_OBJECT(vadj), "value-changed", 0); return TRUE; } return FALSE; } else return TRUE; } static void poppler_scroll_one_line(MimeViewer *_viewer, gboolean up) { PopplerViewer *viewer = (PopplerViewer *)_viewer; GtkAdjustment *vadj = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW(viewer->scrollwin)); if (viewer->pdf_view == NULL) return; gtkutils_scroll_one_line(viewer->pdf_view, vadj, up); } static void button_set_pixmap(GtkWidget *widg, char **button_image) { GdkPixmap *pixmap; GdkBitmap *mask; pixmap = mask = NULL; PIXMAP_CREATE(mainwindow_get_mainwindow()->window, pixmap, mask, button_image); gtk_button_set_image(GTK_BUTTON(widg), gtk_image_new_from_pixmap(pixmap, mask)); } #define BUTTON_H_PADDING 3 #define ADD_BUTTON_TO_TABLE(widget, xpm) \ widget = gtk_button_new(); \ button_set_pixmap(widget, xpm); \ gtk_widget_set_size_request(GTK_WIDGET(widget), 26, 26); \ gtk_table_attach(GTK_TABLE(viewer->buttons_table), GTK_WIDGET(widget), \ col, col+1, 0, 1, 0, 0, BUTTON_H_PADDING, 0); \ col++; #define ADD_SEP_TO_TABLE \ sep = gtk_label_new(""); \ gtk_table_attach(GTK_TABLE(viewer->buttons_table), GTK_WIDGET(sep), \ col, col+1, 0, 1, 0, 0, 0, 0); \ gtk_table_set_col_spacing(GTK_TABLE(viewer->buttons_table), col, 3*BUTTON_H_PADDING); \ col++; static MimeViewer *poppler_viewer_create(void) { PopplerViewer *viewer; GtkTreeViewColumn *column; GtkCellRenderer *renderer; GtkTreeStore *tree_store; GtkWidget *sep; gint col = 0; viewer = g_new0(PopplerViewer, 1); debug_print("poppler_viewer_create\n"); 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->mimeviewer.text_search = poppler_text_search; viewer->mimeviewer.scroll_page = poppler_scroll_page; viewer->mimeviewer.scroll_one_line = poppler_scroll_one_line; viewer->scrollwin = gtk_scrolled_window_new(NULL, NULL); viewer->scrollwin_index = gtk_scrolled_window_new(NULL, NULL); viewer->mimeinfo = NULL; viewer->pdf_view = gtk_image_new(); viewer->icon_type = gtk_image_new(); viewer->doc_label = gtk_label_new(""); viewer->buttons_table = gtk_table_new(1, 1, FALSE); viewer->doc_index_pane = gtk_hpaned_new(); viewer->frame_index = gtk_frame_new(NULL); gtk_frame_set_shadow_type (GTK_FRAME (viewer->frame_index), GTK_SHADOW_IN); gtk_widget_set_size_request (viewer->frame_index, 18, -1); gtk_frame_set_label(GTK_FRAME(viewer->frame_index), _("Document Index")); viewer->button_bar_tips = gtk_tooltips_new(); ADD_SEP_TO_TABLE ADD_BUTTON_TO_TABLE(viewer->first_page, first_arrow_xpm) ADD_BUTTON_TO_TABLE(viewer->prev_page, left_arrow_xpm) viewer->cur_page = gtk_spin_button_new_with_range(0.0, 0.0, 1.0); gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(viewer->cur_page), TRUE); gtk_table_attach(GTK_TABLE(viewer->buttons_table), GTK_WIDGET(viewer->cur_page), col, col+1, 0, 1, 0, 0, BUTTON_H_PADDING, 0); col++; ADD_BUTTON_TO_TABLE(viewer->next_page, right_arrow_xpm) ADD_BUTTON_TO_TABLE(viewer->last_page, last_arrow_xpm) ADD_SEP_TO_TABLE ADD_BUTTON_TO_TABLE(viewer->zoom_in, zoom_in_xpm) ADD_BUTTON_TO_TABLE(viewer->zoom_out, zoom_out_xpm) ADD_BUTTON_TO_TABLE(viewer->zoom_fit, zoom_fit_xpm) ADD_BUTTON_TO_TABLE(viewer->zoom_width, zoom_width_xpm) ADD_SEP_TO_TABLE ADD_BUTTON_TO_TABLE(viewer->rotate_left, rotate_left_xpm) ADD_BUTTON_TO_TABLE(viewer->rotate_right, rotate_right_xpm) ADD_SEP_TO_TABLE ADD_BUTTON_TO_TABLE(viewer->doc_info, doc_info_xpm) viewer->doc_index = gtk_toggle_button_new(); button_set_pixmap(viewer->doc_index, doc_index_xpm); gtk_widget_set_size_request(GTK_WIDGET(viewer->doc_index), 26, 26); gtk_table_attach(GTK_TABLE(viewer->buttons_table), GTK_WIDGET(viewer->doc_index), col, col+1, 0, 1, 0, 0, BUTTON_H_PADDING, 0); col++; 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_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(viewer->scrollwin), viewer->pdf_view); viewer->vbox = gtk_vbox_new(FALSE, 4); viewer->hbox = gtk_hbox_new(FALSE, 4); /* treeview */ tree_store = gtk_tree_store_new(N_INDEX_COLUMNS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_DOUBLE); viewer->index_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tree_store)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes (_("Name"), renderer, "text", 0, NULL); gtk_tree_view_append_column(GTK_TREE_VIEW(viewer->index_list), column); gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(viewer->index_list), FALSE); viewer->index_model = GTK_TREE_MODEL(tree_store); gtk_tree_selection_set_mode(gtk_tree_view_get_selection(GTK_TREE_VIEW(viewer->index_list)), GTK_SELECTION_SINGLE); g_signal_connect(G_OBJECT(viewer->index_list), "row_activated", G_CALLBACK(poppler_index_row_activated), viewer); gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(viewer->scrollwin_index), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_scrolled_window_set_shadow_type( GTK_SCROLLED_WINDOW(viewer->scrollwin_index), GTK_SHADOW_IN); gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(viewer->scrollwin_index), viewer->index_list); /* end treeview */ stock_pixmap_gdk(viewer->hbox, STOCK_PIXMAP_MIME_TEXT_PLAIN, &viewer->icon_pixmap, &viewer->icon_bitmap); gtk_image_set_from_pixmap(GTK_IMAGE(viewer->icon_type), viewer->icon_pixmap, viewer->icon_bitmap); /* pack widgets*/ gtk_box_pack_start(GTK_BOX(viewer->hbox), viewer->icon_type, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(viewer->hbox), viewer->doc_label, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(viewer->hbox), viewer->buttons_table, FALSE, FALSE, 0); gtk_container_add(GTK_CONTAINER(viewer->frame_index), viewer->scrollwin_index); gtk_paned_pack1(GTK_PANED(viewer->doc_index_pane), viewer->frame_index, FALSE, FALSE); gtk_paned_pack2(GTK_PANED(viewer->doc_index_pane), viewer->scrollwin, FALSE, FALSE); gtk_box_pack_start(GTK_BOX(viewer->vbox), viewer->hbox, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(viewer->vbox), viewer->doc_index_pane, TRUE, TRUE, 0); /* show widgets */ gtk_widget_show(GTK_WIDGET(viewer->doc_index_pane)); gtk_widget_ref(GTK_WIDGET(viewer->doc_index_pane)); gtk_widget_show(GTK_WIDGET(viewer->scrollwin)); gtk_widget_ref(GTK_WIDGET(viewer->scrollwin)); gtk_widget_show(GTK_WIDGET(viewer->scrollwin_index)); gtk_widget_ref(GTK_WIDGET(viewer->scrollwin_index)); gtk_widget_show(GTK_WIDGET(viewer->hbox)); gtk_widget_ref(GTK_WIDGET(viewer->hbox)); gtk_widget_show(GTK_WIDGET(viewer->vbox)); gtk_widget_ref(GTK_WIDGET(viewer->vbox)); gtk_widget_show(GTK_WIDGET(viewer->buttons_table)); gtk_widget_ref(GTK_WIDGET(viewer->buttons_table)); gtk_widget_show(GTK_WIDGET(viewer->cur_page)); gtk_widget_ref(GTK_WIDGET(viewer->cur_page)); gtk_widget_show(GTK_WIDGET(viewer->first_page)); gtk_widget_ref(GTK_WIDGET(viewer->first_page)); gtk_widget_show(GTK_WIDGET(viewer->last_page)); gtk_widget_ref(GTK_WIDGET(viewer->last_page)); gtk_widget_show(GTK_WIDGET(viewer->prev_page)); gtk_widget_ref(GTK_WIDGET(viewer->prev_page)); gtk_widget_show(GTK_WIDGET(viewer->next_page)); gtk_widget_ref(GTK_WIDGET(viewer->next_page)); gtk_widget_show(GTK_WIDGET(viewer->zoom_in)); gtk_widget_ref(GTK_WIDGET(viewer->zoom_in)); gtk_widget_show(GTK_WIDGET(viewer->zoom_out)); gtk_widget_ref(GTK_WIDGET(viewer->zoom_out)); gtk_widget_show(GTK_WIDGET(viewer->zoom_fit)); gtk_widget_ref(GTK_WIDGET(viewer->zoom_fit)); gtk_widget_show(GTK_WIDGET(viewer->zoom_width)); gtk_widget_ref(GTK_WIDGET(viewer->zoom_width)); gtk_widget_show(GTK_WIDGET(viewer->rotate_right)); gtk_widget_ref(GTK_WIDGET(viewer->rotate_right)); gtk_widget_show(GTK_WIDGET(viewer->rotate_left)); gtk_widget_ref(GTK_WIDGET(viewer->rotate_left)); gtk_widget_show(GTK_WIDGET(viewer->doc_info)); gtk_widget_ref(GTK_WIDGET(viewer->doc_info)); gtk_widget_show(GTK_WIDGET(viewer->doc_index)); gtk_widget_ref(GTK_WIDGET(viewer->doc_index)); gtk_widget_show(GTK_WIDGET(viewer->doc_label)); gtk_widget_ref(GTK_WIDGET(viewer->doc_label)); gtk_widget_show(GTK_WIDGET(viewer->icon_type)); gtk_widget_ref(GTK_WIDGET(viewer->icon_type)); gtk_widget_show(GTK_WIDGET(viewer->pdf_view)); gtk_widget_ref(GTK_WIDGET(viewer->pdf_view)); gtk_widget_show(GTK_WIDGET(viewer->index_list)); gtk_widget_ref(GTK_WIDGET(viewer->index_list)); /* Set Tooltips*/ gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->first_page, _("First Page"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->prev_page, _("Previous Page"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->next_page, _("Next Page"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->last_page, _("Last Page"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->zoom_in, _("Zoom In"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->zoom_out, _("Zoom Out"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->zoom_fit, _("Fit Page"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->zoom_width, _("Fit Page Width"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->rotate_left, _("Rotate Left"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->rotate_right, _("Rotate Right"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->doc_info, _("Document Info"), NULL); gtk_tooltips_set_tip (GTK_TOOLTIPS (viewer->button_bar_tips), viewer->doc_index, _("Document Index"), NULL); /* Connect Signals */ g_signal_connect (G_OBJECT(viewer->cur_page), "value-changed", G_CALLBACK(poppler_spin_change_page_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->first_page), "clicked", G_CALLBACK(poppler_button_first_page_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->prev_page), "clicked", G_CALLBACK(poppler_button_prev_page_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->next_page), "clicked", G_CALLBACK(poppler_button_next_page_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->last_page), "clicked", G_CALLBACK(poppler_button_last_page_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->zoom_in), "clicked", G_CALLBACK(poppler_button_zoom_in_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->zoom_out), "clicked", G_CALLBACK(poppler_button_zoom_out_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->zoom_fit), "clicked", G_CALLBACK(poppler_button_zoom_fit_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->zoom_width), "clicked", G_CALLBACK(poppler_button_zoom_width_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->rotate_right), "clicked", G_CALLBACK(poppler_button_rotate_right_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->rotate_left), "clicked", G_CALLBACK(poppler_button_rotate_left_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->doc_info), "clicked", G_CALLBACK(poppler_button_document_info_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->doc_index), "clicked", G_CALLBACK(poppler_show_document_index_cb), (gpointer) viewer); /* g_signal_connect (G_OBJECT(viewer->scrollwin), "key_press_event", G_CALLBACK(scrollwin_key_down_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->scrollwin), "key_press_event", G_CALLBACK(scrollwin_key_up_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->scrollwin), "key_press_event", G_CALLBACK(scrollwin_page_down_cb), (gpointer) viewer); g_signal_connect (G_OBJECT(viewer->pdf_view), "key_press_event", G_CALLBACK(scrollwin_page_up_cb), (gpointer) viewer); */ viewer->target_filename = NULL; viewer->filename = NULL; viewer->fsname = NULL; return (MimeViewer *) viewer; } #undef ADD_BUTTON_TO_TABLE #undef ADD_SEP_TO_TABLE #undef BUTTON_H_PADDING #undef SEP_H_PADDING static gchar *content_types[] = {"application/pdf", "application/postscript", NULL}; static MimeViewerFactory poppler_viewer_factory = { content_types, 0, poppler_viewer_create, }; gint plugin_init(gchar **error) { msg = g_strdup_printf(_("This plugin enables the viewing of PDF and PostScript " "attachments using the Poppler %s Lib.\n\n" "PDF Viewer is Copyright (C) 2007\n" "by Salvatore De Paolis " ),poppler_get_version()); bindtextdomain(TEXTDOMAIN, LOCALEDIR); bind_textdomain_codeset(TEXTDOMAIN, "UTF-8"); if (!check_plugin_version(MAKE_NUMERIC_VERSION(2, 7, 2, 57), VERSION_NUMERIC, _("PDF Viewer"), error)) return -1; mimeview_register_viewer_factory(&poppler_viewer_factory); return 0; } void plugin_done(void) { g_free(msg); mimeview_unregister_viewer_factory(&poppler_viewer_factory); } const gchar *plugin_name(void) { return _("PDF Viewer"); } const gchar *plugin_desc(void) { return msg; } 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_MIMEVIEWER, "application/postscript"}, {PLUGIN_NOTHING, NULL} }; return features; }