zathura/zathura.c

747 lines
21 KiB
C
Raw Normal View History

/* See LICENSE file for license and copyright information */
2011-10-21 15:00:22 +02:00
#define _BSD_SOURCE
2011-10-23 20:18:44 +02:00
#define _XOPEN_SOURCE 700
2011-10-21 15:00:22 +02:00
2010-12-28 09:47:09 +01:00
#include <stdlib.h>
#include <unistd.h>
2012-02-08 21:34:53 +01:00
#include <math.h>
2010-12-28 09:47:09 +01:00
#include <girara/datastructures.h>
#include <girara/utils.h>
#include <girara/session.h>
#include <girara/statusbar.h>
#include <girara/settings.h>
2011-10-21 15:00:22 +02:00
#include <glib/gstdio.h>
2012-03-04 18:35:16 +01:00
#include <glib/gi18n.h>
2011-04-18 17:03:08 +02:00
2011-09-01 15:43:34 +02:00
#include "bookmarks.h"
2010-11-12 13:48:18 +01:00
#include "callbacks.h"
#include "config.h"
#ifdef WITH_SQLITE
#include "database-sqlite.h"
#endif
#include "database-plain.h"
#include "document.h"
2010-11-12 13:48:18 +01:00
#include "shortcuts.h"
2010-11-10 19:18:01 +01:00
#include "zathura.h"
2010-12-28 09:47:09 +01:00
#include "utils.h"
2011-04-18 18:19:41 +02:00
#include "render.h"
#include "page-widget.h"
2009-12-26 17:57:46 +01:00
2011-04-18 21:22:35 +02:00
typedef struct zathura_document_info_s
{
zathura_t* zathura;
const char* path;
const char* password;
} zathura_document_info_t;
static gboolean document_info_open(gpointer data);
static gboolean purge_pages(gpointer data);
2009-12-26 17:57:46 +01:00
2010-11-10 19:18:01 +01:00
/* function implementation */
2011-04-18 17:27:49 +02:00
zathura_t*
zathura_init(int argc, char* argv[])
2010-06-03 18:05:34 +02:00
{
2011-04-19 14:46:08 +02:00
/* parse command line options */
2012-02-14 13:53:26 +01:00
#if (GTK_MAJOR_VERSION == 2)
2011-04-19 14:46:08 +02:00
GdkNativeWindow embed = 0;
#else
Window embed = 0;
2012-02-14 13:53:26 +01:00
#endif
gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL;
bool forkback = false;
2011-09-29 15:23:13 +02:00
GOptionEntry entries[] =
2011-04-19 14:46:08 +02:00
{
2012-03-04 18:35:16 +01:00
{ "reparent", 'e', 0, G_OPTION_ARG_INT, &embed, _("Reparents to window specified by xid"), "xid" },
{ "config-dir", 'c', 0, G_OPTION_ARG_FILENAME, &config_dir, _("Path to the config directory"), "path" },
{ "data-dir", 'd', 0, G_OPTION_ARG_FILENAME, &data_dir, _("Path to the data directory"), "path" },
{ "plugins-dir", 'p', 0, G_OPTION_ARG_STRING, &plugin_path, _("Path to the directories containing plugins"), "path" },
{ "fork", '\0', 0, G_OPTION_ARG_NONE, &forkback, _("Fork into the background"), NULL },
2012-03-23 21:21:07 +01:00
{ "debug", 'l', 0, G_OPTION_ARG_STRING, &loglevel, _("Log level (debug, info, warning, error)"), "level" },
2011-09-21 00:46:03 +02:00
{ NULL, '\0', 0, 0, NULL, NULL, NULL }
2011-04-19 14:46:08 +02:00
};
GOptionContext* context = g_option_context_new(" [file] [password]");
g_option_context_add_main_entries(context, entries, NULL);
GError* error = NULL;
2012-02-12 16:35:33 +01:00
if (g_option_context_parse(context, &argc, &argv, &error) == false)
2011-04-19 14:46:08 +02:00
{
printf("Error parsing command line arguments: %s\n", error->message);
g_option_context_free(context);
g_error_free(error);
return NULL;
2011-04-19 14:46:08 +02:00
}
g_option_context_free(context);
/* Fork into the background if the user really wants to ... */
if (forkback == true)
{
int pid = fork();
if (pid > 0) { /* parent */
exit(0);
} else if (pid < 0) { /* error */
printf("Error: couldn't fork.");
}
setsid();
}
/* Set log level. */
if (loglevel == NULL || g_strcmp0(loglevel, "info") == 0) {
girara_set_debug_level(GIRARA_INFO);
} else if (g_strcmp0(loglevel, "warning") == 0) {
girara_set_debug_level(GIRARA_WARNING);
} else if (g_strcmp0(loglevel, "error") == 0) {
girara_set_debug_level(GIRARA_ERROR);
}
zathura_t* zathura = g_malloc0(sizeof(zathura_t));
/* plugins */
2011-10-30 11:46:30 +01:00
zathura->plugins.plugins = girara_list_new2(
2011-09-29 18:08:37 +02:00
(girara_free_function_t)zathura_document_plugin_free);
2011-10-30 11:46:30 +01:00
zathura->plugins.path = girara_list_new2(g_free);
zathura->plugins.type_plugin_mapping = girara_list_new2(
2011-09-29 18:08:37 +02:00
(girara_free_function_t)zathura_type_plugin_mapping_free);
2012-02-12 16:35:33 +01:00
if (config_dir != NULL) {
2011-04-19 14:46:08 +02:00
zathura->config.config_dir = g_strdup(config_dir);
} else {
gchar* path = girara_get_xdg_path(XDG_CONFIG);
zathura->config.config_dir = g_build_filename(path, "zathura", NULL);
g_free(path);
}
2012-02-12 16:35:33 +01:00
if (data_dir != NULL) {
2011-04-19 14:46:08 +02:00
zathura->config.data_dir = g_strdup(config_dir);
} else {
gchar* path = girara_get_xdg_path(XDG_DATA);
2011-04-20 16:58:08 +02:00
zathura->config.data_dir = g_build_filename(path, "zathura", NULL);
2011-04-19 14:46:08 +02:00
g_free(path);
}
/* create zathura (config/data) directory */
g_mkdir_with_parents(zathura->config.config_dir, 0771);
g_mkdir_with_parents(zathura->config.data_dir, 0771);
2012-02-12 16:35:33 +01:00
if (plugin_path != NULL) {
girara_list_t* paths = girara_split_path_array(plugin_path);
girara_list_merge(zathura->plugins.path, paths);
girara_list_free(paths);
2011-04-19 14:46:08 +02:00
} else {
#ifdef ZATHURA_PLUGINDIR
girara_list_t* paths = girara_split_path_array(ZATHURA_PLUGINDIR);
girara_list_merge(zathura->plugins.path, paths);
girara_list_free(paths);
#endif
2011-04-19 14:46:08 +02:00
}
/* UI */
2011-04-18 17:27:49 +02:00
if ((zathura->ui.session = girara_session_create()) == NULL) {
2010-12-26 01:52:17 +01:00
goto error_out;
2010-11-17 22:51:15 +01:00
}
2010-06-03 18:05:34 +02:00
2011-04-18 17:37:03 +02:00
zathura->ui.session->global.data = zathura;
2011-04-29 00:28:19 +02:00
2011-04-30 13:27:27 +02:00
/* global settings */
zathura->global.recolor = false;
zathura->global.update_page_number = true;
2011-04-30 13:27:27 +02:00
/* load plugins */
zathura_document_plugins_load(zathura);
/* configuration */
config_load_default(zathura);
2011-10-30 11:46:30 +01:00
/* load global configuration files */
2012-02-28 08:32:34 +01:00
char* config_path = girara_get_xdg_path(XDG_CONFIG_DIRS);
girara_list_t* config_dirs = girara_split_path_array(config_path);
2011-10-30 11:46:30 +01:00
ssize_t size = girara_list_size(config_dirs) - 1;
for (; size >= 0; --size) {
const char* dir = girara_list_nth(config_dirs, size);
char* file = g_build_filename(dir, ZATHURA_RC, NULL);
config_load_file(zathura, file);
g_free(file);
}
girara_list_free(config_dirs);
2012-02-28 08:32:34 +01:00
g_free(config_path);
2011-10-30 11:46:30 +01:00
config_load_file(zathura, GLOBAL_RC);
/* load local configuration files */
char* configuration_file = g_build_filename(zathura->config.config_dir, ZATHURA_RC, NULL);
config_load_file(zathura, configuration_file);
g_free(configuration_file);
/* initialize girara */
zathura->ui.session->gtk.embed = embed;
2012-02-14 13:53:26 +01:00
2011-12-13 19:59:59 +01:00
if (girara_session_init(zathura->ui.session, "zathura") == false) {
goto error_out;
}
/* girara events */
2012-02-08 15:19:51 +01:00
zathura->ui.session->events.buffer_changed = cb_buffer_changed;
2010-12-29 11:46:13 +01:00
/* page view */
2012-02-07 18:30:46 +01:00
zathura->ui.page_widget = gtk_table_new(0, 0, TRUE);
2012-02-12 16:35:33 +01:00
if (zathura->ui.page_widget == NULL) {
2010-12-29 11:46:13 +01:00
goto error_free;
}
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "size-allocate", G_CALLBACK(cb_view_resized), zathura);
2012-02-09 01:46:51 +01:00
2011-04-19 21:42:18 +02:00
/* callbacks */
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
g_signal_connect(G_OBJECT(view_vadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
g_signal_connect(G_OBJECT(view_hadjustment), "value-changed", G_CALLBACK(cb_view_vadjustment_value_changed), zathura);
2012-01-13 17:39:46 +01:00
/* page view alignment */
2012-02-07 18:30:46 +01:00
zathura->ui.page_widget_alignment = gtk_alignment_new(0.5, 0.5, 0, 0);
2012-02-12 16:35:33 +01:00
if (zathura->ui.page_widget_alignment == NULL) {
2012-01-13 17:39:46 +01:00
goto error_free;
}
2012-02-07 18:30:46 +01:00
gtk_container_add(GTK_CONTAINER(zathura->ui.page_widget_alignment), zathura->ui.page_widget);
2012-01-13 17:39:46 +01:00
2012-02-07 18:30:46 +01:00
gtk_widget_show(zathura->ui.page_widget);
2010-12-26 01:52:17 +01:00
/* statusbar */
2011-04-18 17:27:49 +02:00
zathura->ui.statusbar.file = girara_statusbar_item_add(zathura->ui.session, TRUE, TRUE, TRUE, NULL);
if (zathura->ui.statusbar.file == NULL) {
2010-12-26 01:52:17 +01:00
goto error_free;
2010-11-13 12:40:48 +01:00
}
2011-04-18 17:27:49 +02:00
zathura->ui.statusbar.buffer = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
if (zathura->ui.statusbar.buffer == NULL) {
2010-12-26 01:52:17 +01:00
goto error_free;
2010-11-18 21:22:43 +01:00
}
2011-04-18 17:27:49 +02:00
zathura->ui.statusbar.page_number = girara_statusbar_item_add(zathura->ui.session, FALSE, FALSE, FALSE, NULL);
2012-02-12 16:35:33 +01:00
if (zathura->ui.statusbar.page_number == NULL) {
2010-12-26 01:52:17 +01:00
goto error_free;
2010-11-18 21:22:43 +01:00
}
2012-03-16 15:59:23 +01:00
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, _("[No name]"));
2010-11-18 21:22:43 +01:00
2010-11-12 13:48:18 +01:00
/* signals */
2012-03-07 01:11:18 +01:00
g_signal_connect(G_OBJECT(zathura->ui.session->gtk.window), "destroy", G_CALLBACK(cb_destroy), zathura);
2010-12-29 11:46:13 +01:00
2012-03-16 15:47:30 +01:00
/* set page padding */
int page_padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
2011-04-19 19:24:03 +02:00
2012-03-16 15:47:30 +01:00
gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding);
gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), page_padding);
2011-04-19 21:42:18 +02:00
/* database */
char* database = NULL;
girara_setting_get(zathura->ui.session, "database", &database);
if (g_strcmp0(database, "plain") == 0) {
girara_info("Using plain database backend.");
zathura->database = zathura_plaindatabase_new(zathura->config.data_dir);
#ifdef WITH_SQLITE
} else if (g_strcmp0(database, "sqlite") == 0) {
girara_info("Using sqlite database backend.");
char* tmp = g_build_filename(zathura->config.data_dir, "bookmarks.sqlite", NULL);
zathura->database = zathura_sqldatabase_new(tmp);
g_free(tmp);
#endif
} else {
girara_error("Database backend '%s' is not supported.", database);
}
g_free(database);
if (zathura->database == NULL) {
2011-10-03 17:28:14 +02:00
girara_error("Unable to initialize database. Bookmarks won't be available.");
}
2011-09-01 15:43:34 +02:00
/* bookmarks */
2011-10-15 18:42:30 +02:00
zathura->bookmarks.bookmarks = girara_sorted_list_new2((girara_compare_function_t) zathura_bookmarks_compare,
2011-10-15 18:26:04 +02:00
(girara_free_function_t) zathura_bookmark_free);
2011-09-01 15:43:34 +02:00
2011-04-19 19:24:03 +02:00
/* open document if passed */
2011-04-18 21:22:35 +02:00
if (argc > 1) {
zathura_document_info_t* document_info = g_malloc0(sizeof(zathura_document_info_t));
2011-04-18 21:22:35 +02:00
document_info->zathura = zathura;
document_info->path = argv[1];
document_info->password = (argc >= 2) ? argv[2] : NULL;
gdk_threads_add_idle(document_info_open, document_info);
2011-04-18 21:22:35 +02:00
}
/* add even to purge old pages */
int interval = 30;
girara_setting_get(zathura->ui.session, "page-store-interval", &interval);
g_timeout_add_seconds(interval, purge_pages, zathura);
2011-04-18 17:27:49 +02:00
return zathura;
2010-12-26 01:52:17 +01:00
error_free:
2012-02-12 16:35:33 +01:00
if (zathura->ui.page_widget != NULL) {
2012-02-07 18:30:46 +01:00
g_object_unref(zathura->ui.page_widget);
2010-12-29 11:46:13 +01:00
}
2012-02-12 16:35:33 +01:00
if (zathura->ui.page_widget_alignment != NULL) {
2012-02-07 18:30:46 +01:00
g_object_unref(zathura->ui.page_widget_alignment);
2012-01-13 17:39:46 +01:00
}
2010-12-26 01:52:17 +01:00
error_out:
zathura_free(zathura);
2011-05-09 10:53:09 +02:00
2011-04-18 17:27:49 +02:00
return NULL;
}
void
zathura_free(zathura_t* zathura)
{
if (zathura == NULL) {
return;
}
2012-02-20 20:07:24 +01:00
document_close(zathura, false);
2011-04-18 17:27:49 +02:00
if (zathura->ui.session != NULL) {
girara_session_destroy(zathura->ui.session);
}
2011-10-21 15:00:22 +02:00
/* stdin support */
if (zathura->stdin_support.file != NULL) {
g_unlink(zathura->stdin_support.file);
g_free(zathura->stdin_support.file);
}
2011-09-01 15:43:34 +02:00
/* bookmarks */
girara_list_free(zathura->bookmarks.bookmarks);
/* database */
zathura_db_free(zathura->database);
2011-04-29 00:28:19 +02:00
/* free print settings */
2012-02-12 16:35:33 +01:00
if (zathura->print.settings != NULL) {
2011-09-21 09:46:54 +02:00
g_object_unref(zathura->print.settings);
}
if (zathura->print.page_setup != NULL) {
g_object_unref(zathura->print.page_setup);
}
2011-04-29 00:28:19 +02:00
2011-04-18 17:27:49 +02:00
/* free registered plugins */
2012-02-28 08:32:34 +01:00
girara_list_free(zathura->plugins.type_plugin_mapping);
2011-04-18 18:21:33 +02:00
girara_list_free(zathura->plugins.plugins);
girara_list_free(zathura->plugins.path);
/* free config variables */
g_free(zathura->config.config_dir);
g_free(zathura->config.data_dir);
2011-09-30 12:33:50 +02:00
g_free(zathura);
2010-06-03 18:05:34 +02:00
}
2011-10-21 15:00:22 +02:00
static gchar*
prepare_document_open_from_stdin(zathura_t* zathura)
{
g_return_val_if_fail(zathura, NULL);
GError* error = NULL;
gchar* file = NULL;
gint handle = g_file_open_tmp("zathura.stdin.XXXXXX", &file, &error);
if (handle == -1)
{
if (error != NULL) {
girara_error("Can not create temporary file: %s", error->message);
g_error_free(error);
}
2011-10-21 15:00:22 +02:00
return NULL;
}
// read from stdin and dump to temporary file
int stdinfno = fileno(stdin);
if (stdinfno == -1)
{
girara_error("Can not read from stdin.");
close(handle);
g_unlink(file);
g_free(file);
return NULL;
}
char buffer[BUFSIZ];
ssize_t count = 0;
while ((count = read(stdinfno, buffer, BUFSIZ)) > 0)
{
if (write(handle, buffer, count) != count)
{
girara_error("Can not write to temporary file: %s", file);
close(handle);
g_unlink(file);
g_free(file);
return NULL;
}
}
close(handle);
if (count != 0)
{
girara_error("Can not read from stdin.");
g_unlink(file);
g_free(file);
return NULL;
}
return file;
}
static gboolean
2011-04-18 21:22:35 +02:00
document_info_open(gpointer data)
{
zathura_document_info_t* document_info = data;
g_return_val_if_fail(document_info != NULL, FALSE);
if (document_info->zathura != NULL && document_info->path != NULL) {
2011-10-21 15:00:22 +02:00
char* file = NULL;
if (g_strcmp0(document_info->path, "-") == 0) {
file = prepare_document_open_from_stdin(document_info->zathura);
if (file == NULL) {
girara_notify(document_info->zathura->ui.session, GIRARA_ERROR,
"Could not read file from stdin and write it to a temporary file.");
2011-10-23 17:34:10 +02:00
} else {
document_info->zathura->stdin_support.file = g_strdup(file);
2011-10-21 15:00:22 +02:00
}
} else {
file = g_strdup(document_info->path);
}
if (file != NULL) {
document_open(document_info->zathura, file, document_info->password);
g_free(file);
}
2011-04-18 21:22:35 +02:00
}
g_free(document_info);
2011-04-18 21:22:35 +02:00
return FALSE;
2010-06-03 18:05:34 +02:00
}
2010-12-12 22:04:42 +01:00
bool
2011-04-18 17:27:49 +02:00
document_open(zathura_t* zathura, const char* path, const char* password)
2010-12-12 22:04:42 +01:00
{
2012-02-12 16:35:33 +01:00
if (path == NULL) {
2010-12-29 11:46:13 +01:00
goto error_out;
2010-12-12 22:04:42 +01:00
}
2011-04-18 18:19:41 +02:00
zathura_document_t* document = zathura_document_open(zathura, path, password);
2010-12-12 22:04:42 +01:00
2012-02-12 16:35:33 +01:00
if (document == NULL) {
2010-12-29 11:46:13 +01:00
goto error_out;
2010-12-12 22:04:42 +01:00
}
2012-02-20 20:07:24 +01:00
/* install file monitor */
gchar* file_uri = g_filename_to_uri(document->file_path, NULL, NULL);
if (file_uri == NULL) {
goto error_free;
}
if (zathura->file_monitor.file == NULL) {
zathura->file_monitor.file = g_file_new_for_uri(file_uri);
if (zathura->file_monitor.file == NULL) {
goto error_free;
}
2012-02-20 20:07:24 +01:00
}
if (zathura->file_monitor.monitor == NULL) {
zathura->file_monitor.monitor = g_file_monitor_file(zathura->file_monitor.file, G_FILE_MONITOR_NONE, NULL, NULL);
if (zathura->file_monitor.monitor == NULL) {
goto error_free;
}
g_signal_connect(G_OBJECT(zathura->file_monitor.monitor), "changed", G_CALLBACK(cb_file_monitor), zathura->ui.session);
2012-02-20 20:07:24 +01:00
}
if (zathura->file_monitor.file_path == NULL) {
zathura->file_monitor.file_path = g_strdup(document->file_path);
if (zathura->file_monitor.file_path == NULL) {
goto error_free;
}
2012-02-20 20:07:24 +01:00
}
if (document->password != NULL) {
g_free(zathura->file_monitor.password);
2012-02-20 20:07:24 +01:00
zathura->file_monitor.password = g_strdup(document->password);
if (zathura->file_monitor.password == NULL) {
goto error_free;
}
}
2011-04-18 17:27:49 +02:00
zathura->document = document;
2010-12-12 22:04:42 +01:00
2011-03-18 18:40:20 +01:00
/* view mode */
2012-02-03 22:15:29 +01:00
int pages_per_row = 1;
girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row);
2012-02-07 18:30:46 +01:00
page_widget_set_mode(zathura, pages_per_row);
2010-12-28 09:47:09 +01:00
2012-02-07 18:30:46 +01:00
girara_set_view(zathura->ui.session, zathura->ui.page_widget_alignment);
2010-12-28 09:47:09 +01:00
2011-01-24 12:43:39 +01:00
/* threads */
2011-04-18 18:23:34 +02:00
zathura->sync.render_thread = render_init(zathura);
2011-01-24 12:43:39 +01:00
2012-02-12 16:35:33 +01:00
if (zathura->sync.render_thread == NULL) {
2011-01-24 12:43:39 +01:00
goto error_free;
}
2011-04-19 21:42:18 +02:00
/* create blank pages */
2011-09-21 00:46:03 +02:00
for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) {
2011-04-19 21:42:18 +02:00
zathura_page_t* page = document->pages[page_id];
gtk_widget_realize(page->drawing_area);
2010-12-29 11:46:13 +01:00
}
2010-12-12 22:04:42 +01:00
2011-09-03 14:21:36 +02:00
/* bookmarks */
2012-02-17 00:43:01 +01:00
zathura_bookmarks_load(zathura, zathura->document->file_path);
2011-09-03 14:21:36 +02:00
page_set_delayed(zathura, document->current_page_number);
cb_view_vadjustment_value_changed(NULL, zathura);
2012-03-16 07:58:55 +01:00
/* update title */
girara_set_window_title(zathura->ui.session, document->file_path);
2012-02-20 20:07:24 +01:00
free(file_uri);
2010-12-12 22:04:42 +01:00
return true;
2010-12-29 11:46:13 +01:00
error_free:
2012-02-20 20:07:24 +01:00
if (file_uri != NULL) {
g_free(file_uri);
}
2010-12-29 11:46:13 +01:00
zathura_document_free(document);
error_out:
return false;
2010-12-12 22:04:42 +01:00
}
2011-09-01 11:51:49 +02:00
bool
document_save(zathura_t* zathura, const char* path, bool overwrite)
{
g_return_val_if_fail(zathura, false);
g_return_val_if_fail(zathura->document, false);
g_return_val_if_fail(path, false);
gchar* file_path = girara_fix_path(path);
2012-02-12 16:35:33 +01:00
if ((overwrite == false) && g_file_test(file_path, G_FILE_TEST_EXISTS))
2011-09-01 11:51:49 +02:00
{
girara_error("File already exists: %s. Use :write! to overwrite it.", file_path);
2011-10-21 15:00:22 +02:00
g_free(file_path);
2011-09-01 11:51:49 +02:00
return false;
}
zathura_plugin_error_t error = zathura_document_save_as(zathura->document, file_path);
2011-09-01 11:51:49 +02:00
g_free(file_path);
return (error == ZATHURA_PLUGIN_ERROR_OK) ? true : false;
2011-09-01 11:51:49 +02:00
}
static void
remove_page_from_table(GtkWidget* page, gpointer permanent)
{
2012-02-12 16:35:33 +01:00
if (permanent == false) {
g_object_ref(G_OBJECT(page));
}
gtk_container_remove(GTK_CONTAINER(gtk_widget_get_parent(page)), page);
}
2010-12-12 22:04:42 +01:00
bool
2012-02-20 20:07:24 +01:00
document_close(zathura_t* zathura, bool keep_monitor)
2010-12-12 22:04:42 +01:00
{
2012-02-20 20:07:24 +01:00
if (zathura == NULL || zathura->document == NULL) {
2010-12-12 22:04:42 +01:00
return false;
}
2012-02-20 20:07:24 +01:00
/* remove monitor */
if (keep_monitor == false) {
if (zathura->file_monitor.monitor != NULL) {
g_file_monitor_cancel(zathura->file_monitor.monitor);
g_object_unref(zathura->file_monitor.monitor);
zathura->file_monitor.monitor = NULL;
}
if (zathura->file_monitor.file != NULL) {
g_object_unref(zathura->file_monitor.file);
zathura->file_monitor.file = NULL;
}
if (zathura->file_monitor.file_path != NULL) {
g_free(zathura->file_monitor.file_path);
zathura->file_monitor.file_path = NULL;
}
if (zathura->file_monitor.password != NULL) {
g_free(zathura->file_monitor.password);
zathura->file_monitor.password = NULL;
}
}
2011-10-06 17:57:26 +02:00
/* store last seen page */
zathura_db_set_fileinfo(zathura->database, zathura->document->file_path,
zathura->document->current_page_number, zathura->document->page_offset,
zathura->document->scale, zathura->document->rotate);
2011-10-06 17:57:26 +02:00
render_free(zathura->sync.render_thread);
zathura->sync.render_thread = NULL;
2012-02-07 18:30:46 +01:00
gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer)1);
2011-01-24 12:43:39 +01:00
2011-04-18 17:27:49 +02:00
zathura_document_free(zathura->document);
zathura->document = NULL;
2012-02-07 18:30:46 +01:00
gtk_widget_hide(zathura->ui.page_widget);
statusbar_page_number_update(zathura);
if (zathura->ui.session != NULL && zathura->ui.statusbar.file != NULL) {
2012-03-16 13:42:15 +01:00
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, _("[No name]"));
}
2010-12-12 22:04:42 +01:00
2012-03-16 07:58:55 +01:00
/* update title */
girara_set_window_title(zathura->ui.session, "zathura");
2010-12-12 22:04:42 +01:00
return true;
}
2011-12-11 19:30:36 +01:00
typedef struct page_set_delayed_s
{
zathura_t* zathura;
unsigned int page;
} page_set_delayed_t;
static gboolean
2011-12-11 19:30:36 +01:00
page_set_delayed_impl(gpointer data)
{
page_set_delayed_t* p = data;
page_set(p->zathura, p->page);
g_free(p);
return FALSE;
}
bool
page_set_delayed(zathura_t* zathura, unsigned int page_id)
{
if (zathura == NULL || zathura->document == NULL || zathura->document->pages == NULL ||
page_id >= zathura->document->number_of_pages) {
return false;
}
page_set_delayed_t* p = g_malloc(sizeof(page_set_delayed_t));
p->zathura = zathura;
p->page = page_id;
gdk_threads_add_idle(page_set_delayed_impl, p);
return true;
}
2010-12-12 22:04:42 +01:00
bool
2011-04-18 17:27:49 +02:00
page_set(zathura_t* zathura, unsigned int page_id)
2010-12-12 22:04:42 +01:00
{
if (zathura == NULL || zathura->document == NULL || zathura->document->pages == NULL) {
2010-12-26 01:52:17 +01:00
goto error_out;
2010-12-12 22:04:42 +01:00
}
2011-04-18 17:27:49 +02:00
if (page_id >= zathura->document->number_of_pages) {
2010-12-26 01:52:17 +01:00
goto error_out;
2010-12-12 22:04:42 +01:00
}
/* render page */
2011-04-18 17:27:49 +02:00
zathura_page_t* page = zathura->document->pages[page_id];
2010-12-27 09:44:28 +01:00
2012-02-12 16:35:33 +01:00
if (page == NULL) {
goto error_out;
}
2012-02-20 12:40:25 +01:00
zathura->document->current_page_number = page_id;
zathura->global.update_page_number = false;
2012-02-20 12:40:25 +01:00
page_offset_t offset;
page_calculate_offset(page, &offset);
2011-04-27 20:32:57 +02:00
2011-04-18 17:27:49 +02:00
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
2011-04-27 20:32:57 +02:00
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
2012-02-08 21:34:53 +01:00
set_adjustment(view_hadjustment, offset.x);
set_adjustment(view_vadjustment, offset.y);
2012-02-21 22:12:44 +01:00
statusbar_page_number_update(zathura);
2010-12-12 22:04:42 +01:00
return true;
2010-12-26 01:52:17 +01:00
error_out:
return false;
2010-12-12 22:04:42 +01:00
}
void
statusbar_page_number_update(zathura_t* zathura)
{
if (zathura == NULL || zathura->ui.statusbar.page_number == NULL) {
return;
}
if (zathura->document != NULL) {
char* page_number_text = g_strdup_printf("[%d/%d]", zathura->document->current_page_number + 1, zathura->document->number_of_pages);
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.page_number, page_number_text);
g_free(page_number_text);
} else {
girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.page_number, "");
}
}
2011-03-18 18:40:20 +01:00
void
2012-02-07 18:30:46 +01:00
page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row)
2011-03-18 18:40:20 +01:00
{
2011-04-25 16:54:21 +02:00
/* show at least one page */
if (pages_per_row == 0) {
pages_per_row = 1;
}
if (zathura->document == NULL) {
return;
}
2012-02-07 18:30:46 +01:00
gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer)0);
2012-02-08 21:34:53 +01:00
gtk_table_resize(GTK_TABLE(zathura->ui.page_widget), ceil(zathura->document->number_of_pages / pages_per_row), pages_per_row);
2011-04-18 17:27:49 +02:00
for (unsigned int i = 0; i < zathura->document->number_of_pages; i++)
2011-03-18 18:40:20 +01:00
{
2011-04-19 20:41:16 +02:00
int x = i % pages_per_row;
int y = i / pages_per_row;
2012-02-07 18:30:46 +01:00
gtk_table_attach(GTK_TABLE(zathura->ui.page_widget), zathura->document->pages[i]->drawing_area, x, x + 1, y, y + 1, GTK_SHRINK, GTK_SHRINK, 0, 0);
2011-03-18 18:40:20 +01:00
}
2012-02-07 18:30:46 +01:00
gtk_widget_show_all(zathura->ui.page_widget);
2011-03-18 18:40:20 +01:00
}
static
gboolean purge_pages(gpointer data)
{
zathura_t* zathura = data;
if (zathura == NULL || zathura->document == NULL) {
return TRUE;
}
int threshold = 0;
girara_setting_get(zathura->ui.session, "page-store-threshold", &threshold);
if (threshold <= 0) {
return TRUE;
}
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) {
zathura_page_t* page = zathura->document->pages[page_id];
zathura_page_widget_purge_unused(ZATHURA_PAGE(page->drawing_area), threshold);
}
return TRUE;
}