diff --git a/src/gtk-tpdfv.c b/src/gtk-tpdfv.c
index 771dff99871ebd2f2490207790760175caa684e9..e17a4eb22073f252910f0ee96afe48e2b941b9fa 100644 (file)
--- a/src/gtk-tpdfv.c
+++ b/src/gtk-tpdfv.c
#include <stdlib.h>
#include <string.h>
+#include <sys/stat.h>
+
#define TPDFV_MIN(a, b) ((a) <= (b) ? (a) : (b))
#define TPDFV_MAX(a, b) ((a) >= (b) ? (a) : (b))
} tpdfv_zoommode_t;
typedef struct {
- char *filename;
+ gchar *filename;
+
+ time_t mtime;
PopplerDocument *doc;
PopplerPage *current_page;
* Private helper functions.
*/
-static gboolean
-tpdfv_init(gtk_tpdfv_t *pdf, const char *filename)
+static void
+tpdfv_open(gtk_tpdfv_t *pdf)
{
GError *err = NULL;
- if (strstr(filename, "://"))
- pdf->filename = strdup(filename);
- else {
- size_t len = strlen("file://") + strlen(filename);
- pdf->filename = (char *)malloc(len + 1);
- if (pdf->filename) {
- *pdf->filename = '\0';
- strncat(pdf->filename, "file://", len);
- strncat(pdf->filename, filename, len - strlen("file://"));
- }
- }
+ struct stat statbuf;
- /* XXX: error reporting mechanism */
+ if ((! pdf) || (! pdf->filename))
+ return;
- if (! pdf->filename) {
+ memset(&statbuf, 0, sizeof(statbuf));
+ if (stat(pdf->filename + strlen("file://"), &statbuf) != 0) {
char errbuf[1024];
strerror_r(errno, errbuf, sizeof(errbuf));
- fprintf(stderr, "Failed to allocate string: %s.\n", errbuf);
- return FALSE;
+ fprintf(stderr, "Failed to access PDF: %s.\n", errbuf);
+ return;
}
+ pdf->mtime = statbuf.st_mtime;
+
pdf->doc = poppler_document_new_from_file(pdf->filename,
/* password = */ NULL, &err);
if (! pdf->doc) {
fprintf(stderr, "Failed to open PDF: %s.\n", err->message);
+ return;
+ }
+
+ pdf->total_pages = poppler_document_get_n_pages(pdf->doc);
+ if (pdf->current_page_no >= pdf->total_pages)
+ pdf->current_page_no = pdf->total_pages - 1;
+} /* tpdfv_open */
+
+static void
+tpdfv_close(gtk_tpdfv_t *pdf)
+{
+ if (! pdf)
+ return;
+
+ g_object_unref(pdf->doc);
+ pdf->doc = NULL;
+ pdf->current_page = NULL;
+} /* tpdfv_close */
+
+static gboolean
+tpdfv_init(gtk_tpdfv_t *pdf, const char *filename)
+{
+ GError *err = NULL;
+
+ char *scheme;
+
+ if ((! pdf) || (! filename))
+ return FALSE;
+
+ scheme = g_uri_parse_scheme(filename);
+ if (scheme)
+ filename += strlen(scheme);
+
+ if (g_path_is_absolute(filename)) {
+ pdf->filename = g_filename_to_uri(filename,
+ /* hostname = */ NULL, &err);
+ }
+ else {
+ gchar *tmp = g_build_filename(g_get_current_dir(), filename, NULL);
+ pdf->filename = g_filename_to_uri(tmp, /* hostname = */ NULL, &err);
+ g_free(tmp);
+ }
+
+ /* XXX: error reporting mechanism */
+
+ if (! pdf->filename) {
+ if (err)
+ fprintf(stderr, "Failed to allocate string: %s.\n", err->message);
return FALSE;
}
+ pdf->doc = NULL;
+ tpdfv_open(pdf);
+
pdf->current_page_no = 0;
pdf->current_page = poppler_document_get_page(pdf->doc,
pdf->current_page_no);
return FALSE;
}
- pdf->total_pages = poppler_document_get_n_pages(pdf->doc);
-
pdf->zoom_mode = TPDFV_ZOOM_CUSTOM;
pdf->zoom_factor = 1.0;
pdf->delta_x = pdf->delta_y = 0.0;
if (! pdf)
return;
- g_object_unref(pdf->doc);
- pdf->doc = NULL;
+ tpdfv_close(pdf);
pdf->current_page = NULL;
- free(pdf->filename);
+ g_free(pdf->filename);
pdf->filename = NULL;
return;
} /* tpdfv_clean */
pdf = GTK_TPDFV_GET_PRIVATE(widget);
- if (poppler_page_get_index(pdf->current_page)
- != pdf->current_page_no) {
+ if ((! pdf->current_page) || (poppler_page_get_index(pdf->current_page)
+ != pdf->current_page_no)) {
pdf->current_page = poppler_document_get_page(pdf->doc,
pdf->current_page_no);
gtk_tpdfv_t *pdf;
cairo_t *cr;
+ struct stat statbuf;
+
gdouble width, height;
gdouble page_width = 0.0;
if (! pdf)
return FALSE;
+ memset(&statbuf, 0, sizeof(statbuf));
+ if (stat(pdf->filename + strlen("file://"), &statbuf)) {
+ char errbuf[1024];
+ strerror_r(errno, errbuf, sizeof(errbuf));
+ fprintf(stderr, "Failed to access PDF: %s.\n", errbuf);
+ return FALSE;
+ }
+
+ if (statbuf.st_mtime > pdf->mtime)
+ gtk_tpdfv_reload(tpdfv);
+
cr = gdk_cairo_create(tpdfv->window);
cairo_rectangle(cr, event->area.x, event->area.y,
event->area.width, event->area.height);
cairo_translate(cr, x + pdf->delta_x, y + pdf->delta_y);
+ /* draw empty white page */
+ cairo_save(cr);
+
+ cairo_set_source_rgba(cr, 1.0, 1.0, 1.0, 1.0);
+ cairo_rectangle(cr, 0.0, 0.0, page_width, page_height);
+ cairo_fill(cr);
+
+ cairo_restore(cr);
+
poppler_page_render(pdf->current_page, cr);
cairo_destroy(cr);
return GTK_WIDGET(tpdfv);
} /* gtk_tpdfv_new */
+void
+gtk_tpdfv_reload(GtkWidget *widget)
+{
+ gtk_tpdfv_t *pdf;
+
+ pdf = GTK_TPDFV_GET_PRIVATE(widget);
+ tpdfv_close(pdf);
+ tpdfv_open(pdf);
+ do_redraw(widget);
+} /* gtk_tpdfv_reload */
+
+int
+gtk_tpdfv_get_n_pages(GtkWidget *widget)
+{
+ gtk_tpdfv_t *pdf;
+
+ if (! widget)
+ return -1;
+
+ pdf = GTK_TPDFV_GET_PRIVATE(widget);
+ return pdf->total_pages;
+} /* gtk_tpdfv_get_n_pages */
+
+int
+gtk_tpdfv_get_current_page(GtkWidget *widget)
+{
+ gtk_tpdfv_t *pdf;
+
+ if (! widget)
+ return -1;
+
+ pdf = GTK_TPDFV_GET_PRIVATE(widget);
+ return pdf->current_page_no;
+} /* gtk_tpdfv_get_current_page */
+
void
gtk_tpdfv_page_up(GtkWidget *widget)
{
do_redraw(widget);
} /* gtk_tpdfv_last_page */
+void
+gtk_tpdfv_goto_page(GtkWidget *widget, int page)
+{
+ gtk_tpdfv_t *pdf;
+
+ pdf = GTK_TPDFV_GET_PRIVATE(widget);
+
+ if ((page < 0) || (page >= pdf->total_pages))
+ return;
+
+ pdf->current_page_no = page;
+ do_redraw(widget);
+} /* gtk_tpdfv_goto_page */
+
void
gtk_tpdfv_zoom_in(GtkWidget *widget)
{