2009-08-11 23:18:50 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
2009-08-13 22:55:36 +02:00
|
|
|
#include <unistd.h>
|
2009-08-11 23:18:50 +02:00
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
#include <poppler/glib/poppler.h>
|
|
|
|
#include <cairo.h>
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
#include <gtk/gtk.h>
|
|
|
|
#include <gdk/gdkkeysyms.h>
|
|
|
|
|
|
|
|
/* macros */
|
|
|
|
#define LENGTH(x) sizeof(x)/sizeof((x)[0])
|
|
|
|
|
|
|
|
/* enums */
|
2009-08-12 21:45:49 +02:00
|
|
|
enum { UP, DOWN, LEFT, RIGHT, ZOOM_IN, ZOOM_OUT, ZOOM_ORIGINAL,
|
2009-08-29 16:07:58 +02:00
|
|
|
NEXT, PREVIOUS, HIDE, ERROR, WARNING, DEFAULT, TOP, BOTTOM,
|
|
|
|
ADJUST_BESTFIT, ADJUST_WIDTH, FORWARD, BACKWARD };
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
GtkWindow *window;
|
|
|
|
GtkBox *box;
|
|
|
|
GtkScrolledWindow *view;
|
2009-08-12 21:45:49 +02:00
|
|
|
GtkWidget *drawing_area;
|
2009-08-13 22:55:36 +02:00
|
|
|
GtkBox *notification;
|
2009-08-11 23:18:50 +02:00
|
|
|
GtkEntry *inputbar;
|
2009-09-19 15:53:35 +02:00
|
|
|
GList *history;
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
GdkColor default_fg;
|
|
|
|
GdkColor default_bg;
|
|
|
|
GdkColor inputbar_fg;
|
|
|
|
GdkColor inputbar_bg;
|
2009-08-13 22:55:36 +02:00
|
|
|
GdkColor notification_fg;
|
|
|
|
GdkColor notification_bg;
|
|
|
|
GdkColor notification_wn_fg;
|
|
|
|
GdkColor notification_wn_bg;
|
|
|
|
GdkColor notification_er_fg;
|
|
|
|
GdkColor notification_er_bg;
|
2009-08-11 23:18:50 +02:00
|
|
|
GdkColor completion_fg;
|
|
|
|
GdkColor completion_bg;
|
|
|
|
GdkColor completion_hl_fg;
|
|
|
|
GdkColor completion_hl_bg;
|
2009-08-15 12:35:07 +02:00
|
|
|
GdkColor search_highlight;
|
2009-08-11 23:18:50 +02:00
|
|
|
PangoFontDescription *font;
|
|
|
|
} Settings;
|
2009-08-12 21:45:49 +02:00
|
|
|
|
|
|
|
struct
|
|
|
|
{
|
|
|
|
PopplerDocument *document;
|
|
|
|
PopplerPage *page;
|
2009-08-13 22:55:36 +02:00
|
|
|
char *file;
|
|
|
|
cairo_surface_t *surface;
|
2009-08-12 21:45:49 +02:00
|
|
|
int page_number;
|
2009-08-13 22:55:36 +02:00
|
|
|
int number_of_pages;
|
2009-08-12 21:45:49 +02:00
|
|
|
double scale;
|
|
|
|
int rotate;
|
|
|
|
} PDF;
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
} Zathura;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int n;
|
|
|
|
void *data;
|
|
|
|
} Argument;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int mask;
|
|
|
|
int key;
|
|
|
|
void (*function)(Argument*);
|
|
|
|
Argument argument;
|
|
|
|
} Shortcut;
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
char *command;
|
|
|
|
void (*function)(int, char**);
|
|
|
|
} Command;
|
|
|
|
|
|
|
|
/* function declarations */
|
|
|
|
void init();
|
2009-09-19 15:53:35 +02:00
|
|
|
void history(int);
|
2009-08-11 23:18:50 +02:00
|
|
|
void update_title();
|
2009-08-13 22:55:36 +02:00
|
|
|
void update_status();
|
2009-08-12 21:45:49 +02:00
|
|
|
void set_page(int);
|
|
|
|
void draw();
|
2009-08-15 12:35:07 +02:00
|
|
|
void highlight_result(PopplerRectangle*);
|
|
|
|
void open_link(char*);
|
2009-08-29 16:07:58 +02:00
|
|
|
void save_images(int, char*);
|
|
|
|
void save_attachments(char*);
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
gboolean complete(Argument*);
|
2009-08-13 22:55:36 +02:00
|
|
|
gboolean delete_widget(gpointer);
|
2009-08-15 12:35:07 +02:00
|
|
|
|
|
|
|
GtkWidget* notify(int, char*);
|
|
|
|
GtkWidget* update_notification(GtkWidget*, int, char*);
|
2009-08-11 23:18:50 +02:00
|
|
|
|
2009-08-29 16:07:58 +02:00
|
|
|
PopplerRectangle* recalcRectangle(PopplerRectangle*);
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
/* shortcut declarations */
|
|
|
|
void sc_focus_inputbar(Argument*);
|
2009-08-12 21:45:49 +02:00
|
|
|
void sc_scroll(Argument*);
|
|
|
|
void sc_navigate(Argument*);
|
|
|
|
void sc_zoom(Argument*);
|
|
|
|
void sc_adjust_window(Argument*);
|
|
|
|
void sc_rotate(Argument*);
|
2009-08-13 22:55:36 +02:00
|
|
|
void sc_search(Argument*);
|
2009-09-19 10:43:41 +02:00
|
|
|
void sc_toggle_inputbar(Argument*);
|
2009-08-11 23:18:50 +02:00
|
|
|
void sc_quit(Argument*);
|
|
|
|
|
|
|
|
/* command declarations */
|
2009-08-15 12:35:07 +02:00
|
|
|
void cmd_export(int, char**);
|
2009-09-10 23:46:40 +02:00
|
|
|
void cmd_form(int, char**);
|
2009-08-12 21:45:49 +02:00
|
|
|
void cmd_goto(int, char**);
|
2009-08-15 12:35:07 +02:00
|
|
|
void cmd_info(int, char**);
|
|
|
|
void cmd_links(int, char**);
|
2009-08-11 23:18:50 +02:00
|
|
|
void cmd_open(int, char**);
|
2009-08-29 16:07:58 +02:00
|
|
|
void cmd_print(int, char**);
|
2009-08-12 21:45:49 +02:00
|
|
|
void cmd_rotate(int, char**);
|
2009-09-10 23:46:40 +02:00
|
|
|
void cmd_save(int, char**);
|
2009-08-11 23:18:50 +02:00
|
|
|
void cmd_quit(int, char**);
|
2009-08-12 21:45:49 +02:00
|
|
|
void cmd_zoom(int, char**);
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
/* callbacks declarations */
|
2009-08-12 21:45:49 +02:00
|
|
|
void cb_draw(GtkWidget*, gpointer);
|
2009-08-11 23:18:50 +02:00
|
|
|
void cb_destroy(GtkWidget*, gpointer);
|
|
|
|
void cb_inputbar_activate(GtkEntry*, gpointer);
|
|
|
|
void cb_inputbar_button_pressed(GtkWidget*, GdkEventButton*, gpointer);
|
2009-08-15 12:35:07 +02:00
|
|
|
void cb_drawing_area_button_pressed(GtkWidget*, GdkEventButton*, gpointer);
|
2009-08-11 23:18:50 +02:00
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
gboolean cb_label_open_link(GtkLabel*, gchar*, gpointer);
|
2009-08-11 23:18:50 +02:00
|
|
|
gboolean cb_inputbar_key_pressed(GtkEntry*, GdkEventKey*, gpointer);
|
|
|
|
gboolean cb_inputbar_key_released(GtkEntry*, GdkEventKey*, gpointer);
|
|
|
|
gboolean cb_view_key_pressed(GtkWidget*, GdkEventKey*, gpointer);
|
|
|
|
|
|
|
|
/* configuration */
|
|
|
|
#include "config.h"
|
|
|
|
|
|
|
|
/* function implementations */
|
|
|
|
void
|
|
|
|
init()
|
|
|
|
{
|
|
|
|
/* settings */
|
2009-08-13 22:55:36 +02:00
|
|
|
gdk_color_parse(default_fgcolor, &(Zathura.Settings.default_fg));
|
|
|
|
gdk_color_parse(default_bgcolor, &(Zathura.Settings.default_bg));
|
|
|
|
gdk_color_parse(inputbar_fgcolor, &(Zathura.Settings.inputbar_fg));
|
|
|
|
gdk_color_parse(inputbar_bgcolor, &(Zathura.Settings.inputbar_bg));
|
|
|
|
gdk_color_parse(notification_fgcolor, &(Zathura.Settings.notification_fg));
|
|
|
|
gdk_color_parse(notification_bgcolor, &(Zathura.Settings.notification_bg));
|
|
|
|
gdk_color_parse(notification_warning_fgcolor, &(Zathura.Settings.notification_wn_fg));
|
|
|
|
gdk_color_parse(notification_warning_bgcolor, &(Zathura.Settings.notification_wn_bg));
|
|
|
|
gdk_color_parse(notification_error_fgcolor, &(Zathura.Settings.notification_er_fg));
|
|
|
|
gdk_color_parse(notification_error_bgcolor, &(Zathura.Settings.notification_er_bg));
|
|
|
|
gdk_color_parse(completion_fgcolor, &(Zathura.Settings.completion_fg));
|
|
|
|
gdk_color_parse(completion_bgcolor, &(Zathura.Settings.completion_bg));
|
|
|
|
gdk_color_parse(completion_hl_fgcolor, &(Zathura.Settings.completion_hl_fg));
|
|
|
|
gdk_color_parse(completion_hl_bgcolor, &(Zathura.Settings.completion_hl_bg));
|
2009-08-15 12:35:07 +02:00
|
|
|
gdk_color_parse(search_highlight, &(Zathura.Settings.search_highlight));
|
2009-08-11 23:18:50 +02:00
|
|
|
Zathura.Settings.font = pango_font_description_from_string(font);
|
|
|
|
|
|
|
|
/* variables */
|
2009-08-12 21:45:49 +02:00
|
|
|
Zathura.window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
|
|
|
|
Zathura.box = GTK_BOX(gtk_vbox_new(FALSE, 0));
|
|
|
|
Zathura.view = GTK_SCROLLED_WINDOW(gtk_scrolled_window_new(NULL, NULL));
|
|
|
|
Zathura.drawing_area = gtk_drawing_area_new();
|
2009-08-13 22:55:36 +02:00
|
|
|
Zathura.notification = GTK_BOX(gtk_vbox_new(FALSE, 0));
|
2009-08-12 21:45:49 +02:00
|
|
|
Zathura.inputbar = GTK_ENTRY(gtk_entry_new());
|
|
|
|
Zathura.PDF.scale = 1.0;
|
|
|
|
Zathura.PDF.rotate = 0;
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
/* window */
|
2009-08-12 21:45:49 +02:00
|
|
|
gtk_window_set_title(Zathura.window, "zathura");
|
2009-08-15 12:35:07 +02:00
|
|
|
gtk_window_set_default_size(Zathura.window, DEFAULT_WIDTH, DEFAULT_HEIGHT);
|
|
|
|
g_signal_connect(G_OBJECT(Zathura.window), "destroy", G_CALLBACK(cb_destroy), NULL);
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
/* box */
|
|
|
|
gtk_box_set_spacing(Zathura.box, 0);
|
|
|
|
gtk_container_add(GTK_CONTAINER(Zathura.window), GTK_WIDGET(Zathura.box));
|
|
|
|
|
|
|
|
/* view */
|
2009-08-15 12:35:07 +02:00
|
|
|
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(Zathura.view),
|
|
|
|
Zathura.drawing_area);
|
|
|
|
gtk_viewport_set_shadow_type((GtkViewport*) gtk_bin_get_child(GTK_BIN(Zathura.view)), GTK_SHADOW_NONE);
|
2009-08-11 23:18:50 +02:00
|
|
|
g_signal_connect(G_OBJECT(Zathura.view), "key-press-event", G_CALLBACK(cb_view_key_pressed), NULL);
|
2009-08-13 22:55:36 +02:00
|
|
|
|
2009-09-12 11:19:51 +02:00
|
|
|
#if SHOW_SCROLLBARS
|
2009-08-11 23:18:50 +02:00
|
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.view), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
|
|
|
|
#else
|
|
|
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(Zathura.view), GTK_POLICY_NEVER, GTK_POLICY_NEVER);
|
|
|
|
#endif
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
/* drawing area */
|
2009-08-15 12:35:07 +02:00
|
|
|
g_signal_connect(G_OBJECT(Zathura.drawing_area), "expose-event", G_CALLBACK(cb_draw), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(Zathura.drawing_area), "button-press-event", G_CALLBACK(cb_drawing_area_button_pressed), NULL);
|
|
|
|
gtk_widget_set_events(Zathura.drawing_area, GDK_BUTTON_PRESS_MASK);
|
|
|
|
gtk_widget_modify_bg(GTK_WIDGET(Zathura.drawing_area), GTK_STATE_NORMAL, &(Zathura.Settings.default_bg));
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
/* inputbar */
|
|
|
|
gtk_entry_set_inner_border(Zathura.inputbar, NULL);
|
|
|
|
gtk_entry_set_has_frame(Zathura.inputbar, FALSE);
|
|
|
|
gtk_entry_set_editable(Zathura.inputbar,TRUE);
|
|
|
|
g_signal_connect(G_OBJECT(Zathura.inputbar), "activate", G_CALLBACK(cb_inputbar_activate), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(Zathura.inputbar), "button-press-event", G_CALLBACK(cb_inputbar_button_pressed), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(Zathura.inputbar), "key-press-event", G_CALLBACK(cb_inputbar_key_pressed), NULL);
|
|
|
|
g_signal_connect(G_OBJECT(Zathura.inputbar), "key-release-event", G_CALLBACK(cb_inputbar_key_released), NULL);
|
|
|
|
|
|
|
|
/* packing */
|
2009-08-13 22:55:36 +02:00
|
|
|
gtk_box_pack_start(Zathura.box, GTK_WIDGET(Zathura.view), TRUE, TRUE, 0);
|
|
|
|
gtk_box_pack_start(Zathura.box, GTK_WIDGET(Zathura.notification), FALSE, FALSE, 0);
|
|
|
|
gtk_box_pack_end(Zathura.box, GTK_WIDGET(Zathura.inputbar), FALSE, FALSE, 0);
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
/* visuals */
|
|
|
|
gtk_widget_modify_base(GTK_WIDGET(Zathura.inputbar), GTK_STATE_NORMAL, &(Zathura.Settings.inputbar_bg));
|
|
|
|
gtk_widget_modify_text(GTK_WIDGET(Zathura.inputbar), GTK_STATE_NORMAL, &(Zathura.Settings.inputbar_fg));
|
|
|
|
gtk_widget_modify_font(GTK_WIDGET(Zathura.inputbar), Zathura.Settings.font);
|
|
|
|
}
|
|
|
|
|
2009-09-19 15:53:35 +02:00
|
|
|
void
|
|
|
|
history(int direction)
|
|
|
|
{
|
|
|
|
static int current = 0;
|
|
|
|
int length = g_list_length(Zathura.history);
|
|
|
|
|
|
|
|
if(length > 0)
|
|
|
|
{
|
|
|
|
if(direction == NEXT)
|
|
|
|
current = (length + current + 1) % length;
|
|
|
|
else
|
|
|
|
current = (length + current - 1) % length;
|
|
|
|
|
|
|
|
char* command = (char*) g_list_nth_data(Zathura.history, current);
|
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(Zathura.inputbar));
|
|
|
|
gtk_entry_set_text(Zathura.inputbar, command);
|
|
|
|
gtk_editable_set_position(GTK_EDITABLE(Zathura.inputbar), -1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
void
|
|
|
|
update_title()
|
|
|
|
{
|
2009-08-12 21:45:49 +02:00
|
|
|
if(Zathura.PDF.file != NULL)
|
2009-08-13 22:55:36 +02:00
|
|
|
gtk_window_set_title(GTK_WINDOW(Zathura.window), Zathura.PDF.file);
|
2009-08-12 21:45:49 +02:00
|
|
|
else
|
|
|
|
gtk_window_set_title(GTK_WINDOW(Zathura.window), "zathura");
|
2009-08-11 23:18:50 +02:00
|
|
|
}
|
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
GtkWidget*
|
2009-08-13 22:55:36 +02:00
|
|
|
notify(int level, char* text)
|
2009-08-11 23:18:50 +02:00
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
GtkEventBox *view = GTK_EVENT_BOX(gtk_event_box_new());
|
2009-08-15 12:35:07 +02:00
|
|
|
|
|
|
|
update_notification(GTK_WIDGET(view), level, text);
|
|
|
|
|
|
|
|
gtk_container_add(GTK_CONTAINER(Zathura.notification), GTK_WIDGET(view));
|
2009-08-13 22:55:36 +02:00
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
gtk_widget_show_all(GTK_WIDGET(Zathura.window));
|
|
|
|
g_timeout_add_seconds(SHOW_NOTIFICATION, delete_widget, GTK_WIDGET(GTK_WIDGET(view)));
|
|
|
|
|
|
|
|
return GTK_WIDGET(view);
|
|
|
|
}
|
|
|
|
|
|
|
|
GtkWidget*
|
|
|
|
update_notification(GtkWidget* view, int level, char* text)
|
|
|
|
{
|
|
|
|
GtkLabel *message = GTK_LABEL(gtk_label_new(""));
|
|
|
|
gtk_label_set_markup(message, text);
|
|
|
|
g_signal_connect(G_OBJECT(message), "activate-link", G_CALLBACK(cb_label_open_link), NULL);
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
gtk_misc_set_alignment(GTK_MISC(message), 0, 0);
|
|
|
|
gtk_widget_modify_font(GTK_WIDGET(message), Zathura.Settings.font);
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
if(level == WARNING)
|
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
gtk_widget_modify_fg(GTK_WIDGET(message), GTK_STATE_NORMAL, &(Zathura.Settings.notification_wn_fg));
|
|
|
|
gtk_widget_modify_bg(GTK_WIDGET(view), GTK_STATE_NORMAL, &(Zathura.Settings.notification_wn_bg));
|
2009-08-11 23:18:50 +02:00
|
|
|
}
|
2009-08-13 22:55:36 +02:00
|
|
|
else if(level == ERROR)
|
2009-08-11 23:18:50 +02:00
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
gtk_widget_modify_fg(GTK_WIDGET(message), GTK_STATE_NORMAL, &(Zathura.Settings.notification_er_fg));
|
|
|
|
gtk_widget_modify_bg(GTK_WIDGET(view), GTK_STATE_NORMAL, &(Zathura.Settings.notification_er_bg));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
gtk_widget_modify_fg(GTK_WIDGET(message), GTK_STATE_NORMAL, &(Zathura.Settings.notification_fg));
|
|
|
|
gtk_widget_modify_bg(GTK_WIDGET(view), GTK_STATE_NORMAL, &(Zathura.Settings.notification_bg));
|
2009-08-11 23:18:50 +02:00
|
|
|
}
|
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
if(gtk_bin_get_child(GTK_BIN(view)))
|
|
|
|
gtk_container_remove(GTK_CONTAINER(view), gtk_bin_get_child(GTK_BIN(view)));
|
2009-08-13 22:55:36 +02:00
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
gtk_container_add(GTK_CONTAINER(view), GTK_WIDGET(message));
|
2009-08-13 22:55:36 +02:00
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
return GTK_WIDGET(view);
|
2009-08-13 22:55:36 +02:00
|
|
|
}
|
|
|
|
|
2009-08-29 16:07:58 +02:00
|
|
|
PopplerRectangle*
|
|
|
|
recalcRectangle(PopplerRectangle* rectangle)
|
|
|
|
{
|
|
|
|
double page_width, page_height;
|
|
|
|
double x1 = rectangle->x1;
|
|
|
|
double x2 = rectangle->x2;
|
|
|
|
double y1 = rectangle->y1;
|
|
|
|
double y2 = rectangle->y2;
|
|
|
|
|
|
|
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
|
|
|
|
|
|
|
switch(Zathura.PDF.rotate)
|
|
|
|
{
|
|
|
|
case 90:
|
|
|
|
rectangle->x1 = (page_height - y2) * Zathura.PDF.scale;
|
|
|
|
rectangle->y1 = x1 * Zathura.PDF.scale;
|
|
|
|
rectangle->x2 = (page_height - y1) * Zathura.PDF.scale;
|
|
|
|
rectangle->y2 = x2 * Zathura.PDF.scale;
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
rectangle->x1 = (page_width - x2) * Zathura.PDF.scale;
|
|
|
|
rectangle->y1 = (page_height - y2) * Zathura.PDF.scale;
|
|
|
|
rectangle->x2 = (page_width - x1) * Zathura.PDF.scale;
|
|
|
|
rectangle->y2 = (page_height - y1) * Zathura.PDF.scale;
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
rectangle->x1 = y1 * Zathura.PDF.scale;
|
|
|
|
rectangle->y1 = (page_width - x2) * Zathura.PDF.scale;
|
|
|
|
rectangle->x2 = y2 * Zathura.PDF.scale;
|
|
|
|
rectangle->y2 = (page_width - x1) * Zathura.PDF.scale;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
rectangle->x1 = x1 * Zathura.PDF.scale;
|
|
|
|
rectangle->y1 = y1 * Zathura.PDF.scale;
|
|
|
|
rectangle->x2 = x2 * Zathura.PDF.scale;
|
|
|
|
rectangle->y2 = y2 * Zathura.PDF.scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rectangle;
|
|
|
|
}
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
void
|
|
|
|
update_status()
|
|
|
|
{
|
|
|
|
char* text = "";
|
|
|
|
|
|
|
|
if(Zathura.PDF.document && Zathura.PDF.page)
|
2009-08-15 12:35:07 +02:00
|
|
|
text = g_strdup_printf("[%i/%i] %s", Zathura.PDF.page_number + 1, Zathura.PDF.number_of_pages, Zathura.PDF.file);
|
2009-08-12 21:45:49 +02:00
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
gtk_entry_set_text(Zathura.inputbar, text);
|
|
|
|
}
|
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
void set_page(int page_number)
|
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
if(page_number > Zathura.PDF.number_of_pages)
|
2009-08-12 21:45:49 +02:00
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
notify(WARNING, "Could not open page");
|
2009-08-12 21:45:49 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Zathura.PDF.page_number = page_number;
|
|
|
|
Zathura.PDF.page = poppler_document_get_page(Zathura.PDF.document, page_number);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
draw()
|
|
|
|
{
|
|
|
|
if(!Zathura.PDF.document || !Zathura.PDF.page)
|
|
|
|
return;
|
|
|
|
|
|
|
|
double page_width, page_height;
|
|
|
|
double width, height;
|
|
|
|
|
|
|
|
if(Zathura.PDF.surface)
|
|
|
|
cairo_surface_destroy(Zathura.PDF.surface);
|
|
|
|
Zathura.PDF.surface = NULL;
|
|
|
|
|
|
|
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
|
|
|
|
|
|
|
if(Zathura.PDF.rotate == 0 || Zathura.PDF.rotate == 180)
|
|
|
|
{
|
|
|
|
width = page_width * Zathura.PDF.scale;
|
|
|
|
height = page_height * Zathura.PDF.scale;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width = page_height * Zathura.PDF.scale;
|
|
|
|
height = page_width * Zathura.PDF.scale;
|
|
|
|
}
|
|
|
|
|
|
|
|
cairo_t *cairo;
|
|
|
|
Zathura.PDF.surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, width, height);
|
|
|
|
cairo = cairo_create(Zathura.PDF.surface);
|
|
|
|
|
|
|
|
cairo_save(cairo);
|
|
|
|
cairo_set_source_rgb(cairo, 1, 1, 1);
|
|
|
|
cairo_rectangle(cairo, 0, 0, width, height);
|
|
|
|
cairo_fill(cairo);
|
|
|
|
cairo_restore(cairo);
|
|
|
|
cairo_save(cairo);
|
|
|
|
|
|
|
|
switch(Zathura.PDF.rotate)
|
|
|
|
{
|
|
|
|
case 90:
|
|
|
|
cairo_translate(cairo, width, 0);
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
cairo_translate(cairo, width, height);
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
cairo_translate(cairo, 0, height);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
cairo_translate(cairo, 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(Zathura.PDF.scale != 1.0)
|
|
|
|
cairo_scale(cairo, Zathura.PDF.scale, Zathura.PDF.scale);
|
|
|
|
|
|
|
|
if(Zathura.PDF.rotate != 0)
|
|
|
|
cairo_rotate(cairo, Zathura.PDF.rotate * G_PI / 180.0);
|
|
|
|
|
|
|
|
poppler_page_render(Zathura.PDF.page, cairo);
|
2009-09-12 11:19:51 +02:00
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
cairo_restore(cairo);
|
|
|
|
cairo_destroy(cairo);
|
|
|
|
|
|
|
|
gtk_widget_set_size_request(Zathura.drawing_area, width, height);
|
|
|
|
gtk_widget_queue_draw(Zathura.drawing_area);
|
|
|
|
}
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
void
|
2009-08-15 12:35:07 +02:00
|
|
|
highlight_result(PopplerRectangle* rectangle)
|
2009-08-13 22:55:36 +02:00
|
|
|
{
|
2009-08-15 12:35:07 +02:00
|
|
|
cairo_t *cairo = cairo_create(Zathura.PDF.surface);
|
|
|
|
cairo_set_source_rgba(cairo, Zathura.Settings.search_highlight.red, Zathura.Settings.search_highlight.green,
|
|
|
|
Zathura.Settings.search_highlight.blue, HL_TRANSPARENCY);
|
|
|
|
|
2009-08-29 16:07:58 +02:00
|
|
|
rectangle = recalcRectangle(rectangle);
|
|
|
|
|
|
|
|
cairo_rectangle(cairo, rectangle->x1, rectangle->y1, (rectangle->x2 - rectangle->x1), (rectangle->y2 - rectangle->y1));
|
2009-08-15 12:35:07 +02:00
|
|
|
cairo_fill(cairo);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
open_link(char* link)
|
|
|
|
{
|
|
|
|
char* start_browser = g_strdup_printf(BROWSER, link);
|
|
|
|
system(start_browser);
|
2009-08-13 22:55:36 +02:00
|
|
|
}
|
|
|
|
|
2009-08-29 16:07:58 +02:00
|
|
|
void
|
|
|
|
save_images(int page, char* directory)
|
|
|
|
{
|
|
|
|
GList *image_list;
|
|
|
|
GList *images;
|
|
|
|
cairo_surface_t *image;
|
|
|
|
PopplerPage *document_page;
|
|
|
|
|
|
|
|
document_page = poppler_document_get_page(Zathura.PDF.document, page);
|
|
|
|
image_list = poppler_page_get_image_mapping(document_page);
|
|
|
|
|
|
|
|
for(images = image_list; images; images = g_list_next(images))
|
|
|
|
{
|
|
|
|
PopplerImageMapping *image_mapping;
|
|
|
|
PopplerRectangle image_field;
|
|
|
|
gint image_id;
|
|
|
|
char* file;
|
2009-09-19 10:43:41 +02:00
|
|
|
char* filename;
|
2009-08-29 16:07:58 +02:00
|
|
|
|
|
|
|
image_mapping = (PopplerImageMapping*) images->data;
|
|
|
|
image_field = image_mapping->area;
|
|
|
|
image_id = image_mapping->image_id;
|
|
|
|
|
2009-09-19 10:43:41 +02:00
|
|
|
image = poppler_page_get_image(document_page, image_id);
|
|
|
|
filename = g_strdup_printf("p%i_i%i.png", page + 1, image_id);
|
|
|
|
|
|
|
|
if(directory[0] == '~')
|
|
|
|
{
|
|
|
|
file = malloc(((int) strlen(filename) + (int) strlen(directory)
|
|
|
|
+ (int) strlen(getenv("HOME")) - 1) * sizeof(char));
|
|
|
|
file = g_strdup_printf("%s%s%s", getenv("HOME"), directory + 1, filename);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
file = g_strdup_printf("%s%s", directory, filename);
|
2009-08-29 16:07:58 +02:00
|
|
|
|
|
|
|
cairo_surface_write_to_png(image, file);
|
|
|
|
|
|
|
|
g_free(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
save_attachments(char* directory)
|
|
|
|
{
|
|
|
|
GList *attachment_list;
|
|
|
|
GList *attachments;
|
|
|
|
char *file;
|
|
|
|
|
|
|
|
attachment_list = poppler_document_get_attachments(Zathura.PDF.document);
|
|
|
|
|
|
|
|
for(attachments = attachment_list; attachments; attachments = g_list_next(attachments))
|
|
|
|
{
|
|
|
|
PopplerAttachment *attachment = (PopplerAttachment*) attachments->data;
|
2009-09-19 10:43:41 +02:00
|
|
|
|
|
|
|
if(directory[0] == '~')
|
|
|
|
{
|
|
|
|
file = malloc(((int) strlen(attachment->name) + (int) strlen(directory)
|
|
|
|
+ (int) strlen(getenv("HOME")) - 1) * sizeof(char));
|
|
|
|
file = g_strdup_printf("%s%s%s", getenv("HOME"), directory + 1, attachment->name);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
file = g_strdup_printf("%s%s", directory, attachment->name);
|
2009-08-29 16:07:58 +02:00
|
|
|
|
|
|
|
poppler_attachment_save(attachment, file, NULL);
|
|
|
|
|
|
|
|
g_free(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
gboolean
|
2009-08-13 22:55:36 +02:00
|
|
|
delete_widget(gpointer data)
|
2009-08-11 23:18:50 +02:00
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
gtk_widget_destroy(GTK_WIDGET(data));
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-08-11 23:18:50 +02:00
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
gboolean
|
|
|
|
complete(Argument* argument)
|
|
|
|
{
|
2009-08-11 23:18:50 +02:00
|
|
|
static GtkBox *results;
|
|
|
|
static GtkWidget **result_rows;
|
|
|
|
static char **command_names;
|
|
|
|
static int n = 0;
|
|
|
|
static int current = -1;
|
|
|
|
|
|
|
|
char *command = (char*) gtk_entry_get_text(Zathura.inputbar);
|
|
|
|
int command_length = strlen(command);
|
|
|
|
int length = 0;
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
if( (command_length == 0 || command[0] != ':') && argument->n != HIDE )
|
|
|
|
return TRUE;
|
|
|
|
|
|
|
|
if(argument->n != HIDE && n > 0 && results && current != -1 && !strcmp(&command[1], command_names[current]) )
|
|
|
|
{
|
|
|
|
GtkEventBox *current_box = (GtkEventBox*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(results)), current);
|
|
|
|
GtkLabel *current_label = (GtkLabel*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(current_box)), 0);
|
|
|
|
|
|
|
|
gtk_widget_modify_fg(GTK_WIDGET(current_label), GTK_STATE_NORMAL, &(Zathura.Settings.completion_fg));
|
|
|
|
gtk_widget_modify_bg(GTK_WIDGET(current_box), GTK_STATE_NORMAL, &(Zathura.Settings.completion_bg));
|
|
|
|
|
|
|
|
if(argument->n == NEXT)
|
|
|
|
current = (current + n + 1) % n;
|
|
|
|
else if (argument->n == PREVIOUS)
|
|
|
|
current = (current + n - 1) % n;
|
|
|
|
|
|
|
|
current_box = (GtkEventBox*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(results)), current);
|
|
|
|
current_label = (GtkLabel*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(current_box)), 0);
|
|
|
|
|
|
|
|
gtk_widget_modify_fg(GTK_WIDGET(current_label), GTK_STATE_NORMAL, &(Zathura.Settings.completion_hl_fg));
|
|
|
|
gtk_widget_modify_bg(GTK_WIDGET(current_box), GTK_STATE_NORMAL, &(Zathura.Settings.completion_hl_bg));
|
|
|
|
|
|
|
|
char* temp_string = g_strconcat(":", command_names[current], NULL);
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(Zathura.inputbar), temp_string);
|
|
|
|
gtk_editable_set_position(GTK_EDITABLE(Zathura.inputbar), -1);
|
|
|
|
g_free(temp_string);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(results != NULL)
|
|
|
|
gtk_widget_destroy(GTK_WIDGET(results));
|
|
|
|
|
|
|
|
free(result_rows);
|
|
|
|
free(command_names);
|
|
|
|
|
|
|
|
n = 0;
|
|
|
|
current = -1;
|
|
|
|
results = NULL;
|
|
|
|
result_rows = NULL;
|
|
|
|
command_names = NULL;
|
|
|
|
|
|
|
|
if(argument->n == HIDE)
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!results)
|
|
|
|
{
|
|
|
|
results = GTK_BOX(gtk_vbox_new(FALSE, 0));
|
|
|
|
result_rows = malloc(LENGTH(commands) * sizeof(GtkWidget*));
|
|
|
|
command_names = malloc(LENGTH(commands) * sizeof(char*));
|
|
|
|
|
|
|
|
for(i = 0; i < LENGTH(commands); i++)
|
|
|
|
{
|
|
|
|
length = strlen(commands[i].command);
|
|
|
|
|
|
|
|
if( (command_length - 1 <= length) && !strncmp(&command[1], commands[i].command, command_length - 1) )
|
|
|
|
{
|
|
|
|
GtkLabel *show_command = GTK_LABEL(gtk_label_new(commands[i].command));
|
|
|
|
GtkEventBox *event_box = GTK_EVENT_BOX(gtk_event_box_new());
|
|
|
|
|
|
|
|
gtk_misc_set_alignment(GTK_MISC(show_command), 0, 0);
|
|
|
|
gtk_widget_modify_fg( GTK_WIDGET(show_command), GTK_STATE_NORMAL, &(Zathura.Settings.completion_fg));
|
|
|
|
gtk_widget_modify_bg( GTK_WIDGET(event_box), GTK_STATE_NORMAL, &(Zathura.Settings.completion_bg));
|
|
|
|
gtk_widget_modify_font(GTK_WIDGET(show_command), Zathura.Settings.font);
|
|
|
|
|
|
|
|
gtk_container_add(GTK_CONTAINER(event_box), GTK_WIDGET(show_command));
|
|
|
|
gtk_box_pack_start(results, GTK_WIDGET(event_box), FALSE, FALSE, 0);
|
|
|
|
|
|
|
|
command_names[n] = commands[i].command;
|
|
|
|
result_rows[n++] = GTK_WIDGET(event_box);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
command_names = realloc(command_names, n * sizeof(char*));
|
|
|
|
result_rows = realloc(result_rows, n * sizeof(GtkWidget*));
|
|
|
|
|
|
|
|
gtk_box_pack_start(Zathura.box, GTK_WIDGET(results), FALSE, FALSE, 0);
|
|
|
|
gtk_widget_show_all(GTK_WIDGET(Zathura.window));
|
|
|
|
|
|
|
|
current = (argument->n == NEXT) ? 0 : (n - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(current != -1 && n > 0)
|
|
|
|
{
|
|
|
|
GtkEventBox *current_box = (GtkEventBox*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(results)), current);
|
|
|
|
GtkLabel *current_label = (GtkLabel*) g_list_nth_data(gtk_container_get_children(GTK_CONTAINER(current_box)), 0);
|
|
|
|
|
|
|
|
gtk_widget_modify_fg(GTK_WIDGET(current_label), GTK_STATE_NORMAL, &(Zathura.Settings.completion_hl_fg));
|
|
|
|
gtk_widget_modify_bg(GTK_WIDGET(current_box), GTK_STATE_NORMAL, &(Zathura.Settings.completion_hl_bg));
|
|
|
|
|
|
|
|
char* temp_string = g_strconcat(":", command_names[current], NULL);
|
|
|
|
gtk_entry_set_text(GTK_ENTRY(Zathura.inputbar), temp_string);
|
|
|
|
gtk_editable_set_position(GTK_EDITABLE(Zathura.inputbar), -1);
|
|
|
|
g_free(temp_string);
|
|
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* shortcut implementations */
|
|
|
|
void
|
|
|
|
sc_focus_inputbar(Argument *argument)
|
|
|
|
{
|
2009-09-19 15:53:35 +02:00
|
|
|
if(argument->data)
|
|
|
|
gtk_entry_set_text(Zathura.inputbar, argument->data);
|
|
|
|
else
|
|
|
|
history(PREVIOUS);
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
gtk_widget_modify_text(GTK_WIDGET(Zathura.inputbar), GTK_STATE_NORMAL, &(Zathura.Settings.inputbar_fg));
|
|
|
|
gtk_widget_modify_base(GTK_WIDGET(Zathura.inputbar), GTK_STATE_NORMAL, &(Zathura.Settings.inputbar_bg));
|
2009-09-19 15:53:35 +02:00
|
|
|
|
|
|
|
if(argument->data)
|
|
|
|
{
|
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(Zathura.inputbar));
|
|
|
|
gtk_editable_set_position(GTK_EDITABLE(Zathura.inputbar), -1);
|
|
|
|
}
|
2009-08-11 23:18:50 +02:00
|
|
|
}
|
2009-08-12 21:45:49 +02:00
|
|
|
|
|
|
|
void
|
|
|
|
sc_scroll(Argument *argument)
|
|
|
|
{
|
|
|
|
GtkAdjustment* adjustment;
|
|
|
|
|
|
|
|
if( (argument->n == LEFT) || (argument->n == RIGHT) )
|
|
|
|
adjustment = gtk_scrolled_window_get_hadjustment(Zathura.view);
|
|
|
|
else
|
|
|
|
adjustment = gtk_scrolled_window_get_vadjustment(Zathura.view);
|
|
|
|
|
|
|
|
gdouble view_size = gtk_adjustment_get_page_size(adjustment);
|
|
|
|
gdouble value = gtk_adjustment_get_value(adjustment);
|
|
|
|
gdouble max = gtk_adjustment_get_upper(adjustment) - view_size;
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
if( (argument->n == LEFT) || (argument->n == DOWN))
|
2009-08-12 21:45:49 +02:00
|
|
|
gtk_adjustment_set_value(adjustment, (value - SCROLL_STEP) < 0 ? 0 : (value - SCROLL_STEP));
|
2009-08-13 22:55:36 +02:00
|
|
|
else if (argument->n == TOP)
|
|
|
|
gtk_adjustment_set_value(adjustment, 0);
|
|
|
|
else if(argument->n == BOTTOM)
|
|
|
|
gtk_adjustment_set_value(adjustment, max);
|
2009-08-12 21:45:49 +02:00
|
|
|
else
|
|
|
|
gtk_adjustment_set_value(adjustment, (value + SCROLL_STEP) > max ? max : (value + SCROLL_STEP));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_navigate(Argument *argument)
|
|
|
|
{
|
|
|
|
int number_of_pages = poppler_document_get_n_pages(Zathura.PDF.document);
|
|
|
|
int new_page = Zathura.PDF.page_number;
|
|
|
|
|
|
|
|
if(argument->n == NEXT)
|
|
|
|
new_page = abs( (new_page + number_of_pages + 1) % number_of_pages);
|
|
|
|
else if(argument->n == PREVIOUS)
|
|
|
|
new_page = abs( (new_page + number_of_pages - 1) % number_of_pages);
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
set_page(new_page);
|
|
|
|
|
|
|
|
Argument reset;
|
|
|
|
reset.n = TOP;
|
|
|
|
sc_scroll(&reset);
|
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
draw();
|
2009-08-13 22:55:36 +02:00
|
|
|
|
|
|
|
update_status();
|
2009-08-12 21:45:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_zoom(Argument *argument)
|
|
|
|
{
|
|
|
|
if(argument->n == ZOOM_IN)
|
|
|
|
Zathura.PDF.scale += ZOOM_STEP;
|
|
|
|
else if(argument->n == ZOOM_OUT)
|
|
|
|
Zathura.PDF.scale -= ZOOM_STEP;
|
|
|
|
else if(argument->n == ZOOM_ORIGINAL)
|
|
|
|
Zathura.PDF.scale = 1.0;
|
|
|
|
|
|
|
|
draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_adjust_window(Argument *argument)
|
|
|
|
{
|
|
|
|
GtkAdjustment* adjustment;
|
|
|
|
double view_size;
|
|
|
|
double page_width;
|
|
|
|
double page_height;
|
|
|
|
|
|
|
|
if(argument->n == ADJUST_WIDTH)
|
|
|
|
adjustment = gtk_scrolled_window_get_vadjustment(Zathura.view);
|
|
|
|
else
|
|
|
|
adjustment = gtk_scrolled_window_get_hadjustment(Zathura.view);
|
|
|
|
|
|
|
|
view_size = gtk_adjustment_get_page_size(adjustment);
|
|
|
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
|
|
|
|
|
|
|
if(argument->n == ADJUST_WIDTH)
|
|
|
|
Zathura.PDF.scale = view_size / page_height;
|
|
|
|
else
|
|
|
|
Zathura.PDF.scale = view_size / page_width;
|
2009-09-19 10:43:41 +02:00
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
draw();
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
sc_rotate(Argument *argument)
|
|
|
|
{
|
|
|
|
if(argument->n == LEFT)
|
2009-09-19 10:43:41 +02:00
|
|
|
Zathura.PDF.rotate = (270 + Zathura.PDF.rotate) % 360;
|
2009-08-12 21:45:49 +02:00
|
|
|
else if(argument->n == RIGHT)
|
2009-09-19 10:43:41 +02:00
|
|
|
Zathura.PDF.rotate = (450 + Zathura.PDF.rotate) % 360;
|
2009-08-12 21:45:49 +02:00
|
|
|
|
|
|
|
draw();
|
|
|
|
}
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
void
|
|
|
|
sc_search(Argument *argument)
|
|
|
|
{
|
|
|
|
static char* search_item;
|
|
|
|
static int direction;
|
|
|
|
int page_counter;
|
|
|
|
GList* results;
|
|
|
|
GList* list;
|
|
|
|
|
|
|
|
if(argument->data)
|
2009-09-12 11:19:51 +02:00
|
|
|
search_item = g_strdup((char*) argument->data);
|
2009-08-13 22:55:36 +02:00
|
|
|
|
|
|
|
if(!Zathura.PDF.document || !Zathura.PDF.page || !search_item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* search document */
|
2009-08-15 12:35:07 +02:00
|
|
|
GtkWidget* search_status = notify(DEFAULT, "Searching...");
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
if(argument->n)
|
|
|
|
direction = (argument->n == BACKWARD) ? -1 : 1;
|
|
|
|
|
2009-09-12 11:19:51 +02:00
|
|
|
for(page_counter = 1; page_counter <= Zathura.PDF.number_of_pages; page_counter++)
|
2009-08-13 22:55:36 +02:00
|
|
|
{
|
2009-09-12 11:19:51 +02:00
|
|
|
int next_page = (Zathura.PDF.number_of_pages + Zathura.PDF.page_number +
|
|
|
|
page_counter * direction) % Zathura.PDF.number_of_pages;
|
2009-08-13 22:55:36 +02:00
|
|
|
set_page(next_page);
|
|
|
|
|
|
|
|
results = poppler_page_find_text(Zathura.PDF.page, search_item);
|
|
|
|
if(results)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* draw results */
|
|
|
|
if(results)
|
|
|
|
{
|
2009-08-29 16:07:58 +02:00
|
|
|
double page_width, page_height;
|
|
|
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
2009-08-13 22:55:36 +02:00
|
|
|
draw();
|
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
update_notification(GTK_WIDGET(search_status), DEFAULT, g_strdup_printf("%s found on page %i for %i time(s)",
|
|
|
|
search_item, Zathura.PDF.page_number, g_list_length(results)));
|
2009-08-13 22:55:36 +02:00
|
|
|
|
|
|
|
for(list = results; list && list->data; list = g_list_next(list))
|
|
|
|
{
|
2009-08-29 16:07:58 +02:00
|
|
|
PopplerRectangle* result = (PopplerRectangle*) list->data;
|
|
|
|
result->y1 = page_height - result->y1;
|
|
|
|
result->y2 = page_height - result->y2;
|
|
|
|
highlight_result(result);
|
2009-08-13 22:55:36 +02:00
|
|
|
}
|
2009-09-12 11:19:51 +02:00
|
|
|
|
|
|
|
if(argument->n == FORWARD || argument->n == BACKWARD)
|
|
|
|
update_status();
|
2009-08-13 22:55:36 +02:00
|
|
|
}
|
|
|
|
else
|
2009-08-15 12:35:07 +02:00
|
|
|
update_notification(search_status, DEFAULT, g_strdup_printf("No match for %s", search_item));
|
2009-08-13 22:55:36 +02:00
|
|
|
}
|
|
|
|
|
2009-09-19 10:43:41 +02:00
|
|
|
void
|
|
|
|
sc_toggle_inputbar(Argument *argument)
|
|
|
|
{
|
2009-09-19 15:53:35 +02:00
|
|
|
if(GTK_WIDGET_VISIBLE(GTK_WIDGET(Zathura.inputbar)))
|
2009-09-19 10:43:41 +02:00
|
|
|
gtk_widget_hide(GTK_WIDGET(Zathura.inputbar));
|
|
|
|
else
|
|
|
|
gtk_widget_show(GTK_WIDGET(Zathura.inputbar));
|
|
|
|
|
|
|
|
cb_draw(Zathura.drawing_area, NULL);
|
|
|
|
}
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
void
|
|
|
|
sc_quit(Argument *argument)
|
|
|
|
{
|
|
|
|
cb_destroy(NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* command implementations */
|
|
|
|
void
|
|
|
|
cmd_open(int argc, char** argv)
|
|
|
|
{
|
2009-08-12 21:45:49 +02:00
|
|
|
if(argc == 0 || (int) strlen(argv[0]) == 0)
|
|
|
|
return;
|
|
|
|
|
2009-08-30 23:27:22 +02:00
|
|
|
char* file = realpath(argv[0], NULL);
|
2009-09-19 10:43:41 +02:00
|
|
|
|
|
|
|
if(argv[0][0] == '~')
|
|
|
|
{
|
|
|
|
file = realloc(file, ((int) strlen(argv[0]) + (int) strlen(getenv("HOME")) - 1) * sizeof(char));
|
|
|
|
file = g_strdup_printf("%s%s", getenv("HOME"), argv[0] + 1);
|
|
|
|
}
|
2009-08-12 21:45:49 +02:00
|
|
|
|
2009-08-30 23:27:22 +02:00
|
|
|
if(!g_file_test(file, G_FILE_TEST_IS_REGULAR))
|
2009-08-13 22:55:36 +02:00
|
|
|
{
|
|
|
|
notify(ERROR, "File does not exist");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-08-30 23:27:22 +02:00
|
|
|
Zathura.PDF.document = poppler_document_new_from_file(g_strdup_printf("file://%s", file),
|
|
|
|
(argc == 2) ? argv[1] : NULL, NULL);
|
2009-08-13 22:55:36 +02:00
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
if(!Zathura.PDF.document)
|
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
notify(WARNING, "Can not open file");
|
2009-08-12 21:45:49 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
Zathura.PDF.number_of_pages = poppler_document_get_n_pages(Zathura.PDF.document);
|
2009-09-10 23:46:40 +02:00
|
|
|
Zathura.PDF.file = file;
|
2009-08-12 21:45:49 +02:00
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
set_page(0);
|
2009-08-12 21:45:49 +02:00
|
|
|
draw();
|
2009-08-29 16:07:58 +02:00
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
update_status();
|
2009-08-12 21:45:49 +02:00
|
|
|
update_title();
|
|
|
|
}
|
|
|
|
|
2009-08-29 16:07:58 +02:00
|
|
|
void
|
|
|
|
cmd_print(int argc, char** argv)
|
|
|
|
{
|
|
|
|
if(argc == 0 || !Zathura.PDF.document)
|
|
|
|
return;
|
|
|
|
|
|
|
|
char* print_command;
|
|
|
|
char* sites;
|
2009-09-19 10:43:41 +02:00
|
|
|
char* printer;
|
2009-08-29 16:07:58 +02:00
|
|
|
|
|
|
|
if(strcmp(argv[0], "all") == 0)
|
|
|
|
sites = g_strdup_printf("%i", Zathura.PDF.number_of_pages);
|
|
|
|
else
|
|
|
|
sites = argv[0];
|
|
|
|
|
2009-09-19 10:43:41 +02:00
|
|
|
if(argc == 2)
|
|
|
|
{
|
|
|
|
if(atoi(argv[1]) != 0 && atoi(argv[1]) <= (sizeof(PRINTER) / sizeof(char*)))
|
|
|
|
printer = (char*) PRINTER[atoi(argv[1]) - 1];
|
|
|
|
else
|
|
|
|
printer = argv[1];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
printer = (char*) PRINTER[0];
|
2009-08-29 16:07:58 +02:00
|
|
|
|
2009-09-19 10:43:41 +02:00
|
|
|
print_command = g_strdup_printf("lp -d '%s' -P %s %s", printer, sites, Zathura.PDF.file);
|
2009-08-29 16:07:58 +02:00
|
|
|
system(print_command);
|
|
|
|
}
|
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
void
|
|
|
|
cmd_export(int argc, char** argv)
|
|
|
|
{
|
2009-08-29 16:07:58 +02:00
|
|
|
if(argc == 0 || !Zathura.PDF.document)
|
2009-08-15 12:35:07 +02:00
|
|
|
return;
|
|
|
|
|
2009-08-29 16:07:58 +02:00
|
|
|
if(argc < 2)
|
2009-08-15 12:35:07 +02:00
|
|
|
{
|
2009-08-29 16:07:58 +02:00
|
|
|
notify(WARNING, "No export path specified");
|
|
|
|
return;
|
2009-08-15 12:35:07 +02:00
|
|
|
}
|
2009-08-29 16:07:58 +02:00
|
|
|
|
|
|
|
/* export images */
|
|
|
|
if(strcmp(argv[0], "images") == 0)
|
2009-08-15 12:35:07 +02:00
|
|
|
{
|
2009-08-29 16:07:58 +02:00
|
|
|
int page_counter;
|
|
|
|
|
|
|
|
if(argc == 3)
|
|
|
|
{
|
|
|
|
int page_number = atoi(argv[2]) - 1;
|
|
|
|
|
|
|
|
if(page_number < 0 || page_number > Zathura.PDF.number_of_pages)
|
|
|
|
notify(WARNING, "Page does not exist");
|
|
|
|
else
|
|
|
|
save_images(page_number, argv[1]);
|
2009-08-15 12:35:07 +02:00
|
|
|
|
2009-08-29 16:07:58 +02:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(page_counter = 0; page_counter < Zathura.PDF.number_of_pages; page_counter++)
|
|
|
|
{
|
|
|
|
save_images(page_counter, argv[1]);
|
|
|
|
}
|
2009-08-15 12:35:07 +02:00
|
|
|
}
|
2009-08-29 16:07:58 +02:00
|
|
|
|
|
|
|
/* export attachments */
|
2009-08-15 12:35:07 +02:00
|
|
|
else if(strcmp(argv[0], "attachments") == 0)
|
|
|
|
{
|
2009-08-29 16:07:58 +02:00
|
|
|
if(!poppler_document_has_attachments(Zathura.PDF.document))
|
|
|
|
notify(WARNING, "PDF file has no attachments");
|
|
|
|
else
|
|
|
|
save_attachments(argv[1]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
notify(DEFAULT, "export [images|attachments]");
|
|
|
|
return;
|
2009-08-15 12:35:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-10 23:46:40 +02:00
|
|
|
void
|
|
|
|
cmd_form(int argc, char** argv)
|
|
|
|
{
|
|
|
|
if(argc == 0 || !Zathura.PDF.document || !Zathura.PDF.page)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if(strcmp(argv[0], "show") == 0)
|
|
|
|
{
|
|
|
|
double page_width, page_height;
|
|
|
|
int form_id = 0;
|
|
|
|
GList* form_mapping = g_list_reverse(poppler_page_get_form_field_mapping(Zathura.PDF.page));
|
|
|
|
GList* forms;
|
|
|
|
|
|
|
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
|
|
|
|
|
|
|
for(forms = form_mapping; forms; forms = g_list_next(forms))
|
|
|
|
{
|
|
|
|
/* draw rectangle */
|
|
|
|
PopplerFormFieldMapping *form = (PopplerFormFieldMapping*) forms->data;
|
|
|
|
PopplerRectangle *form_rectangle = &form->area;
|
|
|
|
|
|
|
|
if(!poppler_form_field_is_read_only(form->field))
|
|
|
|
{
|
|
|
|
form_rectangle->y1 = page_height - form_rectangle->y1;
|
|
|
|
form_rectangle->y2 = page_height - form_rectangle->y2;
|
|
|
|
|
|
|
|
highlight_result(form_rectangle);
|
|
|
|
|
|
|
|
/* draw text */
|
|
|
|
cairo_t *cairo = cairo_create(Zathura.PDF.surface);
|
|
|
|
cairo_select_font_face(cairo, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
|
|
|
|
cairo_set_font_size(cairo, 10);
|
|
|
|
cairo_move_to(cairo, form_rectangle->x1 + 1, form_rectangle->y1 - 1);
|
|
|
|
cairo_show_text(cairo, g_strdup_printf("%i", form_id));
|
|
|
|
}
|
|
|
|
|
|
|
|
form_id++;
|
|
|
|
}
|
2009-09-11 21:03:33 +02:00
|
|
|
|
|
|
|
gtk_widget_queue_draw(Zathura.drawing_area);
|
2009-09-10 23:46:40 +02:00
|
|
|
poppler_page_free_form_field_mapping(form_mapping);
|
|
|
|
}
|
|
|
|
else if(strcmp(argv[0], "set") == 0)
|
|
|
|
{
|
|
|
|
if(argc <= 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
GList* form_mapping = g_list_reverse(poppler_page_get_form_field_mapping(Zathura.PDF.page));
|
|
|
|
int form_id = atoi(argv[1]);
|
|
|
|
|
|
|
|
PopplerFormFieldMapping *form = (PopplerFormFieldMapping*) g_list_nth_data(form_mapping, form_id);
|
|
|
|
PopplerFormFieldType type = poppler_form_field_get_field_type(form->field);
|
|
|
|
|
|
|
|
if(type == POPPLER_FORM_FIELD_TEXT)
|
|
|
|
{
|
|
|
|
char *text = "";
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for(i = 2; i < argc; i++)
|
|
|
|
text = g_strdup_printf("%s %s", text, argv[i]);
|
|
|
|
|
|
|
|
poppler_form_field_text_set_text(form->field, text);
|
|
|
|
}
|
|
|
|
else if(type == POPPLER_FORM_FIELD_BUTTON)
|
|
|
|
{
|
|
|
|
if(argv[2][0] == '0')
|
|
|
|
poppler_form_field_button_set_state(form->field, FALSE);
|
|
|
|
else
|
|
|
|
poppler_form_field_button_set_state(form->field, TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
draw();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
void
|
|
|
|
cmd_goto(int argc, char** argv)
|
|
|
|
{
|
|
|
|
if(argc == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int page = atoi(argv[0]);;
|
2009-08-13 22:55:36 +02:00
|
|
|
set_page(page - 1);
|
|
|
|
|
|
|
|
Argument argument;
|
|
|
|
argument.n = TOP;
|
|
|
|
sc_scroll(&argument);
|
|
|
|
|
|
|
|
draw();
|
|
|
|
|
|
|
|
update_status();
|
2009-08-12 21:45:49 +02:00
|
|
|
}
|
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
void
|
|
|
|
cmd_info(int argc, char** argv)
|
|
|
|
{
|
|
|
|
if(!Zathura.PDF.document)
|
|
|
|
return;
|
|
|
|
|
|
|
|
gchar *info;
|
|
|
|
gchar *title, *author;
|
|
|
|
gchar *subject, *keywords;
|
|
|
|
gchar *creator, *producer;
|
|
|
|
GTime creation_date, modification_date;
|
|
|
|
|
|
|
|
g_object_get(Zathura.PDF.document,
|
|
|
|
"title", &title,
|
|
|
|
"author", &author,
|
|
|
|
"subject", &subject,
|
|
|
|
"keywords", &keywords,
|
|
|
|
"creator", &creator,
|
|
|
|
"producer", &producer,
|
|
|
|
"creation-date", &creation_date,
|
|
|
|
"mod-date", &modification_date,
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
info = g_strconcat(
|
|
|
|
"<b>Title:</b> ", title ? title : "", "\n",
|
|
|
|
"<b>Author:</b> ", author ? author : "", "\n",
|
|
|
|
"<b>Subject:</b> ", subject ? subject : "", "\n",
|
|
|
|
"<b>Keywords:</b> ", keywords ? keywords : "", "\n",
|
|
|
|
"<b>Creator:</b> ", creator ? creator : "", "\n",
|
|
|
|
"<b>Producer:</b> ", producer ? producer : "",
|
|
|
|
NULL);
|
|
|
|
|
|
|
|
notify(DEFAULT, info);
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_links(int argc, char** argv)
|
|
|
|
{
|
|
|
|
if(!Zathura.PDF.document && !Zathura.PDF.page)
|
|
|
|
return;
|
|
|
|
|
|
|
|
GList *link_list;
|
|
|
|
GList *links;
|
2009-09-19 10:43:41 +02:00
|
|
|
int number_of_links = 0;
|
2009-08-15 12:35:07 +02:00
|
|
|
|
|
|
|
link_list = poppler_page_get_link_mapping(Zathura.PDF.page);
|
|
|
|
|
|
|
|
for(links = link_list; links; links = g_list_next(links))
|
|
|
|
{
|
|
|
|
PopplerLinkMapping *link_mapping;
|
|
|
|
PopplerAction *action;
|
|
|
|
|
|
|
|
link_mapping = (PopplerLinkMapping*) links->data;
|
|
|
|
action = poppler_action_copy(link_mapping->action);
|
2009-09-19 10:43:41 +02:00
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
if(action->type == POPPLER_ACTION_URI)
|
|
|
|
{
|
|
|
|
char* link_name = poppler_page_get_text(Zathura.PDF.page, POPPLER_SELECTION_WORD, &link_mapping->area);
|
2009-09-19 10:43:41 +02:00
|
|
|
notify(DEFAULT, g_strdup_printf("<b><a href=\"%s\">%s</a>:</b> %s", action->uri.uri, link_name, action->uri.uri));
|
|
|
|
number_of_links++;
|
2009-08-15 12:35:07 +02:00
|
|
|
}
|
|
|
|
}
|
2009-09-19 10:43:41 +02:00
|
|
|
|
|
|
|
if(number_of_links > 0)
|
|
|
|
notify(DEFAULT, g_strdup_printf("%d links found", number_of_links));
|
|
|
|
else
|
|
|
|
notify(WARNING, "No links found");
|
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
|
|
|
|
poppler_page_free_link_mapping(link_list);
|
|
|
|
}
|
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
void
|
|
|
|
cmd_rotate(int argc, char** argv)
|
|
|
|
{
|
|
|
|
Argument argument;
|
|
|
|
|
|
|
|
if(argc == 0)
|
|
|
|
argument.n = RIGHT;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!strncmp(argv[0], "left", strlen(argv[0]) - 1))
|
|
|
|
argument.n = LEFT;
|
|
|
|
else
|
|
|
|
argument.n = RIGHT;
|
|
|
|
}
|
|
|
|
|
|
|
|
sc_rotate(&argument);
|
|
|
|
}
|
|
|
|
|
2009-09-10 23:46:40 +02:00
|
|
|
void
|
|
|
|
cmd_save(int argc, char** argv)
|
|
|
|
{
|
|
|
|
if(argc == 0 || !Zathura.PDF.document)
|
|
|
|
return;
|
|
|
|
|
|
|
|
poppler_document_save(Zathura.PDF.document, g_strdup_printf("file://%s", argv[0]), NULL);
|
|
|
|
}
|
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
void
|
|
|
|
cmd_zoom(int argc, char** argv)
|
|
|
|
{
|
|
|
|
if(argc == 0)
|
|
|
|
return;
|
2009-08-11 23:18:50 +02:00
|
|
|
|
2009-08-12 21:45:49 +02:00
|
|
|
int zoom = atoi(argv[0]);
|
|
|
|
if(zoom < 1 || zoom >= 1000)
|
|
|
|
return;
|
|
|
|
|
|
|
|
Zathura.PDF.scale = (float) zoom / 100;
|
|
|
|
draw();
|
2009-08-11 23:18:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cmd_quit(int argc, char** argv)
|
|
|
|
{
|
|
|
|
cb_destroy(NULL, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* callback implementations */
|
2009-08-12 21:45:49 +02:00
|
|
|
void
|
|
|
|
cb_draw(GtkWidget *widget, gpointer data)
|
|
|
|
{
|
|
|
|
gdk_window_clear(widget->window);
|
|
|
|
cairo_t *cairo = gdk_cairo_create(widget->window);
|
|
|
|
cairo_set_source_surface(cairo, Zathura.PDF.surface, 0, 0);
|
|
|
|
cairo_paint(cairo);
|
|
|
|
cairo_destroy(cairo);
|
|
|
|
}
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
void
|
|
|
|
cb_destroy(GtkWidget *widget, gpointer data)
|
|
|
|
{
|
2009-08-29 16:07:58 +02:00
|
|
|
pango_font_description_free(Zathura.Settings.font);
|
2009-08-11 23:18:50 +02:00
|
|
|
gtk_main_quit();
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
cb_view_key_pressed(GtkWidget *widget, GdkEventKey *event, gpointer data)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for(i = 0; i < LENGTH(shortcuts); i++)
|
|
|
|
{
|
2009-08-12 21:45:49 +02:00
|
|
|
if (event->keyval == shortcuts[i].key &&
|
|
|
|
(((event->state & shortcuts[i].mask) == shortcuts[i].mask) || shortcuts[i].mask == 0))
|
2009-08-11 23:18:50 +02:00
|
|
|
{
|
|
|
|
shortcuts[i].function(&(shortcuts[i].argument));
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cb_inputbar_activate(GtkEntry* entry, gpointer data)
|
|
|
|
{
|
|
|
|
gchar **tokens = g_strsplit(gtk_entry_get_text(entry), " ", gtk_entry_get_text_length(entry));
|
|
|
|
gchar *command = tokens[0] + 1;
|
|
|
|
int length = g_strv_length(tokens);
|
|
|
|
int i = 0;
|
|
|
|
gboolean success = FALSE;
|
|
|
|
Argument argument;
|
|
|
|
|
|
|
|
argument.n = HIDE;
|
|
|
|
complete(&argument);
|
|
|
|
|
|
|
|
if(length < 1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// special command
|
|
|
|
if(*tokens[0] == '/')
|
2009-08-12 21:45:49 +02:00
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
Argument argument;
|
|
|
|
argument.data = (char*) gtk_entry_get_text(entry) + 1;
|
|
|
|
sc_search(&argument);
|
2009-08-12 21:45:49 +02:00
|
|
|
g_strfreev(tokens);
|
2009-08-13 22:55:36 +02:00
|
|
|
update_status();
|
2009-08-12 21:45:49 +02:00
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(Zathura.view));
|
2009-08-11 23:18:50 +02:00
|
|
|
return;
|
2009-08-12 21:45:49 +02:00
|
|
|
}
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
// other
|
|
|
|
for(i = 0; i < LENGTH(commands); i++)
|
|
|
|
{
|
|
|
|
if(g_strcmp0(command, commands[i].command) == 0)
|
|
|
|
{
|
|
|
|
commands[i].function(length - 1, tokens + 1);
|
|
|
|
success = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!success)
|
2009-08-13 22:55:36 +02:00
|
|
|
notify(ERROR, g_strdup_printf("\"%s\" is not a valid command", command));
|
2009-08-11 23:18:50 +02:00
|
|
|
|
2009-09-19 15:53:35 +02:00
|
|
|
Zathura.history = g_list_append(Zathura.history, (char*) g_strdup(gtk_entry_get_text(entry)));
|
|
|
|
|
2009-08-13 22:55:36 +02:00
|
|
|
update_status();
|
2009-08-11 23:18:50 +02:00
|
|
|
g_strfreev(tokens);
|
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(Zathura.view));
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
cb_inputbar_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointer data)
|
|
|
|
{
|
|
|
|
if(event->type == GDK_BUTTON_PRESS)
|
|
|
|
{
|
|
|
|
gtk_widget_modify_text(GTK_WIDGET(Zathura.inputbar), GTK_STATE_NORMAL, &(Zathura.Settings.inputbar_fg));
|
|
|
|
gtk_widget_modify_base(GTK_WIDGET(Zathura.inputbar), GTK_STATE_NORMAL, &(Zathura.Settings.inputbar_bg));
|
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(Zathura.inputbar));
|
2009-08-13 22:55:36 +02:00
|
|
|
gtk_entry_set_text(Zathura.inputbar, "");
|
|
|
|
gtk_editable_set_position(GTK_EDITABLE(Zathura.inputbar), -1);
|
2009-08-11 23:18:50 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-08-15 12:35:07 +02:00
|
|
|
void
|
|
|
|
cb_drawing_area_button_pressed(GtkWidget* widget, GdkEventButton* event, gpointer data)
|
|
|
|
{
|
|
|
|
if(!Zathura.PDF.document && !Zathura.PDF.page)
|
|
|
|
return;
|
|
|
|
|
|
|
|
// left click
|
|
|
|
if(event->button == 1)
|
|
|
|
{
|
|
|
|
// check for links
|
|
|
|
GList *link_list = poppler_page_get_link_mapping(Zathura.PDF.page);
|
|
|
|
GList *links;
|
|
|
|
int number_of_links = g_list_length(link_list);
|
|
|
|
|
|
|
|
if(number_of_links <= 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for(links = link_list; links; links = g_list_next(links))
|
|
|
|
{
|
|
|
|
PopplerLinkMapping *link_mapping = (PopplerLinkMapping*) links->data;
|
|
|
|
PopplerAction *action = poppler_action_copy(link_mapping->action);
|
|
|
|
|
2009-09-19 10:43:41 +02:00
|
|
|
double page_width, page_height;
|
|
|
|
poppler_page_get_size(Zathura.PDF.page, &page_width, &page_height);
|
|
|
|
PopplerRectangle* link_rectangle = &link_mapping->area;
|
|
|
|
|
|
|
|
if(Zathura.PDF.rotate == 0 || Zathura.PDF.rotate == 180)
|
|
|
|
event->y = page_height - event->y;
|
|
|
|
else if(Zathura.PDF.rotate == 90 || Zathura.PDF.rotate == 270)
|
|
|
|
event->x = page_height - event->x;
|
2009-08-29 16:07:58 +02:00
|
|
|
|
2009-09-19 10:43:41 +02:00
|
|
|
link_rectangle = recalcRectangle(link_rectangle);
|
|
|
|
|
|
|
|
// check if click is in url area
|
|
|
|
if( (link_rectangle->x1 <= event->x)
|
|
|
|
&& (link_rectangle->x2 >= event->x)
|
|
|
|
&& (link_rectangle->y1 <= event->y)
|
|
|
|
&& (link_rectangle->y2 >= event->y))
|
|
|
|
{
|
|
|
|
if(action->type == POPPLER_ACTION_URI)
|
2009-08-15 12:35:07 +02:00
|
|
|
open_link(action->uri.uri);
|
2009-09-19 10:43:41 +02:00
|
|
|
else if(action->type == POPPLER_ACTION_GOTO_DEST)
|
|
|
|
{
|
|
|
|
PopplerDest* destination = action->goto_dest.dest;
|
|
|
|
|
|
|
|
if(destination->type == POPPLER_DEST_NAMED)
|
|
|
|
{
|
|
|
|
destination = poppler_document_find_dest(Zathura.PDF.document, destination->named_dest);
|
|
|
|
|
|
|
|
if(destination)
|
|
|
|
{
|
|
|
|
set_page(destination->page_num - 1);
|
|
|
|
draw();
|
|
|
|
update_status();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2009-08-15 12:35:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
poppler_page_free_link_mapping(link_list);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
cb_label_open_link(GtkLabel* label, gchar* link, gpointer data)
|
|
|
|
{
|
|
|
|
open_link(link);
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
gboolean
|
|
|
|
cb_inputbar_key_pressed(GtkEntry* entry, GdkEventKey *event, gpointer data)
|
|
|
|
{
|
|
|
|
Argument argument;
|
|
|
|
|
|
|
|
switch(event->keyval)
|
|
|
|
{
|
|
|
|
case GDK_Escape:
|
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(Zathura.view));
|
2009-08-15 12:35:07 +02:00
|
|
|
update_status();
|
2009-08-11 23:18:50 +02:00
|
|
|
argument.n = HIDE;
|
|
|
|
return complete(&argument);
|
|
|
|
case GDK_Tab:
|
|
|
|
argument.n = NEXT;
|
|
|
|
return complete(&argument);
|
|
|
|
case GDK_ISO_Left_Tab:
|
|
|
|
argument.n = PREVIOUS;
|
|
|
|
return complete(&argument);
|
2009-09-19 15:53:35 +02:00
|
|
|
case GDK_Up:
|
|
|
|
history(PREVIOUS);
|
|
|
|
return TRUE;
|
|
|
|
case GDK_Down:
|
|
|
|
history(NEXT);
|
|
|
|
return TRUE;
|
2009-08-11 23:18:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
gboolean
|
|
|
|
cb_inputbar_key_released(GtkEntry *entry, GdkEventKey *event, gpointer data)
|
|
|
|
{
|
2009-08-12 21:45:49 +02:00
|
|
|
int length = gtk_entry_get_text_length(entry);
|
2009-09-12 11:19:51 +02:00
|
|
|
|
|
|
|
#if INCREMENTAL_SEARCH
|
2009-08-12 21:45:49 +02:00
|
|
|
char* text = (char*) gtk_entry_get_text(entry);
|
2009-09-12 11:19:51 +02:00
|
|
|
#endif
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
Argument argument;
|
|
|
|
|
|
|
|
if(!length)
|
|
|
|
{
|
|
|
|
argument.n = HIDE;
|
|
|
|
complete(&argument);
|
|
|
|
}
|
2009-09-12 11:19:51 +02:00
|
|
|
|
|
|
|
#if INCREMENTAL_SEARCH
|
2009-08-12 21:45:49 +02:00
|
|
|
else if(length > 1 && text[0] == '/')
|
|
|
|
{
|
2009-08-13 22:55:36 +02:00
|
|
|
Argument argument;
|
|
|
|
argument.data = (char*) text + 1;
|
2009-09-19 10:43:41 +02:00
|
|
|
sc_search(&argument);
|
2009-08-12 21:45:49 +02:00
|
|
|
gtk_widget_grab_focus(GTK_WIDGET(Zathura.inputbar));
|
|
|
|
gtk_editable_set_position(GTK_EDITABLE(Zathura.inputbar), -1);
|
|
|
|
}
|
2009-09-12 11:19:51 +02:00
|
|
|
#endif
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* main function */
|
|
|
|
int
|
|
|
|
main(int argc, char* argv[])
|
|
|
|
{
|
|
|
|
gtk_init(&argc, &argv);
|
|
|
|
|
|
|
|
init();
|
2009-08-12 21:45:49 +02:00
|
|
|
|
|
|
|
if(argc >= 2)
|
|
|
|
cmd_open(2, &argv[1]);
|
2009-08-11 23:18:50 +02:00
|
|
|
|
|
|
|
gtk_widget_show_all(GTK_WIDGET(Zathura.window));
|
2009-09-19 10:43:41 +02:00
|
|
|
|
|
|
|
Argument arg;
|
|
|
|
arg.n = ADJUST_BESTFIT;
|
|
|
|
sc_adjust_window(&arg);
|
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
gtk_main();
|
2009-09-19 10:43:41 +02:00
|
|
|
|
2009-08-11 23:18:50 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|