Commit b533801e authored by Sebastian Ramacher's avatar Sebastian Ramacher

Imported Upstream version 0.1.0

parent 426159d4
zathura is written by:
Moritz Lipp <mlq@pwmt.org>
Sebastian Ramacher <s.ramacher@gmx.at>
Other contributors are (in alphabetical order):
Pavel Borzenkov <pavel.borzenkov@gmail.com>
Ivan Sichmann Freitas <ivansichfreitas@gmail.com>
int3 <jezreel@gmail.com>
karottenreibe <k@rottenrei.be>
Johannes Meng <j@jmeng.de>
# See LICENSE file for license and copyright information
# General information
PROJECT_NAME = zathura
OUTPUT_DIRECTORY = ./doc/
OUTPUT_LANGUAGE = English
TAB_SIZE = 2
EXTRACT_ALL = YES
OPTIMIZE_OUTPUT_FOR_C = YES
DOXYFILE_ENCODING = UTF-8
TYPEDEF_HIDES_STRUCT = YES
# Warning and progress messages
QUIET = YES
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
# Input files
INPUT =
EXCLUDE = ./tests
FILE_PATTERNS = *.h *.c
RECURSIVE = YES
# Output files
GENERATE_HTML = YES
GENERATE_LATEX = NO
GENERATE_RTF = NO
GENERATE_XML = NO
SOURCE_BROWSER = YES
Copyright (c) 2009-2011 pwmt.org Copyright (c) 2009-2012 pwmt.org
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages
......
# See LICENSE file for license and copyright information # See LICENSE file for license and copyright information
# zathura - user interface
include config.mk include config.mk
include common.mk include common.mk
PROJECT = zathura PROJECT = zathura
SOURCE = zathura.c SOURCE = $(shell find . -iname "*.c" -a ! -iname "database-*" ! -path "*tests*")
OBJECTS = ${SOURCE:.c=.o} HEADER = $(shell find . -iname "*.h")
DOBJECTS = ${SOURCE:.c=.do} OBJECTS = $(patsubst %.c, %.o, $(SOURCE))
DOBJECTS = $(patsubst %.c, %.do, $(SOURCE))
ifeq (${DATABASE}, sqlite)
INCS += $(SQLITE_INC)
LIBS += $(SQLITE_LIB)
SOURCE += database-sqlite.c
else
ifeq (${DATABASE}, plain)
SOURCE += database-plain.c
endif
endif
all: options ${PROJECT} all: options ${PROJECT}
options: options:
@echo ${PROJECT} build options: @echo ${PROJECT} build options:
@echo "CFLAGS = ${CFLAGS}" @echo "CFLAGS = ${CFLAGS}"
@echo "LDFLAGS = ${LDFLAGS}"
@echo "LIBS = ${LIBS}" @echo "LIBS = ${LIBS}"
@echo "DFLAGS = ${DFLAGS}" @echo "DFLAGS = ${DFLAGS}"
@echo "CC = ${CC}" @echo "CC = ${CC}"
%.o: %.c %.o: %.c
$(ECHO) CC $< $(ECHO) CC $<
$(QUIET)${CC} -c ${CFLAGS} -o $@ $< @mkdir -p .depend
$(QUIET)${CC} -c ${CPPFLAGS} ${CFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
%.do: %.c %.do: %.c
$(ECHO) CC $< $(ECHO) CC $<
$(QUIET)${CC} -c ${CFLAGS} ${DFLAGS} -o $@ $< @mkdir -p .depend
$(QUIET)${CC} -c ${CPPFLAGS} ${CFLAGS} ${DFLAGS} -o $@ $< -MMD -MF .depend/$@.dep
${OBJECTS}: config.h config.mk # force recompilation of database.o if DATABASE has changed
${DOBJECTS}: config.h config.mk database.o: database-${DATABASE}.o
config.h: config.def.h ${OBJECTS}: config.mk
@if [ -f $@ ] ; then \ ${DOBJECTS}: config.mk
echo "config.h exists, but config.def.h is newer. Please check your" \
"config.h or ${PROJECT} might fail to build." ; \
else \
cp $< $@ ; \
fi
${PROJECT}: ${OBJECTS} ${PROJECT}: ${OBJECTS}
$(ECHO) CC -o $@ $(ECHO) CC -o $@
...@@ -44,17 +50,23 @@ ${PROJECT}: ${OBJECTS} ...@@ -44,17 +50,23 @@ ${PROJECT}: ${OBJECTS}
clean: clean:
$(QUIET)rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \ $(QUIET)rm -rf ${PROJECT} ${OBJECTS} ${PROJECT}-${VERSION}.tar.gz \
${DOBJECTS} ${PROJECT}-debug ${DOBJECTS} ${PROJECT}-debug .depend ${PROJECT}.pc doc *gcda *gcno $(PROJECT).info gcov
$(QUIET)make -C tests clean
distclean: clean
$(QUIET)rm -rf config.h
${PROJECT}-debug: ${DOBJECTS} ${PROJECT}-debug: ${DOBJECTS}
$(ECHO) CC -o ${PROJECT}-debug $(ECHO) CC -o $@
$(QUIET)${CC} ${LDFLAGS} -o ${PROJECT}-debug ${DOBJECTS} ${LIBS} $(QUIET)${CC} ${LDFLAGS} -o $@ ${DOBJECTS} ${LIBS}
debug: ${PROJECT}-debug debug: ${PROJECT}-debug
${PROJECT}.pc: ${PROJECT}.pc.in config.mk
$(QUIET)echo project=${PROJECT} > ${PROJECT}.pc
$(QUIET)echo version=${VERSION} >> ${PROJECT}.pc
$(QUIET)echo includedir=${PREFIX}/include >> ${PROJECT}.pc
$(QUIET)echo plugindir=${PLUGINDIR} >> ${PROJECT}.pc
$(QUIET)echo GTK_VERSION=${ZATHURA_GTK_VERSION} >> ${PROJECT}.pc
$(QUIET)cat ${PROJECT}.pc.in >> ${PROJECT}.pc
valgrind: debug valgrind: debug
valgrind --tool=memcheck --leak-check=yes --show-reachable=yes \ valgrind --tool=memcheck --leak-check=yes --show-reachable=yes \
./${PROJECT}-debug ./${PROJECT}-debug
...@@ -62,36 +74,72 @@ valgrind: debug ...@@ -62,36 +74,72 @@ valgrind: debug
gdb: debug gdb: debug
cgdb ${PROJECT}-debug cgdb ${PROJECT}-debug
test: ${OBJECTS}
$(QUIET)make -C tests run
dist: clean dist: clean
$(QUIET)mkdir -p ${PROJECT}-${VERSION} $(QUIET)mkdir -p ${PROJECT}-${VERSION}
$(QUIET)cp -R LICENSE Makefile config.mk common.mk config.def.h README \ $(QUIET)mkdir -p ${PROJECT}-${VERSION}/tests
${PROJECT}.desktop ${PROJECT}rc.5.rst \ $(QUIET)cp LICENSE Makefile config.mk common.mk README AUTHORS Doxyfile \
${PROJECT}.1 ${SOURCE} ${PROJECT}-${VERSION} ${PROJECT}.1.rst ${PROJECT}rc.5.rst ${SOURCE} ${HEADER} ${PROJECT}.pc.in \
${PROJECT}.desktop \
${PROJECT}-${VERSION}
$(QUIET)cp tests/Makefile tests/config.mk tests/*.c \
${PROJECT}-${VERSION}/tests
$(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION} $(QUIET)tar -cf ${PROJECT}-${VERSION}.tar ${PROJECT}-${VERSION}
$(QUIET)gzip ${PROJECT}-${VERSION}.tar $(QUIET)gzip ${PROJECT}-${VERSION}.tar
$(QUIET)rm -rf ${PROJECT}-${VERSION} $(QUIET)rm -rf ${PROJECT}-${VERSION}
install: all doc:
$(QUIET)doxygen Doxyfile
gcov: clean
$(QUIET)CFLAGS="${CFLAGS}-fprofile-arcs -ftest-coverage" LDFLAGS="${LDFLAGS} -fprofile-arcs" ${MAKE} $(PROJECT)
$(QUIET)${MAKE} -C tests
$(QUIET)lcov --directory . --capture --output-file $(PROJECT).info
$(QUIET)genhtml --output-directory gcov $(PROJECT).info
install: all ${PROJECT}.pc
$(ECHO) installing executable file $(ECHO) installing executable file
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/bin $(QUIET)mkdir -p ${DESTDIR}${PREFIX}/bin
$(QUIET)install -m 755 ${PROJECT} ${DESTDIR}${PREFIX}/bin $(QUIET)install -m 755 ${PROJECT} ${DESTDIR}${PREFIX}/bin
$(ECHO) installing manual page $(ECHO) installing header files
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/include/${PROJECT}
$(QUIET)cp -f document.h ${DESTDIR}${PREFIX}/include/${PROJECT}
$(QUIET)cp -f zathura.h ${DESTDIR}${PREFIX}/include/${PROJECT}
$(ECHO) installing manual pages
$(QUIET)mkdir -p ${DESTDIR}${MANPREFIX}/man1 $(QUIET)mkdir -p ${DESTDIR}${MANPREFIX}/man1
$(QUIET)sed "s/VERSION/${VERSION}/g" < ${PROJECT}.1 > ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
$(QUIET)if which rst2man > /dev/null ; then \ $(QUIET)if which rst2man > /dev/null ; then \
mkdir -p ${DESTDIR}${MANPREFIX}/man1 ; \
sed "s/VERSION/${VERSION}/g" < ${PROJECT}.1.rst > ${PROJECT}-v.1.rst ; \
rst2man ${PROJECT}-v.1.rst > ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1 ; \
rm -f ${PROJECT}-v.1.rst ; \
mkdir -p ${DESTDIR}${MANPREFIX}/man5 ; \ mkdir -p ${DESTDIR}${MANPREFIX}/man5 ; \
rst2man ${PROJECT}rc.5.rst > ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5 ; \ sed "s/VERSION/${VERSION}/g" < ${PROJECT}rc.5.rst > ${PROJECT}rc-v.5.rst ; \
rst2man ${PROJECT}rc-v.5.rst > ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5 ; \
rm -f ${PROJECT}rc-v.5.rst ; \
fi fi
$(QUIET)chmod 644 ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
$(QUIET)mkdir -p ${DESTDIR}${DESKTOPPREFIX} $(QUIET)mkdir -p ${DESTDIR}${DESKTOPPREFIX}
$(ECHO) installing desktop file $(ECHO) installing desktop file
$(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX} $(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX}
$(QUIET)chmod 644 ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
$(ECHO) installing pkgconfig file
$(QUIET)mkdir -p ${DESTDIR}${PREFIX}/lib/pkgconfig
$(QUIET)cp -f ${PROJECT}.pc ${DESTDIR}${PREFIX}/lib/pkgconfig
uninstall: uninstall:
$(ECHO) removing executable file $(ECHO) removing executable file
$(QUIET)rm -f ${DESTDIR}${PREFIX}/bin/${PROJECT} $(QUIET)rm -f ${DESTDIR}${PREFIX}/bin/${PROJECT}
$(ECHO) removing manual page $(ECHO) removing header files
$(QUIET)rm -rf ${DESTDIR}${PREFIX}/include/${PROJECT}
$(ECHO) removing manual pages
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1 $(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man1/${PROJECT}.1
$(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5 $(QUIET)rm -f ${DESTDIR}${MANPREFIX}/man5/${PROJECT}rc.5
$(ECHO) removing desktop file $(ECHO) removing desktop file
$(QUIET)rm -f ${DESTDIR}${DESKTOPPREFIX}/${PROJECT}.desktop $(QUIET)rm -f ${DESTDIR}${DESKTOPPREFIX}/${PROJECT}.desktop
$(ECHO) removing pkgconfig file
$(QUIET)rm -f ${DESTDIR}${PREFIX}/lib/pkgconfig/${PROJECT}.pc
-include $(wildcard .depend/*.dep)
.PHONY: all options clean doc debug valgrind gdb dist doc install uninstall test
zathura - pdf viewer zathura - a document viewer
-------------------- --------------------
zathura is a pdf viewer based on the poppler pdf rendering library zathura is a highly customizable and functional document viewer based on the
girara user interface library and several document libraries.
Requirements Requirements
------------ ------------
poppler-glib (>= 0.12.3)
cairo (>= 1.8.8)
gtk2 (>= 2.18.6) gtk2 (>= 2.18.6)
glib2 (>= 2.22.4) girara
sqlite3
check (for tests)
Please note that you need to have a working pkg-config installation Please note that you need to have a working pkg-config installation and that the
and that the Makefile is only compatible with GNU make. Makefile is only compatible with GNU make. If you don't have a working
pkg-config installation please set the GTK_INC, GTK_LIB, GIRARA_INC, GIRARA_LIB,
SQLITE_INC and SQLITE_LIB variables accordingly.
And also note that rst2man from python-docutils is needed to build And also note that rst2man from python-docutils is needed to build zathurarc.5.
zathurarc.5. If it is not installed, zathurarc.5 won't be built. If it is not installed, zathurarc.5 won't be built.
Configuration
-------------
You can modify some parts of zathura by editing the config.h file
Installation Installation
------------ ------------
Customise config.h according to your wishes and run the following To build and install zathura:
command to build and install zathura:
make install make install
...@@ -31,9 +29,3 @@ Uninstall: ...@@ -31,9 +29,3 @@ Uninstall:
To delete zathura from your system, just type: To delete zathura from your system, just type:
make uninstall make uninstall
Use zathura
-----------
Just run:
zathura <file>
/* See LICENSE file for license and copyright information */
#include <string.h>
#include "bookmarks.h"
#include "database.h"
#include "document.h"
#include <girara/datastructures.h>
#include <girara/utils.h>
static int
bookmark_compare_find(const void* item, const void* data)
{
const zathura_bookmark_t* bookmark = item;
const char* id = data;
return g_strcmp0(bookmark->id, id);
}
zathura_bookmark_t*
zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page)
{
g_return_val_if_fail(zathura && zathura->document && zathura->bookmarks.bookmarks, NULL);
g_return_val_if_fail(id, NULL);
zathura_bookmark_t* old = girara_list_find(zathura->bookmarks.bookmarks, bookmark_compare_find, id);
if (old != NULL) {
return NULL;
}
zathura_bookmark_t* bookmark = g_malloc0(sizeof(zathura_bookmark_t));
bookmark->id = g_strdup(id);
bookmark->page = page;
girara_list_append(zathura->bookmarks.bookmarks, bookmark);
if (zathura->database != NULL) {
if (zathura_db_add_bookmark(zathura->database, zathura->document->file_path, bookmark) == false) {
girara_warning("Failed to add bookmark to database.");
}
}
return bookmark;
}
bool
zathura_bookmark_remove(zathura_t* zathura, const gchar* id)
{
g_return_val_if_fail(zathura && zathura->document && zathura->bookmarks.bookmarks, false);
g_return_val_if_fail(id, false);
zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, id);
if (bookmark == NULL) {
return false;
}
if (zathura->database != NULL) {
if (zathura_db_remove_bookmark(zathura->database, zathura->document->file_path, bookmark->id) == false) {
girara_warning("Failed to remove bookmark from database.");
}
}
girara_list_remove(zathura->bookmarks.bookmarks, bookmark);
return true;
}
zathura_bookmark_t*
zathura_bookmark_get(zathura_t* zathura, const gchar* id)
{
g_return_val_if_fail(zathura && zathura->bookmarks.bookmarks, NULL);
g_return_val_if_fail(id, NULL);
return girara_list_find(zathura->bookmarks.bookmarks, bookmark_compare_find, id);
}
void
zathura_bookmark_free(zathura_bookmark_t* bookmark)
{
if (bookmark == NULL) {
return;
}
g_free(bookmark->id);
g_free(bookmark);
}
bool
zathura_bookmarks_load(zathura_t* zathura, const gchar* file) {
g_return_val_if_fail(zathura, false);
g_return_val_if_fail(file, false);
if (zathura->database == NULL) {
return false;
}
girara_list_t* bookmarks = zathura_db_load_bookmarks(zathura->database, file);
if (bookmarks == NULL) {
return false;
}
girara_list_free(zathura->bookmarks.bookmarks);
zathura->bookmarks.bookmarks = bookmarks;
return true;
}
int
zathura_bookmarks_compare(zathura_bookmark_t* lhs, zathura_bookmark_t* rhs)
{
if (lhs == NULL && rhs == NULL) {
return 0;
}
if (lhs == NULL) {
return -1;
}
if (rhs == NULL) {
return 1;
}
return g_strcmp0(lhs->id, rhs->id);
}
/* See LICENSE file for license and copyright information */
#ifndef BOOKMARKS_H
#define BOOKMARKS_H
#include <stdbool.h>
#include "zathura.h"
struct zathura_bookmark_s
{
gchar* id;
unsigned int page;
};
typedef struct zathura_bookmark_s zathura_bookmark_t;
/**
* Create a bookmark and add it to the list of bookmarks.
* @param zathura The zathura instance.
* @param id The bookmark's id.
* @param page The bookmark's page.
* @return the bookmark instance or NULL on failure.
*/
zathura_bookmark_t* zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int page);
/**
* Remove a bookmark from the list of bookmarks.
* @param zathura The zathura instance.
* @param id The bookmark's id.
* @return true on success, false otherwise
*/
bool zathura_bookmark_remove(zathura_t* zathura, const gchar* id);
/**
* Get bookmark from the list of bookmarks.
* @param zathura The zathura instance.
* @param id The bookmark's id.
* @return The bookmark instance if it exists or NULL otherwise.
*/
zathura_bookmark_t* zathura_bookmark_get(zathura_t* zathura, const gchar* id);
/**
* Free a bookmark instance.
* @param bookmark The bookmark instance.
*/
void zathura_bookmark_free(zathura_bookmark_t* bookmark);
/**
* Load bookmarks for a specific file.
* @param zathura The zathura instance.
* @param file The file.
* @return true on success, false otherwise
*/
bool zathura_bookmarks_load(zathura_t* zathura, const gchar* file);
/**
* Compare two bookmarks.
* @param lhs a bookmark
* @param rhs a bookmark
* @returns g_strcmp0(lhs->id, rhs->id)
*/
int zathura_bookmarks_compare(zathura_bookmark_t* lhs, zathura_bookmark_t* rhs);
#endif // BOOKMARKS_H
/* See LICENSE file for license and copyright information */
#include <girara/statusbar.h>
#include <girara/session.h>
#include <girara/settings.h>
#include <girara/utils.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <string.h>
#include "callbacks.h"
#include "zathura.h"
#include "render.h"
#include "document.h"
#include "utils.h"
#include "shortcuts.h"
#include "page_widget.h"
gboolean
cb_destroy(GtkWidget* UNUSED(widget), gpointer UNUSED(data))
{
gtk_main_quit();
return TRUE;
}
void
cb_buffer_changed(girara_session_t* session)
{
g_return_if_fail(session != NULL);
g_return_if_fail(session->global.data != NULL);
zathura_t* zathura = session->global.data;
char* buffer = girara_buffer_get(session);
if (buffer) {
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, buffer);
free(buffer);
} else {
girara_statusbar_item_set_text(session, zathura->ui.statusbar.buffer, "");
}
}
void
cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data)
{
zathura_t* zathura = data;
if (!zathura || !zathura->document || !zathura->document->pages || !zathura->ui.page_widget) {
return;
}
GtkAdjustment* view_vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
GtkAdjustment* view_hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view));
GdkRectangle view_rect;
/* get current adjustment values */
view_rect.y = gtk_adjustment_get_value(view_vadjustment);
view_rect.height = gtk_adjustment_get_page_size(view_vadjustment);
view_rect.x = gtk_adjustment_get_value(view_hadjustment);
view_rect.width = gtk_adjustment_get_page_size(view_hadjustment);
int page_padding = 1;
girara_setting_get(zathura->ui.session, "page-padding", &page_padding);
GdkRectangle center;
center.x = view_rect.x + (view_rect.width + 1) / 2;
center.y = view_rect.y + (view_rect.height + 1) / 2;
center.height = center.width = 2*page_padding + 1;
bool updated = false;
/* find page that fits */
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++)
{
zathura_page_t* page = zathura->document->pages[page_id];
page_offset_t offset;
page_calculate_offset(page, &offset);
GdkRectangle page_rect;
page_rect.x = offset.x;
page_rect.y = offset.y;
page_rect.width = page->width * zathura->document->scale;
page_rect.height = page->height * zathura->document->scale;
if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) {
page->visible = true;
if (zathura->global.update_page_number == true && updated == false
&& gdk_rectangle_intersect(&center, &page_rect, NULL) == TRUE) {
zathura->document->current_page_number = page_id;
updated = true;
}
} else {
page->visible = false;
}
}
statusbar_page_number_update(zathura);
}
void
cb_pages_per_row_value_changed(girara_session_t* session, const char* UNUSED(name), girara_setting_type_t UNUSED(type), void* value, void* UNUSED(data))
{
g_return_if_fail(value != NULL);
g_return_if_fail(session != NULL);
g_return_if_fail(session->global.data != NULL);
zathura_t* zathura = session->global.data;
int pages_per_row = *(int*) value;
if (pages_per_row < 1) {
pages_per_row = 1;
}
page_widget_set_mode(zathura, pages_per_row);
if (zathura->document != NULL) {
unsigned int current_page = zathura->document->current_page_number;
page_set_delayed(zathura, current_page);
}
}
void
cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
GtkTreeViewColumn* UNUSED(column), void* data)
{
zathura_t* zathura = data;
if (tree_view == NULL || zathura == NULL || zathura->ui.session == NULL) {
return;
}
GtkTreeModel *model;
GtkTreeIter iter;
g_object_get(tree_view, "model", &model, NULL);
if(gtk_tree_model_get_iter(model, &iter, path))
{
zathura_index_element_t* index_element;
gtk_tree_model_get(model, &iter, 2, &index_element, -1);
if (index_element == NULL) {
return;
}
if (index_element->type == ZATHURA_LINK_TO_PAGE) {
sc_toggle_index(zathura->ui.session, NULL, NULL, 0);
page_set_delayed(zathura, index_element->target.page_number);
} else if (index_element->type == ZATHURA_LINK_EXTERNAL) {
if (girara_xdg_open(index_element->target.uri) == false) {
girara_notify(zathura->ui.session, GIRARA_ERROR, "Failed to run xdg-open.");
}
}
}
g_object_unref(model);
}
bool
cb_sc_follow(GtkEntry* entry, girara_session_t* session)
{
g_return_val_if_fail(session != NULL, FALSE);
g_return_val_if_fail(session->global.data != NULL, FALSE);
zathura_t* zathura = session->global.data;
bool eval = true;
char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
if (input == NULL || strlen(input) == 0) {
eval = false;
}
int index = 0;
if (eval == true) {
index = atoi(input);
if (index == 0 && g_strcmp0(input, "0") != 0) {
girara_notify(session, GIRARA_WARNING, "Invalid input '%s' given.", input);
eval = false;
}
index = index - 1;
}
/* set pages to draw links */
bool invalid_index = 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];
if (page == NULL || page->visible == false) {
continue;
}
g_object_set(page->drawing_area, "draw-links", FALSE, NULL);
if (eval == true) {
zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page->drawing_area), index);
if (link != NULL) {
switch (link->type) {
case ZATHURA_LINK_TO_PAGE:
page_set_delayed(zathura, link->target.page_number);
break;
case ZATHURA_LINK_EXTERNAL:
girara_xdg_open(link->target.value);
break;
}
invalid_index = false;
}
}
}
if (eval == true && invalid_index == true) {
girara_notify(session, GIRARA_WARNING, "Invalid index '%s' given.", input);
}
g_free(input);
return (eval == TRUE) ? TRUE : FALSE;
}
void
cb_file_monitor(GFileMonitor* monitor, GFile* file, GFile* UNUSED(other_file), GFileMonitorEvent event, girara_session_t* session)
{
g_return_if_fail(monitor != NULL);
g_return_if_fail(file != NULL);
g_return_if_fail(session != NULL);