diff --git a/AUTHORS b/AUTHORS index ddd62a4..d555e63 100644 --- a/AUTHORS +++ b/AUTHORS @@ -8,6 +8,7 @@ Other contributors are (in alphabetical order): Aepelzen Pavel Borzenkov Géraud Le Falher +Glen Winters Ivan Sichmann Freitas Felix Herrmann int3 diff --git a/Makefile b/Makefile index 9473556..aa0fc6a 100644 --- a/Makefile +++ b/Makefile @@ -6,7 +6,7 @@ include common.mk PROJECT = zathura OSOURCE = $(wildcard *.c) HEADER = $(wildcard *.h) -HEADERINST = version.h zathura.h document.h macros.h +HEADERINST = version.h document.h macros.h page.h types.h plugin-api.h links.h ifneq (${WITH_SQLITE},0) INCS += $(SQLITE_INC) @@ -21,6 +21,16 @@ ifneq ($(wildcard ${VALGRIND_SUPPRESSION_FILE}),) VALGRIND_ARGUMENTS += --suppressions=${VALGRIND_SUPPRESSION_FILE} endif +ifeq (,$(findstring -DZATHURA_PLUGINDIR,${CPPFLAGS})) +CPPFLAGS += -DZATHURA_PLUGINDIR=\"${PLUGINDIR}\" +endif +ifeq (,$(findstring -DGETTEXT_PACKAGE,${CPPFLAGS})) +CPPFLAGS += -DGETTEXT_PACKAGE=\"${PROJECT}\" +endif +ifeq (,$(findstring -DLOCALEDIR,${CPPFLAGS})) +CPPFLAGS += -DLOCALEDIR=\"${LOCALEDIR}\" +endif + OBJECTS = $(patsubst %.c, %.o, $(SOURCE)) DOBJECTS = $(patsubst %.c, %.do, $(SOURCE)) @@ -144,7 +154,7 @@ endif install-manpages: build-manpages $(ECHO) installing manual pages - $(QUIET)mkdir -p ${DESTDIR}${MANPREFIX}/man1 ${DESTDIR}${MANPREFIX}/man5 + $(QUIET)mkdir -m 755 -p ${DESTDIR}${MANPREFIX}/man1 ${DESTDIR}${MANPREFIX}/man5 ifneq "$(wildcard ${PROJECT}.1)" "" $(QUIET)install -m 644 ${PROJECT}.1 ${DESTDIR}${MANPREFIX}/man1 endif @@ -154,17 +164,17 @@ endif install-headers: ${PROJECT}.pc $(ECHO) installing header files - $(QUIET)mkdir -p ${DESTDIR}${INCLUDEDIR}/${PROJECT} + $(QUIET)mkdir -m 755 -p ${DESTDIR}${INCLUDEDIR}/${PROJECT} $(QUIET)install -m 644 ${HEADERINST} ${DESTDIR}${INCLUDEDIR}/${PROJECT} $(ECHO) installing pkgconfig file - $(QUIET)mkdir -p ${DESTDIR}${LIBDIR}/pkgconfig + $(QUIET)mkdir -m 755 -p ${DESTDIR}${LIBDIR}/pkgconfig $(QUIET)install -m 644 ${PROJECT}.pc ${DESTDIR}${LIBDIR}/pkgconfig install: all install-headers install-manpages $(ECHO) installing executable file - $(QUIET)mkdir -p ${DESTDIR}${PREFIX}/bin + $(QUIET)mkdir -m 755 -p ${DESTDIR}${PREFIX}/bin $(QUIET)install -m 755 ${PROJECT} ${DESTDIR}${PREFIX}/bin - $(QUIET)mkdir -p ${DESTDIR}${DESKTOPPREFIX} + $(QUIET)mkdir -m 755 -p ${DESTDIR}${DESKTOPPREFIX} $(ECHO) installing desktop file $(QUIET)install -m 644 ${PROJECT}.desktop ${DESTDIR}${DESKTOPPREFIX} $(MAKE) -C po install @@ -175,7 +185,7 @@ uninstall-headers: $(ECHO) removing pkgconfig file $(QUIET)rm -f ${DESTDIR}${LIBDIR}/pkgconfig/${PROJECT}.pc -uninstall: +uninstall: uninstall-headers $(ECHO) removing executable file $(QUIET)rm -f ${DESTDIR}${PREFIX}/bin/${PROJECT} $(ECHO) removing manual pages diff --git a/README b/README index 5fd88a0..e9c441a 100644 --- a/README +++ b/README @@ -7,7 +7,7 @@ Requirements ------------ gtk2 (>= 2.18.6) girara -sqlite3 +sqlite3 (>= 3.5.9) check (for tests) intltool @@ -20,7 +20,9 @@ And also note that rst2man from python-docutils is needed to build the man pages If it is not installed, the man pages won't be built. If you don't want to build with support for sqlite databases, you can set -WITH_SQLITE=0 and sqlite support won't be available. +WITH_SQLITE=0 and sqlite support won't be available. Please note that sqlite3 +with metadata support is required, i.e. sqlite3 has to be built with +SQLITE_ENABLE_COLUMN_METADATA defined. Installation ------------ diff --git a/bookmarks.c b/bookmarks.c index 5fc94d5..78081e2 100644 --- a/bookmarks.c +++ b/bookmarks.c @@ -34,7 +34,8 @@ zathura_bookmark_add(zathura_t* zathura, const gchar* id, unsigned int 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) { + const char* path = zathura_document_get_path(zathura->document); + if (zathura_db_add_bookmark(zathura->database, path, bookmark) == false) { girara_warning("Failed to add bookmark to database."); } } @@ -54,7 +55,8 @@ zathura_bookmark_remove(zathura_t* zathura, const gchar* id) } if (zathura->database != NULL) { - if (zathura_db_remove_bookmark(zathura->database, zathura->document->file_path, bookmark->id) == false) { + const char* path = zathura_document_get_path(zathura->document); + if (zathura_db_remove_bookmark(zathura->database, path, bookmark->id) == false) { girara_warning("Failed to remove bookmark from database."); } } diff --git a/callbacks.c b/callbacks.c index b54de6c..81a1183 100644 --- a/callbacks.c +++ b/callbacks.c @@ -10,19 +10,20 @@ #include #include "callbacks.h" +#include "links.h" #include "zathura.h" #include "render.h" #include "document.h" #include "utils.h" #include "shortcuts.h" #include "page-widget.h" +#include "page.h" gboolean cb_destroy(GtkWidget* UNUSED(widget), zathura_t* zathura) { if (zathura != NULL && zathura->document != NULL) { - zathura_document_free(zathura->document); - zathura->document = NULL; + document_close(zathura, false); } gtk_main_quit(); @@ -50,8 +51,7 @@ void cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpointer data) { zathura_t* zathura = data; - if (zathura == NULL || zathura->document == NULL || zathura->document->pages == NULL - || zathura->ui.page_widget == NULL) { + if (zathura == NULL || zathura->document == NULL || zathura->ui.page_widget == NULL) { return; } @@ -73,28 +73,32 @@ cb_view_vadjustment_value_changed(GtkAdjustment* GIRARA_UNUSED(adjustment), gpoi center.y = (view_rect.height + 1) / 2; center.height = center.width = (2 * page_padding) + 1; + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + double scale = zathura_document_get_scale(zathura->document); + 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]; + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); GdkRectangle page_rect; - gtk_widget_translate_coordinates(page->drawing_area, + GtkWidget* page_widget = zathura_page_get_widget(zathura, page); + gtk_widget_translate_coordinates(page_widget, zathura->ui.session->gtk.view, 0, 0, &page_rect.x, &page_rect.y); - page_rect.width = page->width * zathura->document->scale; - page_rect.height = page->height * zathura->document->scale; + page_rect.width = zathura_page_get_width(page) * scale; + page_rect.height = zathura_page_get_height(page) * scale; if (gdk_rectangle_intersect(&view_rect, &page_rect, NULL) == TRUE) { - page->visible = true; + zathura_page_set_visibility(page, true); if (zathura->global.update_page_number == true && updated == false && gdk_rectangle_intersect(¢er, &page_rect, NULL) == TRUE) { - zathura->document->current_page_number = page_id; + zathura_document_set_current_page_number(zathura->document, page_id); updated = true; } } else { - page->visible = false; + zathura_page_set_visibility(page, false); } - zathura_page_widget_update_view_time(ZATHURA_PAGE(page->drawing_area)); + zathura_page_widget_update_view_time(ZATHURA_PAGE(page_widget)); } statusbar_page_number_update(zathura); @@ -117,7 +121,7 @@ cb_pages_per_row_value_changed(girara_session_t* session, const char* UNUSED(nam page_widget_set_mode(zathura, pages_per_row); if (zathura->document != NULL) { - unsigned int current_page = zathura->document->current_page_number; + unsigned int current_page = zathura_document_get_current_page_number(zathura->document); page_set_delayed(zathura, current_page); } } @@ -144,14 +148,8 @@ cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path, 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.")); - } - } + sc_toggle_index(zathura->ui.session, NULL, NULL, 0); + zathura_link_evaluate(zathura, index_element->link); } g_object_unref(model); @@ -183,26 +181,20 @@ cb_sc_follow(GtkEntry* entry, girara_session_t* session) /* 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) { + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); + if (page == NULL || zathura_page_get_visibility(page) == false) { continue; } - g_object_set(page->drawing_area, "draw-links", FALSE, NULL); + GtkWidget* page_widget = zathura_page_get_widget(zathura, page); + g_object_set(page_widget, "draw-links", FALSE, NULL); if (eval == true) { - zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page->drawing_area), index); + zathura_link_t* link = zathura_page_widget_link_get(ZATHURA_PAGE(page_widget), 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; - } - + zathura_link_evaluate(zathura, link); invalid_index = false; } } @@ -317,7 +309,7 @@ cb_view_resized(GtkWidget* UNUSED(widget), GtkAllocation* allocation, zathura_t* /* adjust only if the allocation changed */ if (width != allocation->width || height != allocation->height) { - girara_argument_t argument = { zathura->document->adjust_mode, NULL }; + girara_argument_t argument = { zathura_document_get_adjust_mode(zathura->document), NULL }; sc_adjust_window(zathura->ui.session, &argument, NULL, 0); width = allocation->width; @@ -344,3 +336,28 @@ cb_setting_recolor_change(girara_session_t* session, const char* name, render_all(zathura); } } + +bool +cb_unknown_command(girara_session_t* session, const char* input) +{ + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + g_return_val_if_fail(input != NULL, false); + + zathura_t* zathura = session->global.data; + + if (zathura->document == NULL) { + return false; + } + + /* check for number */ + for (unsigned int i = 0; i < strlen(input); i++) { + if (g_ascii_isdigit(input[i]) == FALSE) { + return false; + } + } + + page_set(zathura, atoi(input) - 1); + + return true; +} diff --git a/callbacks.h b/callbacks.h index fc332f7..a7062ea 100644 --- a/callbacks.h +++ b/callbacks.h @@ -7,6 +7,7 @@ #include #include +#include "internal.h" #include "document.h" #include "zathura.h" @@ -110,4 +111,14 @@ bool cb_view_resized(GtkWidget* widget, GtkAllocation* allocation, zathura_t* za void cb_setting_recolor_change(girara_session_t* session, const char* name, girara_setting_type_t type, void* value, void* data); +/** + * Unknown command handler which is used to handle the strict numeric goto + * command + * + * @param session The girara session + * @param input The command input + * @return true if the input has been handled + */ +bool cb_unknown_command(girara_session_t* session, const char* input); + #endif // CALLBACKS_H diff --git a/commands.c b/commands.c index 47b8427..706b718 100644 --- a/commands.c +++ b/commands.c @@ -14,9 +14,12 @@ #include "document.h" #include "utils.h" #include "page-widget.h" - +#include "page.h" +#include "internal.h" +#include "render.h" #include +#include #include #include @@ -40,12 +43,12 @@ cmd_bookmark_create(girara_session_t* session, girara_list_t* argument_list) const char* bookmark_name = girara_list_nth(argument_list, 0); zathura_bookmark_t* bookmark = zathura_bookmark_get(zathura, bookmark_name); if (bookmark != NULL) { - bookmark->page = zathura->document->current_page_number + 1; + bookmark->page = zathura_document_get_current_page_number(zathura->document) + 1; girara_notify(session, GIRARA_INFO, _("Bookmark successfuly updated: %s"), bookmark_name); return true; } - bookmark = zathura_bookmark_add(zathura, bookmark_name, zathura->document->current_page_number + 1); + bookmark = zathura_bookmark_add(zathura, bookmark_name, zathura_document_get_current_page_number(zathura->document) + 1); if (bookmark == NULL) { girara_notify(session, GIRARA_ERROR, _("Could not create bookmark: %s"), bookmark_name); return false; @@ -137,35 +140,39 @@ cmd_info(girara_session_t* session, girara_list_t* UNUSED(argument_list)) struct meta_field { char* name; - zathura_document_meta_t field; + zathura_document_information_type_t field; }; struct meta_field meta_fields[] = { - { "Title", ZATHURA_DOCUMENT_TITLE }, - { "Author", ZATHURA_DOCUMENT_AUTHOR }, - { "Subject", ZATHURA_DOCUMENT_SUBJECT }, - { "Keywords", ZATHURA_DOCUMENT_KEYWORDS }, - { "Creator", ZATHURA_DOCUMENT_CREATOR }, - { "Producer", ZATHURA_DOCUMENT_PRODUCER }, - { "Creation date", ZATHURA_DOCUMENT_CREATION_DATE }, - { "Modiciation date", ZATHURA_DOCUMENT_MODIFICATION_DATE } + { "Title", ZATHURA_DOCUMENT_INFORMATION_TITLE }, + { "Author", ZATHURA_DOCUMENT_INFORMATION_AUTHOR }, + { "Subject", ZATHURA_DOCUMENT_INFORMATION_SUBJECT }, + { "Keywords", ZATHURA_DOCUMENT_INFORMATION_KEYWORDS }, + { "Creator", ZATHURA_DOCUMENT_INFORMATION_CREATOR }, + { "Producer", ZATHURA_DOCUMENT_INFORMATION_PRODUCER }, + { "Creation date", ZATHURA_DOCUMENT_INFORMATION_CREATION_DATE }, + { "Modiciation date", ZATHURA_DOCUMENT_INFORMATION_MODIFICATION_DATE } }; + girara_list_t* information = zathura_document_get_information(zathura->document, NULL); + if (information == NULL) { + girara_notify(session, GIRARA_INFO, _("No information available.")); + return false; + } + GString* string = g_string_new(NULL); - if (string == NULL) { - return true; - } - for (unsigned int i = 0; i < LENGTH(meta_fields); i++) { - char* tmp = zathura_document_meta_get(zathura->document, meta_fields[i].field, NULL); - if (tmp != NULL) { - char* text = g_strdup_printf("%s: %s\n", meta_fields[i].name, tmp); - g_string_append(string, text); - - g_free(text); - g_free(tmp); + GIRARA_LIST_FOREACH(information, zathura_document_information_entry_t*, iter, entry) + if (entry != NULL) { + for (unsigned int i = 0; i < LENGTH(meta_fields); i++) { + if (meta_fields[i].field == entry->type) { + char* text = g_strdup_printf("%s: %s\n", meta_fields[i].name, entry->value); + g_string_append(string, text); + g_free(text); + } + } } - } + GIRARA_LIST_FOREACH_END(information, zathura_document_information_entry_t*, iter, entry); if (strlen(string->str) > 0) { g_string_erase(string, strlen(string->str) - 1, 1); @@ -186,6 +193,20 @@ cmd_help(girara_session_t* UNUSED(session), girara_list_t* return true; } +bool +cmd_hlsearch(girara_session_t* session, girara_list_t* UNUSED(argument_list)) +{ + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + + document_draw_search_results(zathura, true); + render_all(zathura); + + return true; +} + + bool cmd_open(girara_session_t* session, girara_list_t* argument_list) { @@ -231,7 +252,20 @@ cmd_print(girara_session_t* session, girara_list_t* UNUSED(argument_list)) return false; } - print((zathura_t*) session->global.data); + print(zathura); + + return true; +} + +bool +cmd_nohlsearch(girara_session_t* session, girara_list_t* UNUSED(argument_list)) +{ + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + + document_draw_search_results(zathura, false); + render_all(zathura); return true; } @@ -302,34 +336,49 @@ cmd_search(girara_session_t* session, const char* input, girara_argument_t* argu } bool firsthit = true; - zathura_plugin_error_t error = ZATHURA_PLUGIN_ERROR_OK; + zathura_error_t error = ZATHURA_ERROR_OK; - 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->document->current_page_number) % zathura->document->number_of_pages]; + + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + unsigned int current_page_number = zathura_document_get_current_page_number(zathura->document); + + /* reset search highlighting */ + bool nohlsearch = false; + girara_setting_get(session, "nohlsearch", &nohlsearch); + + if (nohlsearch == false) { + document_draw_search_results(zathura, true); + } + + /* search pages */ + for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) { + unsigned int index = (page_id + current_page_number) % number_of_pages; + zathura_page_t* page = zathura_document_get_page(zathura->document, index); if (page == NULL) { continue; } - g_object_set(page->drawing_area, "draw-links", FALSE, NULL); + GtkWidget* page_widget = zathura_page_get_widget(zathura, page); + g_object_set(page_widget, "draw-links", FALSE, NULL); girara_list_t* result = zathura_page_search_text(page, input, &error); if (result == NULL || girara_list_size(result) == 0) { girara_list_free(result); - g_object_set(page->drawing_area, "search-results", NULL, NULL); + g_object_set(page_widget, "search-results", NULL, NULL); - if (error == ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED) { + if (error == ZATHURA_ERROR_NOT_IMPLEMENTED) { break; } else { continue; } } - g_object_set(page->drawing_area, "search-results", result, NULL); + g_object_set(page_widget, "search-results", result, NULL); if (firsthit == true) { if (page_id != 0) { - page_set_delayed(zathura, page->number); + page_set_delayed(zathura, zathura_page_get_index(page)); } - g_object_set(page->drawing_area, "search-current", 0, NULL); + g_object_set(page_widget, "search-current", 0, NULL); firsthit = false; } } @@ -353,21 +402,86 @@ cmd_export(girara_session_t* session, girara_list_t* argument_list) return false; } - const char* attachment_name = girara_list_nth(argument_list, 0); + const char* file_identifier = girara_list_nth(argument_list, 0); const char* file_name = girara_list_nth(argument_list, 1); - if (file_name == NULL || attachment_name == NULL) { + if (file_name == NULL || file_identifier == NULL) { return false; } - char* file_name2 = girara_fix_path(file_name); - if (zathura_document_attachment_save(zathura->document, attachment_name, file_name) == false) { - girara_notify(session, GIRARA_ERROR, _("Couldn't write attachment '%s' to '%s'."), attachment_name, file_name); - } else { - girara_notify(session, GIRARA_INFO, _("Wrote attachment '%s' to '%s'."), attachment_name, file_name2); + char* export_path = girara_fix_path(file_name); + if (export_path == NULL) { + return false; } - g_free(file_name2); + /* attachment */ + if (strncmp(file_identifier, "attachment-", strlen("attachment-")) == 0) { + if (zathura_document_attachment_save(zathura->document, file_identifier + strlen("attachment-"), export_path) == false) { + girara_notify(session, GIRARA_ERROR, _("Couldn't write attachment '%s' to '%s'."), file_identifier, file_name); + } else { + girara_notify(session, GIRARA_INFO, _("Wrote attachment '%s' to '%s'."), file_identifier, export_path); + } + /* image */ + } else if (strncmp(file_identifier, "image-p", strlen("image-p")) == 0 && strlen(file_identifier) >= 10) { + /* parse page id */ + const char* input = file_identifier + strlen("image-p"); + int page_id = atoi(input); + if (page_id == 0) { + goto image_error; + } + + /* parse image id */ + input = strstr(input, "-"); + if (input == NULL) { + goto image_error; + } + + int image_id = atoi(input + 1); + if (image_id == 0) { + goto image_error; + } + + /* get image */ + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id - 1); + if (page == NULL) { + goto image_error; + } + + girara_list_t* images = zathura_page_images_get(page, NULL); + if (images == NULL) { + goto image_error; + } + + zathura_image_t* image = girara_list_nth(images, image_id - 1); + if (image == NULL) { + goto image_error; + } + + cairo_surface_t* surface = zathura_page_image_get_cairo(page, image, NULL); + if (surface == NULL) { + goto image_error; + } + + if (cairo_surface_write_to_png(surface, export_path) == CAIRO_STATUS_SUCCESS) { + girara_notify(session, GIRARA_INFO, _("Wrote image '%s' to '%s'."), file_identifier, export_path); + } else { + girara_notify(session, GIRARA_ERROR, _("Couldn't write image '%s' to '%s'."), file_identifier, file_name); + } + + goto error_ret; + +image_error: + + girara_notify(session, GIRARA_ERROR, _("Unknown image '%s'."), file_identifier); + goto error_ret; + /* unknown */ + } else { + girara_notify(session, GIRARA_ERROR, _("Unknown attachment or image '%s'."), file_identifier); + } + +error_ret: + + g_free(export_path); return true; } @@ -384,7 +498,7 @@ cmd_offset(girara_session_t* session, girara_list_t* argument_list) } /* no argument: take current page as offset */ - unsigned int page_offset = zathura->document->current_page_number; + unsigned int page_offset = zathura_document_get_current_page_number(zathura->document); /* retrieve offset from argument */ if (girara_list_size(argument_list) == 1) { @@ -398,8 +512,8 @@ cmd_offset(girara_session_t* session, girara_list_t* argument_list) } } - if (page_offset < zathura->document->number_of_pages) { - zathura->document->page_offset = page_offset; + if (page_offset < zathura_document_get_number_of_pages(zathura->document)) { + zathura_document_set_page_offset(zathura->document, page_offset); } return true; diff --git a/commands.h b/commands.h index f1f87a4..6e6a1a0 100644 --- a/commands.h +++ b/commands.h @@ -60,6 +60,15 @@ bool cmd_info(girara_session_t* session, girara_list_t* argument_list); */ bool cmd_help(girara_session_t* session, girara_list_t* argument_list); +/** + * Shows current search results + * + * @param session The used girara session + * @param argument_list List of passed arguments + * @return true if no error occured + */ +bool cmd_hlsearch(girara_session_t* session, girara_list_t* argument_list); + /** * Opens a document file * @@ -78,6 +87,15 @@ bool cmd_open(girara_session_t* session, girara_list_t* argument_list); */ bool cmd_print(girara_session_t* session, girara_list_t* argument_list); +/** + * Hides current search results + * + * @param session The used girara session + * @param argument_list List of passed arguments + * @return true if no error occured + */ +bool cmd_nohlsearch(girara_session_t* session, girara_list_t* argument_list); + /** * Close zathura * diff --git a/completion.c b/completion.c index c485977..cca4a18 100644 --- a/completion.c +++ b/completion.c @@ -5,10 +5,13 @@ #include #include #include +#include #include "bookmarks.h" +#include "document.h" #include "completion.h" #include "utils.h" +#include "page.h" #include #include @@ -244,7 +247,7 @@ cc_bookmarks(girara_session_t* session, const char* input) const size_t input_length = strlen(input); GIRARA_LIST_FOREACH(zathura->bookmarks.bookmarks, zathura_bookmark_t*, iter, bookmark) if (input_length <= strlen(bookmark->id) && !strncmp(input, bookmark->id, input_length)) { - gchar* paged = g_strdup_printf("Page %d", bookmark->page); + gchar* paged = g_strdup_printf(_("Page %d"), bookmark->page); girara_completion_group_add_element(group, bookmark->id, paged); g_free(paged); } @@ -270,46 +273,107 @@ error_free: girara_completion_t* cc_export(girara_session_t* session, const char* input) { - if (input == NULL) { - return NULL; - } - g_return_val_if_fail(session != NULL, NULL); g_return_val_if_fail(session->global.data != NULL, NULL); zathura_t* zathura = session->global.data; - girara_completion_t* completion = girara_completion_init(); - girara_completion_group_t* group = girara_completion_group_create(session, NULL); + if (input == NULL || zathura->document == NULL) { + goto error_ret; + } - if (completion == NULL || group == NULL) { + girara_completion_t* completion = NULL; + girara_completion_group_t* attachment_group = NULL; + girara_completion_group_t* image_group = NULL; + + completion = girara_completion_init(); + if (completion == NULL) { goto error_free; } + attachment_group = girara_completion_group_create(session, _("Attachments")); + if (attachment_group == NULL) { + goto error_free; + } + + /* add attachments */ const size_t input_length = strlen(input); girara_list_t* attachments = zathura_document_attachments_get(zathura->document, NULL); - if (attachments == NULL) { + if (attachments != NULL) { + bool added = false; + + GIRARA_LIST_FOREACH(attachments, const char*, iter, attachment) + if (input_length <= strlen(attachment) && !strncmp(input, attachment, input_length)) { + char* attachment_string = g_strdup_printf("attachment-%s", attachment); + girara_completion_group_add_element(attachment_group, attachment_string, NULL); + g_free(attachment_string); + added = true; + } + GIRARA_LIST_FOREACH_END(zathura->bookmarks.bookmarks, zathura_bookmark_t*, iter, bookmark); + + if (added == true) { + girara_completion_add_group(completion, attachment_group); + } else { + girara_completion_group_free(attachment_group); + attachment_group = NULL; + } + + girara_list_free(attachments); + } + + /* add images */ + image_group = girara_completion_group_create(session, _("Images")); + if (image_group == NULL) { goto error_free; } - GIRARA_LIST_FOREACH(attachments, const char*, iter, attachment) - if (input_length <= strlen(attachment) && !strncmp(input, attachment, input_length)) { - girara_completion_group_add_element(group, attachment, NULL); - } - GIRARA_LIST_FOREACH_END(zathura->bookmarks.bookmarks, zathura_bookmark_t*, iter, bookmark); + bool added = false; + + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); + if (page == NULL) { + continue; + } + + girara_list_t* images = zathura_page_images_get(page, NULL); + if (images != NULL) { + unsigned int image_number = 1; + GIRARA_LIST_FOREACH(images, zathura_image_t*, iter, UNUSED(image)) + char* image_string = g_strdup_printf("image-p%d-%d", page_id + 1, image_number); + girara_completion_group_add_element(image_group, image_string, NULL); + g_free(image_string); + + added = true; + image_number++; + GIRARA_LIST_FOREACH_END(images, zathura_image_t*, iter, image); + girara_list_free(images); + } + } + + if (added == true) { + girara_completion_add_group(completion, image_group); + } else { + girara_completion_group_free(image_group); + image_group = NULL; + } - girara_completion_add_group(completion, group); - girara_list_free(attachments); return completion; error_free: - if (completion) { + if (completion != NULL) { girara_completion_free(completion); } - if (group) { - girara_completion_group_free(group); + if (attachment_group != NULL) { + girara_completion_group_free(attachment_group); } + if (image_group != NULL) { + girara_completion_group_free(image_group); + } + +error_ret: + return NULL; } diff --git a/config.c b/config.c index 47a717f..6c7c801 100644 --- a/config.c +++ b/config.c @@ -7,6 +7,8 @@ #include "shortcuts.h" #include "zathura.h" #include "render.h" +#include "marks.h" +#include "utils.h" #include #include @@ -50,8 +52,23 @@ cb_page_padding_changed(girara_session_t* session, const char* UNUSED(name), zathura_t* zathura = session->global.data; int val = *(int*) value; - gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), val); - gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), val); + if (GTK_IS_TABLE(zathura->ui.page_widget) == TRUE) { + gtk_table_set_row_spacings(GTK_TABLE(zathura->ui.page_widget), val); + gtk_table_set_col_spacings(GTK_TABLE(zathura->ui.page_widget), val); + } +} + +static void +cb_nohlsearch_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; + + document_draw_search_results(zathura, !(*(bool*) value)); + render_all(zathura); } void @@ -93,9 +110,9 @@ config_load_default(zathura_t* zathura) girara_setting_add(gsession, "zoom-min", &int_value, INT, false, _("Zoom minimum"), NULL, NULL); int_value = 1000; girara_setting_add(gsession, "zoom-max", &int_value, INT, false, _("Zoom maximum"), NULL, NULL); - int_value = 30; - girara_setting_add(gsession, "page-store-threshold", &int_value, INT, false, _("Store unvisible pages only for some time (in seconds)"), NULL, NULL); - girara_setting_add(gsession, "page-store-interval", &int_value, INT, true, _("Amount of seconds between the checks for invisible pages"), NULL, NULL); + int_value = 5; + girara_setting_add(gsession, "page-store-threshold", &int_value, INT, false, _("Life time (in seconds) of a hidden page"), NULL, NULL); + girara_setting_add(gsession, "page-store-interval", &int_value, INT, true, _("Amount of seconds between each cache purge"), NULL, NULL); girara_setting_add(gsession, "recolor-darkcolor", NULL, STRING, false, _("Recoloring (dark color)"), cb_color_change, NULL); girara_setting_set(gsession, "recolor-darkcolor", "#FFFFFF"); @@ -110,6 +127,8 @@ config_load_default(zathura_t* zathura) girara_setting_add(gsession, "recolor", &bool_value, BOOLEAN, false, _("Recolor pages"), cb_setting_recolor_change, NULL); bool_value = false; girara_setting_add(gsession, "scroll-wrap", &bool_value, BOOLEAN, false, _("Wrap scrolling"), NULL, NULL); + bool_value = false; + girara_setting_add(gsession, "advance-pages-per-row", &bool_value, BOOLEAN, false, _("Advance number of pages per row"), NULL, NULL); float_value = 0.5; girara_setting_add(gsession, "highlight-transparency", &float_value, FLOAT, false, _("Transparency for highlighting"), NULL, NULL); bool_value = true; @@ -121,16 +140,17 @@ config_load_default(zathura_t* zathura) girara_setting_add(gsession, "show-directories", &bool_value, BOOLEAN, false, _("Show directories"), NULL, NULL); bool_value = false; girara_setting_add(gsession, "open-first-page", &bool_value, BOOLEAN, false, _("Always open on first page"), NULL, NULL); + bool_value = false; + girara_setting_add(gsession, "nohlsearch", &bool_value, BOOLEAN, false, _("Highlight search results"), cb_nohlsearch_changed, NULL); + bool_value = true; + girara_setting_add(gsession, "abort-clear-search", &bool_value, BOOLEAN, false, _("Clear search results on abort"), NULL, NULL); /* define default shortcuts */ girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_c, NULL, sc_abort, 0, 0, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_Escape, NULL, sc_abort, 0, 0, NULL); - girara_shortcut_add(gsession, 0, GDK_KEY_a, NULL, sc_adjust_window, NORMAL, ADJUST_BESTFIT, NULL); - girara_shortcut_add(gsession, 0, GDK_KEY_s, NULL, sc_adjust_window, NORMAL, ADJUST_WIDTH, NULL); - - girara_shortcut_add(gsession, 0, GDK_KEY_m, NULL, sc_change_mode, NORMAL, ADD_MARKER, NULL); - girara_shortcut_add(gsession, 0, GDK_KEY_apostrophe, NULL, sc_change_mode, NORMAL, EVAL_MARKER, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_a, NULL, sc_adjust_window, NORMAL, ZATHURA_ADJUST_BESTFIT, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_s, NULL, sc_adjust_window, NORMAL, ZATHURA_ADJUST_WIDTH, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); girara_shortcut_add(gsession, GDK_SHIFT_MASK, GDK_KEY_slash, NULL, sc_focus_inputbar, NORMAL, 0, &("/")); @@ -146,6 +166,9 @@ config_load_default(zathura_t* zathura) girara_shortcut_add(gsession, 0, 0, "G", sc_goto, NORMAL, BOTTOM, NULL); girara_shortcut_add(gsession, 0, 0, "G", sc_goto, FULLSCREEN, BOTTOM, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_m, NULL, sc_mark_add, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_apostrophe, NULL, sc_mark_evaluate, NORMAL, 0, NULL); + girara_shortcut_add(gsession, 0, GDK_KEY_J, NULL, sc_navigate, NORMAL, NEXT, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_K, NULL, sc_navigate, NORMAL, PREVIOUS, NULL); girara_shortcut_add(gsession, GDK_MOD1_MASK, GDK_KEY_Right, NULL, sc_navigate, NORMAL, NEXT, NULL); @@ -174,6 +197,8 @@ config_load_default(zathura_t* zathura) girara_shortcut_add(gsession, 0, GDK_KEY_space, NULL, sc_navigate_index, INDEX, SELECT, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_Return, NULL, sc_navigate_index, INDEX, SELECT, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_p, NULL, sc_print, NORMAL, 0, NULL); + girara_shortcut_add(gsession, GDK_CONTROL_MASK, GDK_KEY_i, NULL, sc_recolor, NORMAL, 0, NULL); girara_shortcut_add(gsession, 0, GDK_KEY_R, NULL, sc_reload, NORMAL, 0, NULL); @@ -240,19 +265,23 @@ config_load_default(zathura_t* zathura) girara_mouse_event_add(gsession, GDK_BUTTON2_MASK, 0, sc_mouse_scroll, NORMAL, GIRARA_EVENT_MOTION_NOTIFY, 0, NULL); /* define default inputbar commands */ - girara_inputbar_command_add(gsession, "bmark", NULL, cmd_bookmark_create, NULL, _("Add a bookmark")); - girara_inputbar_command_add(gsession, "bdelete", NULL, cmd_bookmark_delete, cc_bookmarks, _("Delete a bookmark")); - girara_inputbar_command_add(gsession, "blist", NULL, cmd_bookmark_open, cc_bookmarks, _("List all bookmarks")); - girara_inputbar_command_add(gsession, "close", NULL, cmd_close, NULL, _("Close current file")); - girara_inputbar_command_add(gsession, "info", NULL, cmd_info, NULL, _("Show file information")); - girara_inputbar_command_add(gsession, "help", NULL, cmd_help, NULL, _("Show help")); - girara_inputbar_command_add(gsession, "open", "o", cmd_open, cc_open, _("Open document")); - girara_inputbar_command_add(gsession, "quit", "q", cmd_quit, NULL, _("Close zathura")); - girara_inputbar_command_add(gsession, "print", NULL, cmd_print, NULL, _("Print document")); - girara_inputbar_command_add(gsession, "write", NULL, cmd_save, cc_write, _("Save document")); - girara_inputbar_command_add(gsession, "write!", NULL, cmd_savef, cc_write, _("Save document (and force overwriting)")); - girara_inputbar_command_add(gsession, "export", NULL, cmd_export, cc_export, _("Save attachments")); - girara_inputbar_command_add(gsession, "offset", NULL, cmd_offset, NULL, _("Set page offset")); + girara_inputbar_command_add(gsession, "bmark", NULL, cmd_bookmark_create, NULL, _("Add a bookmark")); + girara_inputbar_command_add(gsession, "bdelete", NULL, cmd_bookmark_delete, cc_bookmarks, _("Delete a bookmark")); + girara_inputbar_command_add(gsession, "blist", NULL, cmd_bookmark_open, cc_bookmarks, _("List all bookmarks")); + girara_inputbar_command_add(gsession, "close", NULL, cmd_close, NULL, _("Close current file")); + girara_inputbar_command_add(gsession, "info", NULL, cmd_info, NULL, _("Show file information")); + girara_inputbar_command_add(gsession, "help", NULL, cmd_help, NULL, _("Show help")); + girara_inputbar_command_add(gsession, "open", "o", cmd_open, cc_open, _("Open document")); + girara_inputbar_command_add(gsession, "quit", "q", cmd_quit, NULL, _("Close zathura")); + girara_inputbar_command_add(gsession, "print", NULL, cmd_print, NULL, _("Print document")); + girara_inputbar_command_add(gsession, "write", NULL, cmd_save, cc_write, _("Save document")); + girara_inputbar_command_add(gsession, "write!", NULL, cmd_savef, cc_write, _("Save document (and force overwriting)")); + girara_inputbar_command_add(gsession, "export", NULL, cmd_export, cc_export, _("Save attachments")); + girara_inputbar_command_add(gsession, "offset", NULL, cmd_offset, NULL, _("Set page offset")); + girara_inputbar_command_add(gsession, "mark", NULL, cmd_marks_add, NULL, _("Mark current location within the document")); + girara_inputbar_command_add(gsession, "delmarks", "delm", cmd_marks_delete, NULL, _("Delete the specified marks")); + girara_inputbar_command_add(gsession, "nohlsearch", "nohl", cmd_nohlsearch, NULL, _("Don't highlight current search results")); + girara_inputbar_command_add(gsession, "hlsearch", NULL, cmd_hlsearch, NULL, _("Highlight current search results")); girara_special_command_add(gsession, '/', cmd_search, true, FORWARD, NULL); girara_special_command_add(gsession, '?', cmd_search, true, BACKWARD, NULL); @@ -265,6 +294,7 @@ config_load_default(zathura_t* zathura) girara_shortcut_mapping_add(gsession, "goto", sc_goto); girara_shortcut_mapping_add(gsession, "navigate_index", sc_navigate_index); girara_shortcut_mapping_add(gsession, "navigate", sc_navigate); + girara_shortcut_mapping_add(gsession, "print", sc_print); girara_shortcut_mapping_add(gsession, "quit", sc_quit); girara_shortcut_mapping_add(gsession, "recolor", sc_recolor); girara_shortcut_mapping_add(gsession, "reload", sc_reload); @@ -302,8 +332,8 @@ config_load_default(zathura_t* zathura) girara_argument_mapping_add(gsession, "specific", ZOOM_SPECIFIC); girara_argument_mapping_add(gsession, "top", TOP); girara_argument_mapping_add(gsession, "up", UP); - girara_argument_mapping_add(gsession, "best-fit", ADJUST_BESTFIT); - girara_argument_mapping_add(gsession, "width", ADJUST_WIDTH); + girara_argument_mapping_add(gsession, "best-fit", ZATHURA_ADJUST_BESTFIT); + girara_argument_mapping_add(gsession, "width", ZATHURA_ADJUST_WIDTH); girara_argument_mapping_add(gsession, "rotate-cw", ROTATE_CW); girara_argument_mapping_add(gsession, "rotate-ccw", ROTATE_CCW); } diff --git a/config.mk b/config.mk index 0001c36..99e9827 100644 --- a/config.mk +++ b/config.mk @@ -2,12 +2,12 @@ # zathura make config ZATHURA_VERSION_MAJOR = 0 -ZATHURA_VERSION_MINOR = 1 -ZATHURA_VERSION_REV = 2 +ZATHURA_VERSION_MINOR = 2 +ZATHURA_VERSION_REV = 0 # If the API changes, the API version and the ABI version have to be bumped. -ZATHURA_API_VERSION = 1 +ZATHURA_API_VERSION = 2 # If the ABI breaks for any reason, this has to be bumped. -ZATHURA_ABI_VERSION = 1 +ZATHURA_ABI_VERSION = 2 VERSION = ${ZATHURA_VERSION_MAJOR}.${ZATHURA_VERSION_MINOR}.${ZATHURA_VERSION_REV} # the GTK+ version to use @@ -16,12 +16,12 @@ ZATHURA_GTK_VERSION ?= 2 # minimum required zathura version # If you want to disable the check, set GIRARA_VERSION_CHECK to 0. -GIRARA_MIN_VERSION = 0.1.2 +GIRARA_MIN_VERSION = 0.1.3 GIRARA_VERSION_CHECK ?= $(shell pkg-config --atleast-version=$(GIRARA_MIN_VERSION) girara-gtk${ZATHURA_GTK_VERSION}; echo $$?) # database # To disable support for the sqlite backend set WITH_SQLITE to 0. -WITH_SQLITE ?= $(shell (pkg-config --exists sqlite3 && echo 1) || echo 0) +WITH_SQLITE ?= $(shell (pkg-config --atleast-version=3.5.9 sqlite3 && echo 1) || echo 0) # paths PREFIX ?= /usr @@ -40,7 +40,13 @@ RSTTOMAN ?= /usr/bin/rst2man # libs GTK_INC ?= $(shell pkg-config --cflags gtk+-${ZATHURA_GTK_VERSION}.0) -GTK_LIB ?= $(shell pkg-config --libs gtk+-${ZATHURA_GTK_VERSION}.0 gthread-2.0) +GTK_LIB ?= $(shell pkg-config --libs gtk+-${ZATHURA_GTK_VERSION}.0) + +GTHREAD_INC ?= $(shell pkg-config --cflags gthread-2.0) +GTHREAD_LIB ?= $(shell pkg-config --libs gthread-2.0) + +GMODULE_INC ?= $(shell pkg-config --cflags gmodule-no-export-2.0) +GMODULE_LIB ?= $(shell pkg-config --libs gmodule-no-export-2.0) GIRARA_INC ?= $(shell pkg-config --cflags girara-gtk${ZATHURA_GTK_VERSION}) GIRARA_LIB ?= $(shell pkg-config --libs girara-gtk${ZATHURA_GTK_VERSION}) @@ -50,25 +56,12 @@ SQLITE_INC ?= $(shell pkg-config --cflags sqlite3) SQLITE_LIB ?= $(shell pkg-config --libs sqlite3) endif -#set it to an empty value if you don't need to link against ld for dlopen and friends -DL_LIB ?= -ldl - -INCS = ${GIRARA_INC} ${GTK_INC} -LIBS = ${GIRARA_LIB} ${GTK_LIB} ${DL_LIB} -lpthread -lm +INCS = ${GIRARA_INC} ${GTK_INC} ${GTHREAD_INC} ${GMODULE_INC} +LIBS = ${GIRARA_LIB} ${GTK_LIB} ${GTHREAD_LIB} ${GMODULE_LIB} -lpthread -lm # flags CFLAGS += -std=c99 -pedantic -Wall -Wno-format-zero-length -Wextra $(INCS) -ifeq (,$(findstring -DZATHURA_PLUGINDIR,${CPPFLAGS})) -CPPFLAGS += -DZATHURA_PLUGINDIR=\"${PLUGINDIR}\" -endif -ifeq (,$(findstring -DGETTEXT_PACKAGE,${CPPFLAGS})) -CPPFLAGS += -DGETTEXT_PACKAGE=\"${PROJECT}\" -endif -ifeq (,$(findstring -DLOCALEDIR,${CPPFLAGS})) -CPPFLAGS += -DLOCALEDIR=\"${LOCALEDIR}\" -endif - # debug DFLAGS ?= -g diff --git a/database-plain.c b/database-plain.c index e10093f..3003c68 100644 --- a/database-plain.c +++ b/database-plain.c @@ -20,12 +20,20 @@ #define KEY_OFFSET "offset" #define KEY_SCALE "scale" #define KEY_ROTATE "rotate" +#define KEY_PAGES_PER_ROW "pages-per-row" +#define KEY_POSITION_X "position-x" +#define KEY_POSITION_Y "position-y" +#ifdef __GNU__ +#include +#define file_lock_set(fd, cmd) flock(fd, cmd) +#else #define file_lock_set(fd, cmd) \ { \ struct flock lock = { .l_type = cmd, .l_start = 0, .l_whence = SEEK_SET, .l_len = 0}; \ fcntl(fd, F_SETLK, lock); \ } +#endif static void zathura_database_interface_init(ZathuraDatabaseInterface* iface); @@ -40,9 +48,9 @@ static bool plain_remove_bookmark(zathura_database_t* db, const char* file, static girara_list_t* plain_load_bookmarks(zathura_database_t* db, const char* file); static bool plain_set_fileinfo(zathura_database_t* db, const char* file, - unsigned int page, unsigned int offset, double scale, unsigned int rotation); + zathura_fileinfo_t* file_info); static bool plain_get_fileinfo(zathura_database_t* db, const char* file, - unsigned int* page, unsigned int* offset, double* scale, unsigned int* rotation); + zathura_fileinfo_t* file_info); static void plain_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); @@ -362,24 +370,35 @@ plain_load_bookmarks(zathura_database_t* db, const char* file) } static bool -plain_set_fileinfo(zathura_database_t* db, const char* file, unsigned int - page, unsigned int offset, double scale, unsigned int rotation) +plain_set_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* + file_info) { zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db); - if (priv->history == NULL) { + if (priv->history == NULL || file_info == NULL || file == NULL) { return false; } - char* tmp = g_strdup_printf("%f", scale); char* name = prepare_filename(file); - g_key_file_set_integer(priv->history, name, KEY_PAGE, page); - g_key_file_set_integer(priv->history, name, KEY_OFFSET, offset); - g_key_file_set_string (priv->history, name, KEY_SCALE, tmp); - g_key_file_set_integer(priv->history, name, KEY_ROTATE, rotation); + g_key_file_set_integer(priv->history, name, KEY_PAGE, file_info->current_page); + g_key_file_set_integer(priv->history, name, KEY_OFFSET, file_info->page_offset); + + char* tmp = g_strdup_printf("%f", file_info->scale); + g_key_file_set_string (priv->history, name, KEY_SCALE, tmp); + g_free(tmp); + + g_key_file_set_integer(priv->history, name, KEY_ROTATE, file_info->rotation); + g_key_file_set_integer(priv->history, name, KEY_PAGES_PER_ROW, file_info->pages_per_row); + + tmp = g_strdup_printf("%f", file_info->position_x); + g_key_file_set_string(priv->history, name, KEY_POSITION_X, tmp); + g_free(tmp); + + tmp = g_strdup_printf("%f", file_info->position_y); + g_key_file_set_string(priv->history, name, KEY_POSITION_Y, tmp); + g_free(tmp); g_free(name); - g_free(tmp); zathura_db_write_key_file_to_file(priv->history_path, priv->history); @@ -387,9 +406,13 @@ plain_set_fileinfo(zathura_database_t* db, const char* file, unsigned int } static bool -plain_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* - page, unsigned int* offset, double* scale, unsigned int* rotation) +plain_get_fileinfo(zathura_database_t* db, const char* file, zathura_fileinfo_t* + file_info) { + if (db == NULL || file == NULL || file_info == NULL) { + return false; + } + zathura_plaindatabase_private_t* priv = ZATHURA_PLAINDATABASE_GET_PRIVATE(db); if (priv->history == NULL) { return false; @@ -397,16 +420,33 @@ plain_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* char* name = prepare_filename(file); if (g_key_file_has_group(priv->history, name) == FALSE) { + g_free(name); return false; } - *page = g_key_file_get_integer(priv->history, name, KEY_PAGE, NULL); - *offset = g_key_file_get_integer(priv->history, name, KEY_OFFSET, NULL); - *rotation = g_key_file_get_integer(priv->history, name, KEY_ROTATE, NULL); + file_info->current_page = g_key_file_get_integer(priv->history, name, KEY_PAGE, NULL); + file_info->page_offset = g_key_file_get_integer(priv->history, name, KEY_OFFSET, NULL); + file_info->rotation = g_key_file_get_integer(priv->history, name, KEY_ROTATE, NULL); + file_info->pages_per_row = g_key_file_get_integer(priv->history, name, KEY_PAGES_PER_ROW, NULL); char* scale_string = g_key_file_get_string(priv->history, name, KEY_SCALE, NULL); - *scale = strtod(scale_string, NULL); - g_free(scale_string); + if (scale_string != NULL) { + file_info->scale = strtod(scale_string, NULL); + g_free(scale_string); + } + + char* position_x_string = g_key_file_get_string(priv->history, name, KEY_POSITION_X, NULL); + if (position_x_string != NULL) { + file_info->position_x = strtod(position_x_string, NULL); + g_free(position_x_string); + } + + char* position_y_string = g_key_file_get_string(priv->history, name, KEY_POSITION_Y, NULL); + if (position_y_string != NULL) { + file_info->position_y = strtod(position_y_string, NULL); + g_free(position_y_string); + } + g_free(name); return true; @@ -441,7 +481,7 @@ zathura_db_read_key_file_from_file(const char* path) } /* open file */ - FILE* file = fopen(path, "r"); + FILE* file = fopen(path, "rw"); if (file == NULL) { return NULL; } @@ -550,4 +590,6 @@ cb_zathura_db_watch_file(GFileMonitor* UNUSED(monitor), GFile* file, GFile* UNUS priv->history = zathura_db_read_key_file_from_file(priv->history_path); } + + g_free(path); } diff --git a/database-sqlite.c b/database-sqlite.c index eec30b3..b8f3edb 100644 --- a/database-sqlite.c +++ b/database-sqlite.c @@ -20,9 +20,9 @@ static bool sqlite_remove_bookmark(zathura_database_t* db, const char* file, static girara_list_t* sqlite_load_bookmarks(zathura_database_t* db, const char* file); static bool sqlite_set_fileinfo(zathura_database_t* db, const char* file, - unsigned int page, unsigned int offset, double scale, unsigned int rotation); + zathura_fileinfo_t* file_info); static bool sqlite_get_fileinfo(zathura_database_t* db, const char* file, - unsigned int* page, unsigned int* offset, double* scale, unsigned int* rotation); + zathura_fileinfo_t* file_info); static void sqlite_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); @@ -118,7 +118,16 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path) "page INTEGER," "offset INTEGER," "scale FLOAT," - "rotation INTEGER);"; + "rotation INTEGER," + "pages_per_row INTEGER," + "position_x FLOAT," + "position_y FLOAT" + ");"; + + static const char SQL_FILEINFO_ALTER[] = + "ALTER TABLE fileinfo ADD COLUMN pages_per_row INTEGER;" + "ALTER TABLE fileinfo ADD COLUMN position_x FLOAT;" + "ALTER TABLE fileinfo ADD COLUMN position_y FLOAT;"; sqlite3* session = NULL; if (sqlite3_open(path, &session) != SQLITE_OK) { @@ -138,6 +147,14 @@ sqlite_db_init(ZathuraSQLDatabase* db, const char* path) return; } + const char* data_type = NULL; + if (sqlite3_table_column_metadata(session, NULL, "fileinfo", "pages_per_row", &data_type, NULL, NULL, NULL, NULL) != SQLITE_OK) { + girara_debug("old database table layout detected; updating ..."); + if (sqlite3_exec(session, SQL_FILEINFO_ALTER, NULL, 0, NULL) != SQLITE_OK) { + girara_warning("failed to update database table layout"); + } + } + priv->session = session; } @@ -272,24 +289,31 @@ sqlite_load_bookmarks(zathura_database_t* db, const char* file) } static bool -sqlite_set_fileinfo(zathura_database_t* db, const char* file, unsigned int - page, unsigned int offset, double scale, unsigned int rotation) +sqlite_set_fileinfo(zathura_database_t* db, const char* file, + zathura_fileinfo_t* file_info) { + if (db == NULL || file == NULL || file_info == NULL) { + return false; + } + zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db); static const char SQL_FILEINFO_SET[] = - "REPLACE INTO fileinfo (file, page, offset, scale, rotation) VALUES (?, ?, ?, ?, ?);"; + "REPLACE INTO fileinfo (file, page, offset, scale, rotation, pages_per_row, position_x, position_y) VALUES (?, ?, ?, ?, ?, ?, ?, ?);"; sqlite3_stmt* stmt = prepare_statement(priv->session, SQL_FILEINFO_SET); if (stmt == NULL) { return false; } - if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK || - sqlite3_bind_int(stmt, 2, page) != SQLITE_OK || - sqlite3_bind_int(stmt, 3, offset) != SQLITE_OK || - sqlite3_bind_double(stmt, 4, scale) != SQLITE_OK || - sqlite3_bind_int(stmt, 5, rotation) != SQLITE_OK) { + if (sqlite3_bind_text(stmt, 1, file, -1, NULL) != SQLITE_OK || + sqlite3_bind_int(stmt, 2, file_info->current_page) != SQLITE_OK || + sqlite3_bind_int(stmt, 3, file_info->page_offset) != SQLITE_OK || + sqlite3_bind_double(stmt, 4, file_info->scale) != SQLITE_OK || + sqlite3_bind_int(stmt, 5, file_info->rotation) != SQLITE_OK || + sqlite3_bind_int(stmt, 6, file_info->pages_per_row) != SQLITE_OK || + sqlite3_bind_double(stmt, 7, file_info->position_x) != SQLITE_OK || + sqlite3_bind_double(stmt, 8, file_info->position_y) != SQLITE_OK) { sqlite3_finalize(stmt); girara_error("Failed to bind arguments."); return false; @@ -302,13 +326,17 @@ sqlite_set_fileinfo(zathura_database_t* db, const char* file, unsigned int } static bool -sqlite_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* - page, unsigned int* offset, double* scale, unsigned int* rotation) +sqlite_get_fileinfo(zathura_database_t* db, const char* file, + zathura_fileinfo_t* file_info) { + if (db == NULL || file == NULL || file_info == NULL) { + return false; + } + zathura_sqldatabase_private_t* priv = ZATHURA_SQLDATABASE_GET_PRIVATE(db); static const char SQL_FILEINFO_GET[] = - "SELECT page, offset, scale, rotation FROM fileinfo WHERE file = ?;"; + "SELECT page, offset, scale, rotation, pages_per_row, position_x, position_y FROM fileinfo WHERE file = ?;"; sqlite3_stmt* stmt = prepare_statement(priv->session, SQL_FILEINFO_GET); if (stmt == NULL) { @@ -327,10 +355,14 @@ sqlite_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* return false; } - *page = sqlite3_column_int(stmt, 0); - *offset = sqlite3_column_int(stmt, 1); - *scale = sqlite3_column_double(stmt, 2); - *rotation = sqlite3_column_int(stmt, 3); + file_info->current_page = sqlite3_column_int(stmt, 0); + file_info->page_offset = sqlite3_column_int(stmt, 1); + file_info->scale = sqlite3_column_double(stmt, 2); + file_info->rotation = sqlite3_column_int(stmt, 3); + file_info->pages_per_row = sqlite3_column_int(stmt, 4); + file_info->position_x = sqlite3_column_double(stmt, 5); + file_info->position_y = sqlite3_column_double(stmt, 6); + sqlite3_finalize(stmt); return true; diff --git a/database.c b/database.c index 48c1518..5d481e7 100644 --- a/database.c +++ b/database.c @@ -46,22 +46,19 @@ zathura_db_load_bookmarks(zathura_database_t* db, const char* file) } bool -zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned int - page, unsigned int offset, double scale, unsigned int rotation) +zathura_db_set_fileinfo(zathura_database_t* db, const char* file, + zathura_fileinfo_t* file_info) { - g_return_val_if_fail(ZATHURA_IS_DATABASE(db) && file != NULL, false); + g_return_val_if_fail(ZATHURA_IS_DATABASE(db) && file != NULL && file_info != NULL, false); - return ZATHURA_DATABASE_GET_INTERFACE(db)->set_fileinfo(db, file, page, offset, - scale, rotation); + return ZATHURA_DATABASE_GET_INTERFACE(db)->set_fileinfo(db, file, file_info); } bool -zathura_db_get_fileinfo(zathura_database_t* db, const char* file, unsigned int* - page, unsigned int* offset, double* scale, unsigned int* rotation) +zathura_db_get_fileinfo(zathura_database_t* db, const char* file, + zathura_fileinfo_t* file_info) { - g_return_val_if_fail(ZATHURA_IS_DATABASE(db) && file != NULL && page != NULL && - offset != NULL && scale != NULL && rotation != NULL, false); + g_return_val_if_fail(ZATHURA_IS_DATABASE(db) && file != NULL && file_info != NULL, false); - return ZATHURA_DATABASE_GET_INTERFACE(db)->get_fileinfo(db, file, page, offset, - scale, rotation); + return ZATHURA_DATABASE_GET_INTERFACE(db)->get_fileinfo(db, file, file_info); } diff --git a/database.h b/database.h index f1c2fac..d2cd624 100644 --- a/database.h +++ b/database.h @@ -9,6 +9,16 @@ #include "bookmarks.h" +typedef struct zathura_fileinfo_s { + unsigned int current_page; + unsigned int page_offset; + double scale; + unsigned int rotation; + unsigned int pages_per_row; + double position_x; + double position_y; +} zathura_fileinfo_t; + #define ZATHURA_TYPE_DATABASE \ (zathura_database_get_type ()) #define ZATHURA_DATABASE(obj) \ @@ -29,13 +39,12 @@ struct _ZathuraDatabaseInterface bool (*add_bookmark)(ZathuraDatabase* db, const char* file, zathura_bookmark_t* bookmark); bool (*remove_bookmark)(ZathuraDatabase* db, const char* file, const char* id); + girara_list_t* (*load_bookmarks)(ZathuraDatabase* db, const char* file); - bool (*set_fileinfo)(ZathuraDatabase* db, const char* file, unsigned - int page, unsigned int offset, double scale, unsigned int rotation); + bool (*set_fileinfo)(ZathuraDatabase* db, const char* file, zathura_fileinfo_t* file_info); - bool (*get_fileinfo)(ZathuraDatabase* db, const char* file, unsigned - int* page, unsigned int* offset, double* scale, unsigned int* rotation); + bool (*get_fileinfo)(ZathuraDatabase* db, const char* file, zathura_fileinfo_t* file_info); }; GType zathura_database_get_type(void); @@ -84,26 +93,20 @@ girara_list_t* zathura_db_load_bookmarks(zathura_database_t* db, const char* * * @param db The database instance * @param file The file to which the file info belongs to. - * @param page The last page. - * @param offset The last offset. - * @param scale The last scale. - * @param rotation The last rotation. + * @param file_info The file info * @return true on success, false otherwise. */ -bool zathura_db_set_fileinfo(zathura_database_t* db, const char* file, unsigned - int page, unsigned int offset, double scale, unsigned int rotation); +bool zathura_db_set_fileinfo(zathura_database_t* db, const char* file, + zathura_fileinfo_t* file_info); /* Get file info (last site, ...) from the database. * * @param db The database instance * @param file The file to which the file info belongs to. - * @param page The last page. - * @param offset The last offset. - * @param scale The last scale. - * @param rotation The rotation. + * @param file_info The file info * @return true on success, false otherwise. */ -bool zathura_db_get_fileinfo(zathura_database_t* db, const char* file, unsigned - int* page, unsigned int* offset, double* scale, unsigned int* rotation); +bool zathura_db_get_fileinfo(zathura_database_t* db, const char* file, + zathura_fileinfo_t* file_info); #endif // DATABASE_H diff --git a/document.c b/document.c index 6248b50..474d4b5 100644 --- a/document.c +++ b/document.c @@ -4,175 +4,481 @@ #define _XOPEN_SOURCE 700 // TODO: Implement realpath +#include #include #include #include #include -#include #include #include #include -#include "document.h" -#include "utils.h" -#include "zathura.h" -#include "render.h" -#include "database.h" -#include "page-widget.h" - #include #include #include #include #include +#include "document.h" +#include "utils.h" +#include "zathura.h" +#include "render.h" +#include "database.h" +#include "page.h" +#include "page-widget.h" +#include "plugin.h" + /** Read a most GT_MAX_READ bytes before falling back to file. */ static const size_t GT_MAX_READ = 1 << 16; +static const gchar* guess_type(const char* path); + /** - * Register document plugin + * Document */ -static bool zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin); - -void -zathura_document_plugins_load(zathura_t* zathura) +struct zathura_document_s { - GIRARA_LIST_FOREACH(zathura->plugins.path, char*, iter, plugindir) - /* read all files in the plugin directory */ - GDir* dir = g_dir_open(plugindir, 0, NULL); - if (dir == NULL) { - girara_error("could not open plugin directory: %s", plugindir); - girara_list_iterator_next(iter); - continue; + char* file_path; /**< File path of the document */ + const char* password; /**< Password of the document */ + unsigned int current_page_number; /**< Current page number */ + unsigned int number_of_pages; /**< Number of pages */ + double scale; /**< Scale value */ + unsigned int rotate; /**< Rotation */ + void* data; /**< Custom data */ + zathura_adjust_mode_t adjust_mode; /**< Adjust mode (best-fit, width) */ + unsigned int page_offset; /**< Page offset */ + + /** + * Document pages + */ + zathura_page_t** pages; + + /** + * Used plugin + */ + zathura_plugin_t* plugin; +}; + + +zathura_document_t* +zathura_document_open(zathura_plugin_manager_t* plugin_manager, const char* + path, const char* password, zathura_error_t* error) +{ + if (path == NULL) { + return NULL; + } + + if (g_file_test(path, G_FILE_TEST_EXISTS) == FALSE) { + girara_error("File '%s' does not exist", path); + return NULL; + } + + const gchar* content_type = guess_type(path); + if (content_type == NULL) { + girara_error("Could not determine file type."); + return NULL; + } + + /* determine real path */ + long path_max; +#ifdef PATH_MAX + path_max = PATH_MAX; +#else + path_max = pathconf(path,_PC_PATH_MAX); + if (path_max <= 0) + path_max = 4096; +#endif + + char* real_path = NULL; + zathura_document_t* document = NULL; + + real_path = malloc(sizeof(char) * path_max); + if (real_path == NULL) { + g_free((void*)content_type); + return NULL; + } + + if (realpath(path, real_path) == NULL) { + g_free((void*)content_type); + free(real_path); + return NULL; + } + + zathura_plugin_t* plugin = zathura_plugin_manager_get_plugin(plugin_manager, content_type); + g_free((void*)content_type); + + if (plugin == NULL) { + girara_error("unknown file type\n"); + goto error_free; + } + + document = g_malloc0(sizeof(zathura_document_t)); + + document->file_path = real_path; + document->password = password; + document->scale = 1.0; + document->plugin = plugin; + document->adjust_mode = ZATHURA_ADJUST_NONE; + + /* open document */ + if (plugin->functions.document_open == NULL) { + girara_error("plugin has no open function\n"); + goto error_free; + } + + zathura_error_t int_error = plugin->functions.document_open(document); + if (int_error != ZATHURA_ERROR_OK) { + if (error != NULL) { + *error = int_error; } - char* name = NULL; - while ((name = (char*) g_dir_read_name(dir)) != NULL) { - char* path = g_build_filename(plugindir, name, NULL); - if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == 0) { - girara_info("%s is not a regular file. Skipping.", path); - g_free(path); - continue; - } + girara_error("could not open document\n"); + goto error_free; + } - void* handle = NULL; - zathura_document_plugin_t* plugin = NULL; + /* read all pages */ + document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*)); + if (document->pages == NULL) { + goto error_free; + } - /* load plugin */ - handle = dlopen(path, RTLD_NOW); - if (handle == NULL) { - girara_error("could not load plugin %s (%s)", path, dlerror()); - g_free(path); - continue; - } - - /* resolve symbols and check API and ABI version*/ - zathura_plugin_api_version_t api_version; - *(void**)(&api_version) = dlsym(handle, PLUGIN_API_VERSION_FUNCTION); - if (api_version != NULL) { - if (api_version() != ZATHURA_API_VERSION) { - girara_error("plugin %s has been built againt zathura with a different API version (plugin: %d, zathura: %d)", - path, api_version(), ZATHURA_API_VERSION); - g_free(path); - dlclose(handle); - continue; - } - } else { -#if ZATHURA_API_VERSION == 1 - girara_warning("could not find '%s' function in plugin %s ... loading anyway", PLUGIN_API_VERSION_FUNCTION, path); -#else - girara_error("could not find '%s' function in plugin %s", PLUGIN_API_VERSION_FUNCTION, path); - g_free(path); - dlclose(handle); - continue; -#endif - } - - zathura_plugin_abi_version_t abi_version; - *(void**)(&abi_version) = dlsym(handle, PLUGIN_ABI_VERSION_FUNCTION); - if (abi_version != NULL) { - if (abi_version() != ZATHURA_ABI_VERSION) { - girara_error("plugin %s has been built againt zathura with a different ABI version (plugin: %d, zathura: %d)", - path, abi_version(), ZATHURA_ABI_VERSION); - g_free(path); - dlclose(handle); - continue; - } - } else { -#if ZATHURA_API_VERSION == 1 - girara_warning("could not find '%s' function in plugin %s ... loading anyway", PLUGIN_ABI_VERSION_FUNCTION, path); -#else - girara_error("could not find '%s' function in plugin %s", PLUGIN_ABI_VERSION_FUNCTION, path); - g_free(path); - dlclose(handle); - continue; -#endif - } - - zathura_plugin_register_service_t register_plugin; - *(void**)(®ister_plugin) = dlsym(handle, PLUGIN_REGISTER_FUNCTION); - - if (register_plugin == NULL) { - girara_error("could not find '%s' function in plugin %s", PLUGIN_REGISTER_FUNCTION, path); - g_free(path); - dlclose(handle); - continue; - } - - plugin = g_malloc0(sizeof(zathura_document_plugin_t)); - plugin->content_types = girara_list_new2(g_free); - plugin->handle = handle; - - register_plugin(plugin); - - bool r = zathura_document_plugin_register(zathura, plugin); - - if (r == false) { - girara_error("could not register plugin %s", path); - zathura_document_plugin_free(plugin); - } else { - girara_info("successfully loaded plugin %s", path); - } - - g_free(path); + for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { + zathura_page_t* page = zathura_page_new(document, page_id, NULL); + if (page == NULL) { + goto error_free; } - g_dir_close(dir); - GIRARA_LIST_FOREACH_END(zathura->plugins.path, char*, iter, plugindir); + + document->pages[page_id] = page; + } + + return document; + +error_free: + + free(real_path); + + if (document != NULL && document->pages != NULL) { + for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { + zathura_page_free(document->pages[page_id]); + } + + free(document->pages); + } + + g_free(document); + return NULL; +} + +zathura_error_t +zathura_document_free(zathura_document_t* document) +{ + if (document == NULL || document->plugin == NULL) { + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + /* free pages */ + for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { + zathura_page_free(document->pages[page_id]); + document->pages[page_id] = NULL; + } + + free(document->pages); + + /* free document */ + zathura_error_t error = ZATHURA_ERROR_OK; + if (document->plugin->functions.document_free == NULL) { + error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } else { + error = document->plugin->functions.document_free(document, document->data); + } + + if (document->file_path != NULL) { + free(document->file_path); + } + + g_free(document); + + return error; +} + +const char* +zathura_document_get_path(zathura_document_t* document) +{ + if (document == NULL) { + return NULL; + } + + return document->file_path; +} + +const char* +zathura_document_get_password(zathura_document_t* document) +{ + if (document == NULL) { + return NULL; + } + + return document->password; +} + +zathura_page_t* +zathura_document_get_page(zathura_document_t* document, unsigned int index) +{ + if (document == NULL || document->pages == NULL || (document->number_of_pages <= index)) { + return NULL; + } + + return document->pages[index]; +} + +void* +zathura_document_get_data(zathura_document_t* document) +{ + if (document == NULL) { + return NULL; + } + + return document->data; } void -zathura_document_plugin_free(zathura_document_plugin_t* plugin) +zathura_document_set_data(zathura_document_t* document, void* data) { - if (plugin == NULL) { + if (document == NULL) { return; } - dlclose(plugin->handle); - girara_list_free(plugin->content_types); - g_free(plugin); + document->data = data; } -static bool -zathura_document_plugin_register(zathura_t* zathura, zathura_document_plugin_t* new_plugin) +unsigned int +zathura_document_get_number_of_pages(zathura_document_t* document) { - if (new_plugin == NULL || new_plugin->content_types == NULL || new_plugin->open_function == NULL) { - girara_error("plugin: could not register\n"); - return false; + if (document == NULL) { + return 0; } - bool atleastone = false; - GIRARA_LIST_FOREACH(new_plugin->content_types, gchar*, iter, type) - if (!zathura_type_plugin_mapping_new(zathura, type, new_plugin)) { - girara_error("plugin: already registered for filetype %s\n", type); - } else { - atleastone = true; + return document->number_of_pages; +} + +void +zathura_document_set_number_of_pages(zathura_document_t* document, unsigned int number_of_pages) +{ + if (document == NULL) { + return; + } + + document->number_of_pages = number_of_pages; +} + +unsigned int +zathura_document_get_current_page_number(zathura_document_t* document) +{ + if (document == NULL) { + return 0; + } + + return document->current_page_number; +} + +void +zathura_document_set_current_page_number(zathura_document_t* document, unsigned int + current_page) +{ + if (document == NULL) { + return; + } + + document->current_page_number = current_page; +} + +double +zathura_document_get_scale(zathura_document_t* document) +{ + if (document == NULL) { + return 0; + } + + return document->scale; +} + +void +zathura_document_set_scale(zathura_document_t* document, double scale) +{ + if (document == NULL) { + return; + } + + document->scale = scale; +} + +unsigned int +zathura_document_get_rotation(zathura_document_t* document) +{ + if (document == NULL) { + return 0; + } + + return document->rotate; +} + +void +zathura_document_set_rotation(zathura_document_t* document, unsigned int rotation) +{ + if (document == NULL) { + return; + } + + document->rotate = rotation % 360; + + if (document->rotate > 0 && document->rotate <= 90) { + document->rotate = 90; + } else if (document->rotate > 0 && document->rotate <= 180) { + document->rotate = 180; + } else if (document->rotate > 0 && document->rotate <= 270) { + document->rotate = 270; + } else { + document->rotate = 0; + } +} + +zathura_adjust_mode_t +zathura_document_get_adjust_mode(zathura_document_t* document) +{ + if (document == NULL) { + return ZATHURA_ADJUST_NONE; + } + + return document->adjust_mode; +} + +void +zathura_document_set_adjust_mode(zathura_document_t* document, zathura_adjust_mode_t mode) +{ + if (document == NULL) { + return; + } + + if (mode == ZATHURA_ADJUST_BESTFIT || mode == ZATHURA_ADJUST_WIDTH) { + document->adjust_mode = mode; + } else { + document->adjust_mode = ZATHURA_ADJUST_NONE; + } +} + +unsigned int +zathura_document_get_page_offset(zathura_document_t* document) +{ + if (document == NULL) { + return 0; + } + + return document->page_offset; +} + +void +zathura_document_set_page_offset(zathura_document_t* document, unsigned int page_offset) +{ + if (document == NULL) { + return; + } + + if (page_offset < document->number_of_pages) { + document->page_offset = page_offset; + } +} + +zathura_error_t +zathura_document_save_as(zathura_document_t* document, const char* path) +{ + if (document == NULL || document->plugin == NULL || path == NULL) { + return ZATHURA_ERROR_UNKNOWN; + } + + if (document->plugin->functions.document_save_as == NULL) { + return ZATHURA_ERROR_NOT_IMPLEMENTED; + } + + return document->plugin->functions.document_save_as(document, document->data, path); +} + +girara_tree_node_t* +zathura_document_index_generate(zathura_document_t* document, zathura_error_t* error) +{ + if (document == NULL || document->plugin == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; } - GIRARA_LIST_FOREACH_END(new_plugin->content_types, gchar*, iter, type); - - if (atleastone) { - girara_list_append(zathura->plugins.plugins, new_plugin); + return NULL; } - return atleastone; + + if (document->plugin->functions.document_index_generate == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return document->plugin->functions.document_index_generate(document, document->data, error); +} + +girara_list_t* +zathura_document_attachments_get(zathura_document_t* document, zathura_error_t* error) +{ + if (document == NULL || document->plugin == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + if (document->plugin->functions.document_attachments_get == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return document->plugin->functions.document_attachments_get(document, document->data, error); +} + +zathura_error_t +zathura_document_attachment_save(zathura_document_t* document, const char* attachment, const char* file) +{ + if (document == NULL || document->plugin == NULL) { + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + if (document->plugin->functions.document_attachment_save == NULL) { + return ZATHURA_ERROR_NOT_IMPLEMENTED; + } + + return document->plugin->functions.document_attachment_save(document, document->data, attachment, file); +} + +girara_list_t* +zathura_document_get_information(zathura_document_t* document, zathura_error_t* error) +{ + if (document == NULL || document->plugin == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + if (document->plugin->functions.document_get_information == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + girara_list_t* result = document->plugin->functions.document_get_information(document, document->data, error); + if (result != NULL) { + girara_list_set_free_function(result, (girara_free_function_t) zathura_document_information_entry_free); + } + + return result; } static const gchar* @@ -251,637 +557,12 @@ guess_type(const char* path) return out; } -zathura_document_t* -zathura_document_open(zathura_t* zathura, const char* path, const char* password) +zathura_plugin_t* +zathura_document_get_plugin(zathura_document_t* document) { - if (path == NULL) { + if (document == NULL) { return NULL; } - if (g_file_test(path, G_FILE_TEST_EXISTS) == FALSE) { - girara_error("File '%s' does not exist", path); - return NULL; - } - - const gchar* content_type = guess_type(path); - if (content_type == NULL) { - girara_error("Could not determine file type."); - return NULL; - } - - /* determine real path */ - long path_max; -#ifdef PATH_MAX - path_max = PATH_MAX; -#else - path_max = pathconf(path,_PC_PATH_MAX); - if (path_max <= 0) - path_max = 4096; -#endif - - char* real_path = NULL; - zathura_document_t* document = NULL; - - real_path = malloc(sizeof(char) * path_max); - if (real_path == NULL) { - g_free((void*)content_type); - return NULL; - } - - if (realpath(path, real_path) == NULL) { - g_free((void*)content_type); - free(real_path); - return NULL; - } - - zathura_document_plugin_t* plugin = NULL; - GIRARA_LIST_FOREACH(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping) - if (g_content_type_equals(content_type, mapping->type)) { - plugin = mapping->plugin; - break; - } - GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping); - g_free((void*)content_type); - - if (plugin == NULL) { - girara_error("unknown file type\n"); - goto error_free; - } - - document = g_malloc0(sizeof(zathura_document_t)); - - document->file_path = real_path; - document->password = password; - document->scale = 1.0; - document->zathura = zathura; - - /* open document */ - if (plugin->open_function == NULL) { - girara_error("plugin has no open function\n"); - goto error_free; - } - - zathura_plugin_error_t error = plugin->open_function(document); - if (error != ZATHURA_PLUGIN_ERROR_OK) { - if (error == ZATHURA_PLUGIN_ERROR_INVALID_PASSWORD) { - zathura_password_dialog_info_t* password_dialog_info = malloc(sizeof(zathura_password_dialog_info_t)); - if (password_dialog_info != NULL) { - password_dialog_info->path = g_strdup(path); - password_dialog_info->zathura = zathura; - - if (path != NULL) { - girara_dialog(zathura->ui.session, "Enter password:", true, NULL, - (girara_callback_inputbar_activate_t) cb_password_dialog, password_dialog_info); - goto error_free; - } else { - free(password_dialog_info); - } - } - goto error_free; - } - - girara_error("could not open document\n"); - goto error_free; - } - - /* read history file */ - zathura_db_get_fileinfo(zathura->database, document->file_path, - &document->current_page_number, &document->page_offset, &document->scale, - &document->rotate); - - /* check for valid scale value */ - if (document->scale <= FLT_EPSILON) { - girara_warning("document info: '%s' has non positive scale", document->file_path); - document->scale = 1; - } - - /* check current page number */ - if (document->current_page_number > document->number_of_pages) { - girara_warning("document info: '%s' has an invalid page number", document->file_path); - document->current_page_number = 0; - } - - /* update statusbar */ - girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, real_path); - - /* read all pages */ - document->pages = calloc(document->number_of_pages, sizeof(zathura_page_t*)); - if (document->pages == NULL) { - goto error_free; - } - - for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { - zathura_page_t* page = zathura_page_get(document, page_id, NULL); - if (page == NULL) { - goto error_free; - } - - document->pages[page_id] = page; - } - - /* jump to first page if setting enabled */ - bool always_first_page = false; - girara_setting_get(zathura->ui.session, "open-first-page", &always_first_page); - if (always_first_page == true) { - document->current_page_number = 0; - } - - /* apply open adjustment */ - char* adjust_open = "best-fit"; - document->adjust_mode = ADJUST_BESTFIT; - if (girara_setting_get(zathura->ui.session, "adjust-open", &(adjust_open)) == true) { - if (g_strcmp0(adjust_open, "best-fit") == 0) { - document->adjust_mode = ADJUST_BESTFIT; - } else if (g_strcmp0(adjust_open, "width") == 0) { - document->adjust_mode = ADJUST_WIDTH; - } else { - document->adjust_mode = ADJUST_NONE; - } - g_free(adjust_open); - } - - return document; - -error_free: - - free(real_path); - - if (document != NULL && document->pages != NULL) { - for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { - zathura_page_free(document->pages[page_id]); - } - - free(document->pages); - } - - g_free(document); - return NULL; -} - -zathura_plugin_error_t -zathura_document_free(zathura_document_t* document) -{ - if (document == NULL || document->zathura == NULL || document->zathura->ui.session == NULL) { - return ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - - /* free pages */ - for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { - zathura_page_free(document->pages[page_id]); - document->pages[page_id] = NULL; - } - - free(document->pages); - - /* free document */ - zathura_plugin_error_t error = ZATHURA_PLUGIN_ERROR_OK; - if (document->functions.document_free == NULL) { - girara_notify(document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } else { - error = document->functions.document_free(document); - } - - if (document->file_path != NULL) { - free(document->file_path); - } - - g_free(document); - - return error; -} - -zathura_plugin_error_t -zathura_document_save_as(zathura_document_t* document, const char* path) -{ - if (document == NULL || path == NULL || document->zathura == NULL || document->zathura->ui.session == NULL) { - return ZATHURA_PLUGIN_ERROR_UNKNOWN; - } - - if (document->functions.document_save_as == NULL) { - girara_notify(document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - return ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - - return document->functions.document_save_as(document, path); -} - -girara_tree_node_t* -zathura_document_index_generate(zathura_document_t* document, zathura_plugin_error_t* error) -{ - if (document == NULL || document->zathura == NULL || document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (document->functions.document_index_generate == NULL) { - girara_notify(document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return document->functions.document_index_generate(document, error); -} - -girara_list_t* -zathura_document_attachments_get(zathura_document_t* document, zathura_plugin_error_t* error) -{ - if (document == NULL || document->zathura == NULL || document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (document->functions.document_attachments_get == NULL) { - girara_notify(document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return document->functions.document_attachments_get(document, error); -} - -zathura_plugin_error_t -zathura_document_attachment_save(zathura_document_t* document, const char* attachment, const char* file) -{ - if (document == NULL || document->zathura == NULL || document->zathura->ui.session == NULL) { - return ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - - if (document->functions.document_attachment_save == NULL) { - girara_notify(document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - return ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - - return document->functions.document_attachment_save(document, attachment, file); -} - -char* -zathura_document_meta_get(zathura_document_t* document, zathura_document_meta_t meta, zathura_plugin_error_t* error) -{ - if (document == NULL || document->zathura == NULL || document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (document->functions.document_meta_get == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - girara_notify(document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - return NULL; - } - - return document->functions.document_meta_get(document, meta, error); -} - -zathura_page_t* -zathura_page_get(zathura_document_t* document, unsigned int page_id, zathura_plugin_error_t* error) -{ - if (document == NULL || document->zathura == NULL || document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (document->functions.page_get == NULL) { - girara_notify(document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - zathura_page_t* page = document->functions.page_get(document, page_id, error); - - if (page != NULL) { - page->number = page_id; - page->visible = false; - page->drawing_area = zathura_page_widget_new(page); - if (page->drawing_area == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_UNKNOWN; - } - girara_error("Couldn't create page widget"); - zathura_page_free(page); - return NULL; - } - - page->document = document; - - unsigned int page_height = 0; - unsigned int page_width = 0; - page_calc_height_width(page, &page_height, &page_width, true); - - gtk_widget_set_size_request(page->drawing_area, page_width, page_height); - } - - return page; -} - -zathura_plugin_error_t -zathura_page_free(zathura_page_t* page) -{ - if (page == NULL || page->document == NULL || page->document->zathura == NULL || page->document->zathura->ui.session == NULL) { - return ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - - if (page->document->functions.page_free == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - return ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - - return page->document->functions.page_free(page); -} - -girara_list_t* -zathura_page_search_text(zathura_page_t* page, const char* text, zathura_plugin_error_t* error) -{ - if (page == NULL || page->document == NULL || text == NULL || - page->document->zathura == NULL || page->document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (page->document->functions.page_search_text == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return page->document->functions.page_search_text(page, text, error); -} - -girara_list_t* -zathura_page_links_get(zathura_page_t* page, zathura_plugin_error_t* error) -{ - if (page == NULL || page->document == NULL || page->document->zathura == NULL - || page->document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (page->document->functions.page_links_get == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return page->document->functions.page_links_get(page, error); -} - -zathura_plugin_error_t -zathura_page_links_free(girara_list_t* UNUSED(list)) -{ - return false; -} - -girara_list_t* -zathura_page_form_fields_get(zathura_page_t* page, zathura_plugin_error_t* error) -{ - if (page == NULL || page->document == NULL || page->document->zathura == NULL - || page->document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (page->document->functions.page_form_fields_get == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return page->document->functions.page_form_fields_get(page, error); -} - -zathura_plugin_error_t -zathura_page_form_fields_free(girara_list_t* UNUSED(list)) -{ - return ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; -} - -girara_list_t* -zathura_page_images_get(zathura_page_t* page, zathura_plugin_error_t* error) -{ - if (page == NULL || page->document == NULL || page->document->zathura == NULL - || page->document->zathura->ui.session == NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (page->document->functions.page_images_get == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return page->document->functions.page_images_get(page, error); -} - -cairo_surface_t* -zathura_page_image_get_cairo(zathura_page_t* page, zathura_image_t* image, zathura_plugin_error_t* error) -{ - if (page == NULL || page->document == NULL || image == NULL || - page->document->zathura == NULL || page->document->zathura->ui.session == - NULL) { - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (page->document->functions.page_image_get_cairo == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error != NULL) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return page->document->functions.page_image_get_cairo(page, image, error); -} - -char* zathura_page_get_text(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_plugin_error_t* error) -{ - if (page == NULL || page->document == NULL || page->document->zathura == NULL || page->document->zathura->ui.session == NULL) { - if (error) { - *error = ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - return NULL; - } - - if (page->document->functions.page_get_text == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - if (error) { - *error = ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - return NULL; - } - - return page->document->functions.page_get_text(page, rectangle, error); -} - -zathura_plugin_error_t -zathura_page_render(zathura_page_t* page, cairo_t* cairo, bool printing) -{ - if (page == NULL || page->document == NULL || cairo == NULL || - page->document->zathura == NULL || page->document->zathura->ui.session == - NULL) { - return ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS; - } - - if (page->document->functions.page_render_cairo == NULL) { - girara_notify(page->document->zathura->ui.session, GIRARA_WARNING, _("%s not implemented"), __FUNCTION__); - girara_error("%s not implemented", __FUNCTION__); - return ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED; - } - - return page->document->functions.page_render_cairo(page, cairo, printing); -} - -zathura_index_element_t* -zathura_index_element_new(const char* title) -{ - if (title == NULL) { - return NULL; - } - - zathura_index_element_t* res = g_malloc0(sizeof(zathura_index_element_t)); - - res->title = g_strdup(title); - - return res; -} - -void -zathura_index_element_free(zathura_index_element_t* index) -{ - if (index == NULL) { - return; - } - - g_free(index->title); - - if (index->type == ZATHURA_LINK_EXTERNAL) { - g_free(index->target.uri); - } - - g_free(index); -} - -zathura_image_buffer_t* -zathura_image_buffer_create(unsigned int width, unsigned int height) -{ - zathura_image_buffer_t* image_buffer = malloc(sizeof(zathura_image_buffer_t)); - - if (image_buffer == NULL) { - return NULL; - } - - image_buffer->data = calloc(width * height * 3, sizeof(unsigned char)); - - if (image_buffer->data == NULL) { - free(image_buffer); - return NULL; - } - - image_buffer->width = width; - image_buffer->height = height; - image_buffer->rowstride = width * 3; - - return image_buffer; -} - -void -zathura_image_buffer_free(zathura_image_buffer_t* image_buffer) -{ - if (image_buffer == NULL) { - return; - } - - free(image_buffer->data); - free(image_buffer); -} - -bool -zathura_type_plugin_mapping_new(zathura_t* zathura, const gchar* type, zathura_document_plugin_t* plugin) -{ - g_return_val_if_fail(zathura && type && plugin, false); - - GIRARA_LIST_FOREACH(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping) - if (g_content_type_equals(type, mapping->type)) { - girara_list_iterator_free(iter); - return false; - } - GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping); - - zathura_type_plugin_mapping_t* mapping = g_malloc(sizeof(zathura_type_plugin_mapping_t)); - mapping->type = g_strdup(type); - mapping->plugin = plugin; - girara_list_append(zathura->plugins.type_plugin_mapping, mapping); - return true; -} - -void -zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping) -{ - if (mapping == NULL) { - return; - } - - g_free((void*)mapping->type); - g_free(mapping); -} - -void -zathura_link_free(zathura_link_t* link) -{ - if (link == NULL) { - return; - } - - if (link->type == ZATHURA_LINK_EXTERNAL) { - g_free(link->target.value); - } - g_free(link); + return document->plugin; } diff --git a/document.h b/document.h index 05c2280..b72e4ac 100644 --- a/document.h +++ b/document.h @@ -3,419 +3,202 @@ #ifndef DOCUMENT_H #define DOCUMENT_H -#include -#include #include - #include -#include "zathura.h" -#include "version.h" -#define PLUGIN_REGISTER_FUNCTION "plugin_register" -#define PLUGIN_API_VERSION_FUNCTION "plugin_api_version" -#define PLUGIN_ABI_VERSION_FUNCTION "plugin_abi_version" - -/** - * Register a plugin. - * - * @param plugin_name the name of the plugin - * @param major the plugin's major version - * @param minor the plugin's minor version - * @param rev the plugin's revision - * @param plugin_open_function the plugin's open function - * @param mimetypes a char array of mime types supported by the plugin - */ -#define PLUGIN_REGISTER(plugin_name, major, minor, rev, plugin_open_function, mimetypes) \ - unsigned int plugin_version_major() { return major; } \ - unsigned int plugin_version_minor() { return minor; } \ - unsigned int plugin_version_revision() { return rev; } \ - unsigned int plugin_api_version() { return ZATHURA_API_VERSION; } \ - unsigned int plugin_abi_version() { return ZATHURA_ABI_VERSION; } \ - \ - void plugin_register(zathura_document_plugin_t* plugin) \ - { \ - if (plugin == NULL) { \ - return; \ - } \ - plugin->open_function = (plugin_open_function); \ - static const char* mime_types[] = mimetypes; \ - for (size_t s = 0; s != sizeof(mime_types) / sizeof(const char*); ++s) { \ - girara_list_append(plugin->content_types, g_content_type_from_mime_type(mime_types[s])); \ - } \ - } \ - -#define PLUGIN_MIMETYPES(...) __VA_ARGS__ - -/** - * Error types for plugins - */ -typedef enum zathura_plugin_error_e -{ - ZATHURA_PLUGIN_ERROR_OK, /**< No error occured */ - ZATHURA_PLUGIN_ERROR_UNKNOWN, /**< An unknown error occured */ - ZATHURA_PLUGIN_ERROR_OUT_OF_MEMORY, /**< Out of memory */ - ZATHURA_PLUGIN_ERROR_NOT_IMPLEMENTED, /**< The called function has not been implemented */ - ZATHURA_PLUGIN_ERROR_INVALID_ARGUMENTS, /**< Invalid arguments have been passed */ - ZATHURA_PLUGIN_ERROR_INVALID_PASSWORD /**< The provided password is invalid */ -} zathura_plugin_error_t; - -/** - * Document open function - * - * @param document The document - * @return true if no error occured otherwise false - */ -typedef zathura_plugin_error_t (*zathura_document_open_t)(zathura_document_t* document); - -/** - * Document plugin structure - */ -typedef struct zathura_document_plugin_s -{ - girara_list_t* content_types; /**< List of supported content types */ - zathura_document_open_t open_function; /**< Document open function */ - void* handle; /**< DLL handle */ -} zathura_document_plugin_t; - -/** - * Plugin mapping - */ -typedef struct zathura_type_plugin_mapping_s -{ - const gchar* type; /**< Plugin type */ - zathura_document_plugin_t* plugin; /**< Mapped plugin */ -} zathura_type_plugin_mapping_t; - -/** - * Meta data entries - */ -typedef enum zathura_document_meta_e -{ - ZATHURA_DOCUMENT_TITLE, /**< Title of the document */ - ZATHURA_DOCUMENT_AUTHOR, /**< Author of the document */ - ZATHURA_DOCUMENT_SUBJECT, /**< Subject of the document */ - ZATHURA_DOCUMENT_KEYWORDS, /**< Keywords of the document */ - ZATHURA_DOCUMENT_CREATOR, /**< Creator of the document */ - ZATHURA_DOCUMENT_PRODUCER, /**< Producer of the document */ - ZATHURA_DOCUMENT_CREATION_DATE, /**< Creation data */ - ZATHURA_DOCUMENT_MODIFICATION_DATE /**< Modification data */ -} zathura_document_meta_t; - -typedef struct zathura_password_dialog_info_s -{ - char* path; /**< Path to the file */ - zathura_t* zathura; /**< Zathura session */ -} zathura_password_dialog_info_t; - -/** - * Function prototype that is called to register a document plugin - * - * @param The document plugin - */ -typedef void (*zathura_plugin_register_service_t)(zathura_document_plugin_t*); - -/** - * Function prototype that is called to get the plugin's API version. - * - * @return plugin's API version - */ -typedef unsigned int (*zathura_plugin_api_version_t)(); - -/** - * Function prototype that is called to get the ABI version the plugin is built - * against. - * - * @return plugin's ABI version - */ -typedef unsigned int (*zathura_plugin_abi_version_t)(); - -/** - * Image buffer - */ -typedef struct zathura_image_buffer_s -{ - unsigned char* data; /**< Image buffer data */ - unsigned int height; /**< Height of the image */ - unsigned int width; /**< Width of the image */ - unsigned int rowstride; /**< Rowstride of the image */ -} zathura_image_buffer_t; - -/** - * Creates an image buffer - * - * @param width Width of the image stored in the buffer - * @param height Height of the image stored in the buffer - * @return Image buffer or NULL if an error occured - */ -zathura_image_buffer_t* zathura_image_buffer_create(unsigned int width, unsigned int height); - -/** - * Frees the image buffer - * - * @param buffer The image buffer - */ -void zathura_image_buffer_free(zathura_image_buffer_t* buffer); - -/** - * Rectangle structure. - * The coordinate system has its origin in the left upper corner. The x axes - * goes to the right, the y access goes down. - */ -typedef struct zathura_rectangle_s -{ - double x1; /**< X coordinate of point 1 */ - double y1; /**< Y coordinate of point 1 */ - double x2; /**< X coordinate of point 2 */ - double y2; /**< Y coordinate of point 2 */ -} zathura_rectangle_t; - -/** - * Image structure - */ -typedef struct zathura_image_s -{ - zathura_rectangle_t position; /**< Coordinates of the image */ - void* data; /**< Custom data of the plugin */ -} zathura_image_t; - -/** - * Possible link types - */ -typedef enum zathura_link_type_e -{ - ZATHURA_LINK_TO_PAGE, /**< Links to a page */ - ZATHURA_LINK_EXTERNAL, /**< Links to an external source */ -} zathura_link_type_t; - -/** - * Link - */ -typedef struct zathura_link_s -{ - zathura_rectangle_t position; /**< Position of the link */ - zathura_link_type_t type; /**< Link type */ - union - { - unsigned int page_number; /**< Page number */ - char* value; /**< Value */ - } target; -} zathura_link_t; - -/** - * Index element - */ -typedef struct zathura_index_element_s -{ - char* title; /**< Title of the element */ - zathura_link_type_t type; /**< Type */ - union - { - unsigned int page_number; /**< Page number */ - char* uri; /**< Uri */ - } target; -} zathura_index_element_t; - -/** - * Form type - */ -typedef enum zathura_form_type_e -{ - ZATHURA_FORM_CHECKBOX, /**< Checkbox */ - ZATHURA_FORM_TEXTFIELD /**< Textfield */ -} zathura_form_type_t; - -/** - * Form element - */ -typedef struct zathura_form_s -{ - zathura_rectangle_t position; /**< Position */ - zathura_form_type_t type; /**< Type */ -} zathura_form_t; - -/** - * Page - */ -struct zathura_page_s -{ - double height; /**< Page height */ - double width; /**< Page width */ - unsigned int number; /**< Page number */ - zathura_document_t* document; /**< Document */ - void* data; /**< Custom data */ - bool visible; /**< Page is visible */ - GtkWidget* drawing_area; /**< Drawing area */ -}; - -/** - * Document - */ -struct zathura_document_s -{ - char* file_path; /**< File path of the document */ - const char* password; /**< Password of the document */ - unsigned int current_page_number; /**< Current page number */ - unsigned int number_of_pages; /**< Number of pages */ - double scale; /**< Scale value */ - unsigned int rotate; /**< Rotation */ - void* data; /**< Custom data */ - zathura_t* zathura; /** Zathura object */ - int adjust_mode; /**< Adjust mode (best-fit, width) */ - unsigned int page_offset; /**< Page offset */ - - struct - { - /** - * Frees the document - */ - zathura_plugin_error_t (*document_free)(zathura_document_t* document); - - /** - * Generates the document index - */ - girara_tree_node_t* (*document_index_generate)(zathura_document_t* document, zathura_plugin_error_t* error); - - /** - * Save the document - */ - zathura_plugin_error_t (*document_save_as)(zathura_document_t* document, const char* path); - - /** - * Get list of attachments - */ - girara_list_t* (*document_attachments_get)(zathura_document_t* document, zathura_plugin_error_t* error); - - /** - * Save attachment to a file - */ - zathura_plugin_error_t (*document_attachment_save)(zathura_document_t* document, const char* attachment, const char* file); - - /** - * Get document information - */ - char* (*document_meta_get)(zathura_document_t* document, zathura_document_meta_t info, zathura_plugin_error_t* error); - - /** - * Gets the page object - */ - zathura_page_t* (*page_get)(zathura_document_t* document, unsigned int page_id, zathura_plugin_error_t* error); - - /** - * Search text - */ - girara_list_t* (*page_search_text)(zathura_page_t* page, const char* text, zathura_plugin_error_t* error); - - /** - * Get links on a page - */ - girara_list_t* (*page_links_get)(zathura_page_t* page, zathura_plugin_error_t* error); - - /** - * Get form fields - */ - girara_list_t* (*page_form_fields_get)(zathura_page_t* page, zathura_plugin_error_t* error); - - /** - * Get list of images - */ - girara_list_t* (*page_images_get)(zathura_page_t* page, zathura_plugin_error_t* error); - - /** - * Get the image - */ - cairo_surface_t* (*page_image_get_cairo)(zathura_page_t* page, zathura_image_t* image, zathura_plugin_error_t* error); - - /** - * Get text for selection - */ - char* (*page_get_text)(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_plugin_error_t* error); - - /** - * Renders the page - */ - zathura_image_buffer_t* (*page_render)(zathura_page_t* page, zathura_plugin_error_t* error); - - /** - * Renders the page - */ - zathura_plugin_error_t (*page_render_cairo)(zathura_page_t* page, cairo_t* cairo, bool printing); - - /** - * Free page - */ - zathura_plugin_error_t (*page_free)(zathura_page_t* page); - } functions; - - /** - * Document pages - */ - zathura_page_t** pages; -}; - -/** - * Load all document plugins - * - * @param zathura the zathura session - */ -void zathura_document_plugins_load(zathura_t* zathura); - -/** - * Free a document plugin - * - * @param plugin The plugin - */ -void zathura_document_plugin_free(zathura_document_plugin_t* plugin); +#include "types.h" /** * Open the document * - * @param zathura Zathura object + * @param plugin_manager The plugin manager * @param path Path to the document * @param password Password of the document or NULL + * @param error Optional error parameter * @return The document object */ -zathura_document_t* zathura_document_open(zathura_t* zathura, const char* path, - const char* password); +zathura_document_t* zathura_document_open(zathura_plugin_manager_t* + plugin_manager, const char* path, const char* password, zathura_error_t* + error); /** * Free the document * * @param document - * @return ZATHURA_PLUGIN_ERROR_OK when no error occured, otherwise see - * zathura_plugin_error_t + * @return ZATHURA_ERROR_OK when no error occured, otherwise see + * zathura_error_t */ -zathura_plugin_error_t zathura_document_free(zathura_document_t* document); +zathura_error_t zathura_document_free(zathura_document_t* document); + +/** + * Returns the path of the document + * + * @param document The document + * @return The file path of the document + */ +const char* zathura_document_get_path(zathura_document_t* document); + +/** + * Returns the password of the document + * + * @param document The document + * @return Returns the password of the document + */ +const char* zathura_document_get_password(zathura_document_t* document); + +/** + * Returns the page at the given index + * + * @param document The document + * @param index The index of the page + * @return The page or NULL if an error occured + */ +zathura_page_t* zathura_document_get_page(zathura_document_t* document, unsigned int index); + +/** + * Returns the number of pages + * + * @param document The document + * @return Number of pages + */ +unsigned int zathura_document_get_number_of_pages(zathura_document_t* document); + +/** + * Sets the number of pages + * + * @param document The document + * @param number_of_pages Number of pages + */ +void zathura_document_set_number_of_pages(zathura_document_t* document, unsigned + int number_of_pages); + +/** + * Returns the current page number + * + * @param document The document + * @return Current page + */ +unsigned int zathura_document_get_current_page_number(zathura_document_t* document); + +/** + * Sets the number of pages + * + * @param document The document + * @param current_page The current page number + */ +void zathura_document_set_current_page_number(zathura_document_t* document, unsigned + int current_page); + +/** + * Returns the current scale value of the document + * + * @param document The document + * @return The current scale value + */ +double zathura_document_get_scale(zathura_document_t* document); + +/** + * Sets the new scale value of the document + * + * @param document The document + * @param scale The new scale value + */ +void zathura_document_set_scale(zathura_document_t* document, double scale); + +/** + * Returns the rotation value of zathura (0..360) + * + * @param document The document + * @return The current rotation value + */ +unsigned int zathura_document_get_rotation(zathura_document_t* document); + +/** + * Sets the new rotation value + * + * @param document The document + * @param rotation The new rotation value + */ +void zathura_document_set_rotation(zathura_document_t* document, unsigned int rotation); + +/** + * Returns the adjust mode of the document + * + * @param document The document + * @return The adjust mode + */ +zathura_adjust_mode_t zathura_document_get_adjust_mode(zathura_document_t* document); + +/** + * Sets the new adjust mode of the document + * + * @param document The document + * @param mode The new adjust mode + */ +void zathura_document_set_adjust_mode(zathura_document_t* document, zathura_adjust_mode_t mode); + +/** + * Returns the page offset of the document + * + * @param document The document + * @return The page offset + */ +unsigned int zathura_document_get_page_offset(zathura_document_t* document); + +/** + * Sets the new page offset of the document + * + * @param document The document + * @param page_offset The new page offset + */ +void zathura_document_set_page_offset(zathura_document_t* document, unsigned int page_offset); + +/** + * Returns the private data of the document + * + * @param document The document + * @return The private data or NULL + */ +void* zathura_document_get_data(zathura_document_t* document); + +/** + * Sets the private data of the document + * + * @param document The document + * @param data The new private data + */ +void zathura_document_set_data(zathura_document_t* document, void* data); /** * Save the document * * @param document The document object * @param path Path for the saved file - * @return ZATHURA_PLUGIN_ERROR_OK when no error occured, otherwise see - * zathura_plugin_error_t + * @return ZATHURA_ERROR_OK when no error occured, otherwise see + * zathura_error_t */ -zathura_plugin_error_t zathura_document_save_as(zathura_document_t* document, const char* path); +zathura_error_t zathura_document_save_as(zathura_document_t* document, const char* path); /** * Generate the document index * * @param document The document object - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an + * @param error Set to an error value (see \ref zathura_error_t) if an * error occured * @return Generated index */ -girara_tree_node_t* zathura_document_index_generate(zathura_document_t* document, zathura_plugin_error_t* error); +girara_tree_node_t* zathura_document_index_generate(zathura_document_t* document, zathura_error_t* error); /** * Get list of attachments * * @param document The document object - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an + * @param error Set to an error value (see \ref zathura_error_t) if an * error occured * @return List of attachments */ -girara_list_t* zathura_document_attachments_get(zathura_document_t* document, zathura_plugin_error_t* error); +girara_list_t* zathura_document_attachments_get(zathura_document_t* document, zathura_error_t* error); /** * Save document attachment @@ -423,169 +206,19 @@ girara_list_t* zathura_document_attachments_get(zathura_document_t* document, za * @param document The document objects * @param attachment name of the attachment * @param file the target filename - * @return ZATHURA_PLUGIN_ERROR_OK when no error occured, otherwise see - * zathura_plugin_error_t + * @return ZATHURA_ERROR_OK when no error occured, otherwise see + * zathura_error_t */ -zathura_plugin_error_t zathura_document_attachment_save(zathura_document_t* document, const char* attachment, const char* file); +zathura_error_t zathura_document_attachment_save(zathura_document_t* document, const char* attachment, const char* file); /** * Returns a string of the requested information * * @param document The zathura document - * @param meta The information field - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an + * @param error Set to an error value (see \ref zathura_error_t) if an * error occured - * @return String or NULL if information could not be retreived + * @return List of document information entries or NULL if information could not be retreived */ -char* zathura_document_meta_get(zathura_document_t* document, zathura_document_meta_t meta, zathura_plugin_error_t* error); - -/** - * Get the page object - * - * @param document The document - * @param page_id Page number - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an - * error occured - * @return Page object or NULL if an error occured - */ -zathura_page_t* zathura_page_get(zathura_document_t* document, unsigned int page_id, zathura_plugin_error_t* error); - -/** - * Frees the page object - * - * @param page The page object - * @return ZATHURA_PLUGIN_ERROR_OK when no error occured, otherwise see - * zathura_plugin_error_t - */ -zathura_plugin_error_t zathura_page_free(zathura_page_t* page); - -/** - * Search page - * - * @param page The page object - * @param text Search item - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an - * error occured - * @return List of results - */ -girara_list_t* zathura_page_search_text(zathura_page_t* page, const char* text, zathura_plugin_error_t* error); - -/** - * Get page links - * - * @param page The page object - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an - * error occured - * @return List of links - */ -girara_list_t* zathura_page_links_get(zathura_page_t* page, zathura_plugin_error_t* error); - -/** - * Free page links - * - * @param list List of links - * @return ZATHURA_PLUGIN_ERROR_OK when no error occured, otherwise see - * zathura_plugin_error_t - */ -zathura_plugin_error_t zathura_page_links_free(girara_list_t* list); - -/** - * Get list of form fields - * - * @param page The page object - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an - * error occured - * @return List of form fields - */ -girara_list_t* zathura_page_form_fields_get(zathura_page_t* page, zathura_plugin_error_t* error); - -/** - * Free list of form fields - * - * @param list List of form fields - * @return ZATHURA_PLUGIN_ERROR_OK when no error occured, otherwise see - * zathura_plugin_error_t - */ -zathura_plugin_error_t zathura_page_form_fields_free(girara_list_t* list); - -/** - * Get list of images - * - * @param page Page - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an - * error occured - * @return List of images or NULL if an error occured - */ -girara_list_t* zathura_page_images_get(zathura_page_t* page, zathura_plugin_error_t* error); - -/** - * Get image - * - * @param page Page - * @param image Image identifier - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an - * error occured - * @return The cairo image surface or NULL if an error occured - */ -cairo_surface_t* zathura_page_image_get_cairo(zathura_page_t* page, zathura_image_t* image, zathura_plugin_error_t* error); - -/** - * Get text for selection - * @param page Page - * @param rectangle Selection - * @param error Set to an error value (see \ref zathura_plugin_error_t) if an error - * occured - * @return The selected text (needs to be deallocated with g_free) - */ -char* zathura_page_get_text(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_plugin_error_t* error); - -/** - * Render page - * - * @param page The page object - * @param cairo Cairo object - * @param printing render for printing - * @return ZATHURA_PLUGIN_ERROR_OK when no error occured, otherwise see - * zathura_plugin_error_t - */ -zathura_plugin_error_t zathura_page_render(zathura_page_t* page, cairo_t* cairo, bool printing); - -/** - * Create new index element - * - * @param title Title of the index element - * @return Index element - */ -zathura_index_element_t* zathura_index_element_new(const char* title); - -/** - * Free index element - * - * @param index The index element - */ -void zathura_index_element_free(zathura_index_element_t* index); - -/** - * Free link - * - * @param link The link - */ -void zathura_link_free(zathura_link_t* link); - -/** - * Add type -> plugin mapping - * @param zathura zathura instance - * @param type content type - * @param plugin plugin instance - * @return true on success, false if another plugin is already registered for - * that type - */ -bool zathura_type_plugin_mapping_new(zathura_t* zathura, const gchar* type, zathura_document_plugin_t* plugin); - -/** - * Free type -> plugin mapping - * @param mapping To be freed - */ -void zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping); +girara_list_t* zathura_document_get_information(zathura_document_t* document, zathura_error_t* error); #endif // DOCUMENT_H diff --git a/internal.h b/internal.h new file mode 100644 index 0000000..4ca2fac --- /dev/null +++ b/internal.h @@ -0,0 +1,32 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef INTERNAL_H +#define INTERNAL_H + +#include "zathura.h" +#include "plugin.h" + +/** + * Zathura password dialog + */ +typedef struct zathura_password_dialog_info_s +{ + char* path; /**< Path to the file */ + zathura_t* zathura; /**< Zathura session */ +} zathura_password_dialog_info_t; + +struct zathura_document_information_entry_s +{ + zathura_document_information_type_t type; /**< Type of the information */ + char* value; /**< Value */ +}; + +/** + * Returns the associated plugin + * + * @param document The document + * @return The plugin or NULL + */ +zathura_plugin_t* zathura_document_get_plugin(zathura_document_t* document); + +#endif // INTERNAL_H diff --git a/links.c b/links.c new file mode 100644 index 0000000..a43e84f --- /dev/null +++ b/links.c @@ -0,0 +1,223 @@ +/* See LICENSE file for license and copyright information */ + +#include +#include +#include +#include + +#include "links.h" +#include "zathura.h" +#include "document.h" +#include "utils.h" + +struct zathura_link_s +{ + zathura_rectangle_t position; /**< Position of the link */ + zathura_link_type_t type; /**< Link type */ + zathura_link_target_t target; /**< Link target */ +}; + +/* forward declarations */ +static void link_remote(zathura_t* zathura, const char* file); +static void link_launch(zathura_t* zathura, zathura_link_t* link); + +zathura_link_t* +zathura_link_new(zathura_link_type_t type, zathura_rectangle_t position, + zathura_link_target_t target) +{ + zathura_link_t* link = g_malloc0(sizeof(zathura_link_t)); + + link->type = type; + link->position = position; + + switch (type) { + case ZATHURA_LINK_GOTO_DEST: + link->target = target; + + if (target.value != NULL) { + link->target.value = g_strdup(target.value); + } + break; + case ZATHURA_LINK_GOTO_REMOTE: + case ZATHURA_LINK_URI: + case ZATHURA_LINK_LAUNCH: + case ZATHURA_LINK_NAMED: + if (target.value == NULL) { + g_free(link); + return NULL; + } + + link->target.value = g_strdup(target.value); + break; + default: + g_free(link); + return NULL; + } + + return link; +} + +void +zathura_link_free(zathura_link_t* link) +{ + if (link == NULL) { + return; + } + + switch (link->type) { + case ZATHURA_LINK_GOTO_DEST: + case ZATHURA_LINK_GOTO_REMOTE: + case ZATHURA_LINK_URI: + case ZATHURA_LINK_LAUNCH: + case ZATHURA_LINK_NAMED: + if (link->target.value != NULL) { + g_free(link->target.value); + } + break; + default: + break; + } + + g_free(link); +} + +zathura_link_type_t +zathura_link_get_type(zathura_link_t* link) +{ + if (link == NULL) { + return ZATHURA_LINK_INVALID; + } + + return link->type; +} + +zathura_rectangle_t +zathura_link_get_position(zathura_link_t* link) +{ + if (link == NULL) { + zathura_rectangle_t position = { 0, 0, 0, 0 }; + return position; + } + + return link->position; +} + +zathura_link_target_t +zathura_link_get_target(zathura_link_t* link) +{ + if (link == NULL) { + zathura_link_target_t target = { 0 }; + return target; + } + + return link->target; +} + +void +zathura_link_evaluate(zathura_t* zathura, zathura_link_t* link) +{ + if (zathura == NULL || zathura->document == NULL || link == NULL) { + return; + } + + switch (link->type) { + case ZATHURA_LINK_GOTO_DEST: + switch (link->target.destination_type) { + case ZATHURA_LINK_DESTINATION_XYZ: { + if (link->target.scale != 0) { + zathura_document_set_scale(zathura->document, link->target.scale); + } + + /* get page */ + zathura_page_t* page = zathura_document_get_page(zathura->document, + link->target.page_number); + if (page == NULL) { + return; + } + + /* get page offset */ + page_offset_t offset; + page_calculate_offset(zathura, page, &offset); + + if (link->target.left != -1) { + offset.x += link->target.left * zathura_document_get_scale(zathura->document); + } + + if (link->target.top != -1) { + offset.y += link->target.top * zathura_document_get_scale(zathura->document); + } + + position_set_delayed(zathura, offset.x, offset.y); + } + break; + default: + break; + } + break; + case ZATHURA_LINK_GOTO_REMOTE: + link_remote(zathura, link->target.value); + break; + case ZATHURA_LINK_URI: + if (girara_xdg_open(link->target.value) == false) { + girara_notify(zathura->ui.session, GIRARA_ERROR, _("Failed to run xdg-open.")); + } + break; + case ZATHURA_LINK_LAUNCH: + link_launch(zathura, link); + break; + default: + break; + } +} + +static void +link_remote(zathura_t* zathura, const char* file) +{ + if (zathura == NULL || file == NULL || zathura->document == NULL) { + return; + } + + const char* path = zathura_document_get_path(zathura->document); + char* dir = g_path_get_dirname(path); + char* uri = g_build_filename(dir, file, NULL); + + char* argv[] = { + *(zathura->global.arguments), + uri, + NULL + }; + + g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); + + g_free(uri); + g_free(dir); +} + +static void +link_launch(zathura_t* zathura, zathura_link_t* link) +{ + if (zathura == NULL || link == NULL || zathura->document == NULL) { + return; + } + + /* get file path */ + if (link->target.value == NULL) { + return; + }; + + char* path = NULL; + if (g_path_is_absolute(link->target.value) == TRUE) { + path = g_strdup(link->target.value); + } else { + const char* document = zathura_document_get_path(zathura->document); + char* dir = g_path_get_dirname(document); + path = g_build_filename(dir, link->target.value, NULL); + g_free(dir); + } + + if (girara_xdg_open(path) == false) { + girara_notify(zathura->ui.session, GIRARA_ERROR, _("Failed to run xdg-open.")); + } + + g_free(path); +} diff --git a/links.h b/links.h new file mode 100644 index 0000000..3dbf8df --- /dev/null +++ b/links.h @@ -0,0 +1,59 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef LINK_H +#define LINK_H + +#include "types.h" + +/** + * Creates a new zathura link + * + * @param type Type of the link + * @param position Position of the link + * @param target Target + * @return New zathura link + */ +zathura_link_t* +zathura_link_new(zathura_link_type_t type, zathura_rectangle_t position, + zathura_link_target_t target); + +/** + * Free link + * + * @param link The link + */ +void zathura_link_free(zathura_link_t* link); + +/** + * Returns the type of the link + * + * @param link The link + * @return The target type of the link + */ +zathura_link_type_t zathura_link_get_type(zathura_link_t* link); + +/** + * Returns the position of the link + * + * @param link The link + * @return The position of the link + */ +zathura_rectangle_t zathura_link_get_position(zathura_link_t* link); + +/** + * The target value of the link + * + * @param link The link + * @return Returns the target of the link (depends on the link type) + */ +zathura_link_target_t zathura_link_get_target(zathura_link_t* link); + +/** + * Evaluate link + * + * @param zathura Zathura instance + * @param link The link + */ +void zathura_link_evaluate(zathura_t* zathura, zathura_link_t* link); + +#endif // LINK_H diff --git a/marks.c b/marks.c new file mode 100644 index 0000000..1e65259 --- /dev/null +++ b/marks.c @@ -0,0 +1,263 @@ +/* See LICENSE file for license and copyright information */ + +#include +#include +#include +#include +#include + +#include "callbacks.h" +#include "marks.h" +#include "document.h" +#include "render.h" +#include "utils.h" + +static void mark_add(zathura_t* zathura, int key); +static void mark_evaluate(zathura_t* zathura, int key); +static bool cb_marks_view_key_press_event_add(GtkWidget* widget, GdkEventKey* + event, girara_session_t* session); +static bool cb_marks_view_key_press_event_evaluate(GtkWidget* widget, + GdkEventKey* event, girara_session_t* session); + +struct zathura_mark_s { + int key; /**> Marks key */ + double position_x; /**> Horizontal adjustment */ + double position_y; /**> Vertical adjustment */ + float scale; /**> Zoom level */ +}; + +bool +sc_mark_add(girara_session_t* session, girara_argument_t* UNUSED(argument), + girara_event_t* UNUSED(event), unsigned int UNUSED(t)) +{ + g_return_val_if_fail(session != NULL, FALSE); + g_return_val_if_fail(session->gtk.view != NULL, FALSE); + + /* redirect signal handler */ + g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed); + session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event", + G_CALLBACK(cb_marks_view_key_press_event_add), session); + + return true; +} + +bool +sc_mark_evaluate(girara_session_t* session, girara_argument_t* UNUSED(argument), + girara_event_t* UNUSED(event), unsigned int UNUSED(t)) +{ + g_return_val_if_fail(session != NULL, FALSE); + g_return_val_if_fail(session->gtk.view != NULL, FALSE); + + /* redirect signal handler */ + g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed); + session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event", + G_CALLBACK(cb_marks_view_key_press_event_evaluate), session); + + return true; +} + +bool +cb_marks_view_key_press_event_add(GtkWidget* UNUSED(widget), GdkEventKey* event, + girara_session_t* session) +{ + g_return_val_if_fail(session != NULL, FALSE); + g_return_val_if_fail(session->gtk.view != NULL, FALSE); + g_return_val_if_fail(session->global.data != NULL, FALSE); + zathura_t* zathura = (zathura_t*) session->global.data; + + /* reset signal handler */ + g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed); + session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event", + G_CALLBACK(girara_callback_view_key_press_event), session); + + /* evaluate key */ + if (((event->keyval >= 0x41 && event->keyval <= 0x5A) || (event->keyval >= + 0x61 && event->keyval <= 0x7A)) == false) { + return false; + } + + mark_add(zathura, event->keyval); + + return true; +} + +bool cb_marks_view_key_press_event_evaluate(GtkWidget* UNUSED(widget), GdkEventKey* + event, girara_session_t* session) +{ + g_return_val_if_fail(session != NULL, FALSE); + g_return_val_if_fail(session->gtk.view != NULL, FALSE); + g_return_val_if_fail(session->global.data != NULL, FALSE); + zathura_t* zathura = (zathura_t*) session->global.data; + + /* reset signal handler */ + g_signal_handler_disconnect(G_OBJECT(session->gtk.view), session->signals.view_key_pressed); + session->signals.view_key_pressed = g_signal_connect(G_OBJECT(session->gtk.view), "key-press-event", + G_CALLBACK(girara_callback_view_key_press_event), session); + + /* evaluate key */ + if (((event->keyval >= 0x41 && event->keyval <= 0x5A) || (event->keyval >= + 0x61 && event->keyval <= 0x7A)) == false) { + return true; + } + + mark_evaluate(zathura, event->keyval); + + return true; +} + +bool +cmd_marks_add(girara_session_t* session, girara_list_t* argument_list) +{ + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = (zathura_t*) session->global.data; + + if (girara_list_size(argument_list) < 1) { + return false; + } + + char* key_string = girara_list_nth(argument_list, 0); + + if (key_string == NULL) { + return false; + } + + if (strlen(key_string) < 1 || strlen(key_string) > 1) { + return false; + } + + char key = key_string[0]; + + if (((key >= 0x41 && key <= 0x5A) || (key >= + 0x61 && key <= 0x7A)) == false) { + return false; + } + + mark_add(zathura, key); + + return false; +} + +bool +cmd_marks_delete(girara_session_t* session, girara_list_t* argument_list) +{ + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = (zathura_t*) session->global.data; + + if (girara_list_size(argument_list) < 1) { + return false; + } + + if (girara_list_size(zathura->global.marks) == 0) { + return false; + } + + GIRARA_LIST_FOREACH(argument_list, char*, iter, key_string) + if (key_string == NULL) { + continue; + } + + for (unsigned int i = 0; i < strlen(key_string); i++) { + char key = key_string[i]; + if (((key >= 0x41 && key <= 0x5A) || (key >= + 0x61 && key <= 0x7A)) == false) { + continue; + } + + /* search for existing mark */ + girara_list_iterator_t* mark_iter = girara_list_iterator(zathura->global.marks); + do { + zathura_mark_t* mark = (zathura_mark_t*) girara_list_iterator_data(mark_iter); + if (mark == NULL) { + continue; + } + + if (mark->key == key) { + girara_list_remove(zathura->global.marks, mark); + continue; + } + } while (girara_list_iterator_next(mark_iter) != NULL); + girara_list_iterator_free(mark_iter); + } + GIRARA_LIST_FOREACH_END(argument_list, char*, iter, key_string); + + return true; +} + +void +mark_add(zathura_t* zathura, int key) +{ + if (zathura == NULL || zathura->document == NULL || zathura->global.marks == NULL) { + return; + } + + GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); + GtkAdjustment* v_adjustment = gtk_scrolled_window_get_vadjustment(window); + GtkAdjustment* h_adjustment = gtk_scrolled_window_get_hadjustment(window); + + if (v_adjustment == NULL || h_adjustment == NULL) { + return; + } + + double position_x = gtk_adjustment_get_value(h_adjustment); + double position_y = gtk_adjustment_get_value(v_adjustment); + float scale = zathura_document_get_scale(zathura->document); + + /* search for existing mark */ + GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark) + if (mark->key == key) { + mark->position_x = position_x; + mark->position_y = position_y; + mark->scale = scale; + return; + } + GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark); + + /* add new mark */ + zathura_mark_t* mark = g_malloc0(sizeof(zathura_mark_t)); + + mark->key = key; + mark->position_x = position_x; + mark->position_y = position_y; + mark->scale = scale; + + girara_list_append(zathura->global.marks, mark); +} + +void +mark_evaluate(zathura_t* zathura, int key) +{ + if (zathura == NULL || zathura->global.marks == NULL) { + return; + } + + /* search for existing mark */ + GIRARA_LIST_FOREACH(zathura->global.marks, zathura_mark_t*, iter, mark) + if (mark != NULL && mark->key == key) { + double old_scale = zathura_document_get_scale(zathura->document); + zathura_document_set_scale(zathura->document, mark->scale); + readjust_view_after_zooming(zathura, old_scale); + render_all(zathura); + + position_set_delayed(zathura, mark->position_x, mark->position_y); + + cb_view_vadjustment_value_changed(NULL, zathura); + + zathura->global.update_page_number = true; + return; + } + GIRARA_LIST_FOREACH_END(zathura->global.marks, zathura_mark_t*, iter, mark); +} + +void +mark_free(void* data) +{ + if (data == NULL) { + return; + } + + zathura_mark_t* mark = (zathura_mark_t*) data; + + g_free(mark); +} diff --git a/marks.h b/marks.h new file mode 100644 index 0000000..b821f52 --- /dev/null +++ b/marks.h @@ -0,0 +1,61 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef MARKS_H +#define MARKS_H + +#include + +#include "zathura.h" + +typedef struct zathura_mark_s zathura_mark_t; + +/** + * Saves a mark + * + * @param session The used girara session + * @param argument The used argument + * @param event Girara event + * @param t Number of executions + * @return true if no error occured otherwise false + */ +bool sc_mark_add(girara_session_t* session, girara_argument_t* argument, + girara_event_t* event, unsigned int t); + +/** + * Evaluates a mark + * + * @param session The used girara session + * @param argument The used argument + * @param event Girara event + * @param t Number of executions + * @return true if no error occured otherwise false + */ +bool sc_mark_evaluate(girara_session_t* session, girara_argument_t* argument, + girara_event_t* event, unsigned int t); + +/** + * Mark current location within the web page + * + * @param session The girara session + * @param argument_list Argument list + * @return true if no error occured otherwise false + */ +bool cmd_marks_add(girara_session_t* session, girara_list_t* argument_list); + +/** + * Delete the specified marks + * + * @param session The girara session + * @param argument_list Argument list + * @return true if no error occured otherwise false + */ +bool cmd_marks_delete(girara_session_t* session, girara_list_t* argument_list); + +/** + * Free function vor marks + * + * @param data + */ +void mark_free(void* data); + +#endif // MARKS_H diff --git a/page-widget.c b/page-widget.c index 32cc86d..4734ff8 100644 --- a/page-widget.c +++ b/page-widget.c @@ -7,7 +7,9 @@ #include #include +#include "links.h" #include "page-widget.h" +#include "page.h" #include "render.h" #include "utils.h" #include "shortcuts.h" @@ -15,26 +17,39 @@ G_DEFINE_TYPE(ZathuraPage, zathura_page_widget, GTK_TYPE_DRAWING_AREA) typedef struct zathura_page_widget_private_s { - zathura_page_t* page; - zathura_t* zathura; + zathura_page_t* page; /**< Page object */ + zathura_t* zathura; /**< Zathura object */ cairo_surface_t* surface; /**< Cairo surface */ + gint64 last_view; /**< Last time the page has been viewed */ GStaticMutex lock; /**< Lock */ - girara_list_t* links; /**< List of links on the page */ - bool links_got; /**< True if we already tried to retrieve the list of links */ - bool draw_links; /**< True if links should be drawn */ - unsigned int link_offset; /**< Offset to the links */ - unsigned int number_of_links; /**< Offset to the links */ - girara_list_t* search_results; /**< A list if there are search results that should be drawn */ - int search_current; /**< The index of the current search result */ - zathura_rectangle_t selection; /**< Region selected with the mouse */ + struct { - int x; - int y; - } selection_basepoint; - girara_list_t* images; /**< List of images on the page */ - bool images_got; /**< True if we already tried to retrieve the list of images */ - zathura_image_t* current_image; /**< Image data of selected image */ - gint64 last_view; + girara_list_t* list; /**< List of links on the page */ + bool retrieved; /**< True if we already tried to retrieve the list of links */ + bool draw; /**< True if links should be drawn */ + unsigned int offset; /**< Offset to the links */ + unsigned int n; /**< Number */ + } links; + + struct { + girara_list_t* list; /**< A list if there are search results that should be drawn */ + int current; /**< The index of the current search result */ + bool draw; /**< Draw search results */ + } search; + + struct { + girara_list_t* list; /**< List of images on the page */ + bool retrieved; /**< True if we already tried to retrieve the list of images */ + zathura_image_t* current; /**< Image data of selected image */ + } images; + + struct { + zathura_rectangle_t selection; /**< Region selected with the mouse */ + struct { + int x; /**< X coordinate */ + int y; /**< Y coordinate */ + } selection_basepoint; + } mouse; } zathura_page_widget_private_t; #define ZATHURA_PAGE_GET_PRIVATE(obj) \ @@ -56,18 +71,21 @@ static gboolean cb_zathura_page_widget_button_release_event(GtkWidget* widget, G static gboolean cb_zathura_page_widget_motion_notify(GtkWidget* widget, GdkEventMotion* event); static gboolean cb_zathura_page_widget_popup_menu(GtkWidget* widget); static void cb_menu_image_copy(GtkMenuItem* item, ZathuraPage* page); +static void cb_menu_image_save(GtkMenuItem* item, ZathuraPage* page); enum properties_e { PROP_0, PROP_PAGE, + PROP_ZATHURA, PROP_DRAW_LINKS, PROP_LINKS_OFFSET, PROP_LINKS_NUMBER, - PROP_SEARCH_RESULT, PROP_SEARCH_RESULTS, PROP_SEARCH_RESULTS_LENGTH, - PROP_SEARCH_RESULTS_CURRENT + PROP_SEARCH_RESULTS_CURRENT, + PROP_DRAW_SEACH_RESULTS, + PROP_LAST_VIEW, }; static void @@ -97,6 +115,8 @@ zathura_page_widget_class_init(ZathuraPageClass* class) /* add properties */ g_object_class_install_property(object_class, PROP_PAGE, g_param_spec_pointer("page", "page", "the page to draw", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + g_object_class_install_property(object_class, PROP_ZATHURA, + g_param_spec_pointer("zathura", "zathura", "the zathura instance", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property(object_class, PROP_DRAW_LINKS, g_param_spec_boolean("draw-links", "draw-links", "Set to true if links should be drawn", FALSE, G_PARAM_WRITABLE)); g_object_class_install_property(object_class, PROP_LINKS_OFFSET, @@ -109,26 +129,39 @@ zathura_page_widget_class_init(ZathuraPageClass* class) g_param_spec_int("search-current", "search-current", "The current search result", -1, INT_MAX, 0, G_PARAM_WRITABLE | G_PARAM_READABLE)); g_object_class_install_property(object_class, PROP_SEARCH_RESULTS_LENGTH, g_param_spec_int("search-length", "search-length", "The number of search results", -1, INT_MAX, 0, G_PARAM_READABLE)); + g_object_class_install_property(object_class, PROP_DRAW_SEACH_RESULTS, + g_param_spec_boolean("draw-search-results", "draw-search-results", "Set to true if search results should be drawn", FALSE, G_PARAM_WRITABLE)); + g_object_class_install_property(object_class, PROP_LAST_VIEW, + g_param_spec_int("last-view", "last-view", "Last time the page has been viewed", -1, INT_MAX, 0, G_PARAM_READABLE)); } static void zathura_page_widget_init(ZathuraPage* widget) { zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); - priv->page = NULL; - priv->surface = NULL; - priv->links = NULL; - priv->links_got = false; - priv->link_offset = 0; - priv->search_results = NULL; - priv->search_current = INT_MAX; - priv->selection.x1 = -1; - priv->selection_basepoint.x = -1; - priv->selection_basepoint.y = -1; - priv->images = NULL; - priv->images_got = false; - priv->current_image = NULL; - priv->last_view = g_get_real_time(); + priv->page = NULL; + priv->surface = NULL; + priv->last_view = g_get_real_time(); + + priv->links.list = NULL; + priv->links.retrieved = false; + priv->links.draw = false; + priv->links.offset = 0; + priv->links.n = 0; + + priv->search.list = NULL; + priv->search.current = INT_MAX; + priv->search.draw = true; + + priv->images.list = NULL; + priv->images.retrieved = false; + priv->images.current = NULL; + + priv->mouse.selection.x1 = -1; + priv->mouse.selection.y1 = -1; + priv->mouse.selection_basepoint.x = -1; + priv->mouse.selection_basepoint.y = -1; + g_static_mutex_init(&(priv->lock)); /* we want mouse events */ @@ -137,11 +170,11 @@ zathura_page_widget_init(ZathuraPage* widget) } GtkWidget* -zathura_page_widget_new(zathura_page_t* page) +zathura_page_widget_new(zathura_t* zathura, zathura_page_t* page) { g_return_val_if_fail(page != NULL, NULL); - return g_object_new(ZATHURA_TYPE_PAGE, "page", page, NULL); + return g_object_new(ZATHURA_TYPE_PAGE, "page", page, "zathura", zathura, NULL); } static void @@ -154,12 +187,12 @@ zathura_page_widget_finalize(GObject* object) cairo_surface_destroy(priv->surface); } - if (priv->search_results != NULL) { - girara_list_free(priv->search_results); + if (priv->search.list != NULL) { + girara_list_free(priv->search.list); } - if (priv->links != NULL) { - girara_list_free(priv->links); + if (priv->links.list != NULL) { + girara_list_free(priv->links.list); } g_static_mutex_free(&(priv->lock)); @@ -175,58 +208,67 @@ zathura_page_widget_set_property(GObject* object, guint prop_id, const GValue* v switch (prop_id) { case PROP_PAGE: - priv->page = g_value_get_pointer(value); - priv->zathura = priv->page->document->zathura; + priv->page = g_value_get_pointer(value); + break; + case PROP_ZATHURA: + priv->zathura = g_value_get_pointer(value); break; case PROP_DRAW_LINKS: - priv->draw_links = g_value_get_boolean(value); + priv->links.draw = g_value_get_boolean(value); /* get links */ - if (priv->draw_links == true && priv->links_got == false) { - priv->links = zathura_page_links_get(priv->page, NULL); - priv->links_got = true; - priv->number_of_links = (priv->links == NULL) ? 0 : girara_list_size(priv->links); + if (priv->links.draw == true && priv->links.retrieved == false) { + priv->links.list = zathura_page_links_get(priv->page, NULL); + priv->links.retrieved = true; + priv->links.n = (priv->links.list == NULL) ? 0 : girara_list_size(priv->links.list); } - if (priv->links_got == true && priv->links != NULL) { - GIRARA_LIST_FOREACH(priv->links, zathura_link_t*, iter, link) - zathura_rectangle_t rectangle = recalc_rectangle(priv->page, link->position); - redraw_rect(pageview, &rectangle); - GIRARA_LIST_FOREACH_END(priv->links, zathura_link_t*, iter, link); + if (priv->links.retrieved == true && priv->links.list != NULL) { + GIRARA_LIST_FOREACH(priv->links.list, zathura_link_t*, iter, link) + if (link != NULL) { + zathura_rectangle_t rectangle = recalc_rectangle(priv->page, zathura_link_get_position(link)); + redraw_rect(pageview, &rectangle); + } + GIRARA_LIST_FOREACH_END(priv->links.list, zathura_link_t*, iter, link); } break; case PROP_LINKS_OFFSET: - priv->link_offset = g_value_get_int(value); + priv->links.offset = g_value_get_int(value); break; case PROP_SEARCH_RESULTS: - if (priv->search_results != NULL) { - redraw_all_rects(pageview, priv->search_results); - girara_list_free(priv->search_results); + if (priv->search.list != NULL && priv->search.draw) { + redraw_all_rects(pageview, priv->search.list); + girara_list_free(priv->search.list); } - priv->search_results = g_value_get_pointer(value); - if (priv->search_results != NULL) { - priv->draw_links = false; - redraw_all_rects(pageview, priv->search_results); + priv->search.list = g_value_get_pointer(value); + if (priv->search.list != NULL && priv->search.draw) { + priv->links.draw = false; + redraw_all_rects(pageview, priv->search.list); } - priv->search_current = -1; + priv->search.current = -1; break; case PROP_SEARCH_RESULTS_CURRENT: { - g_return_if_fail(priv->search_results != NULL); - if (priv->search_current >= 0 && priv->search_current < (signed) girara_list_size(priv->search_results)) { - zathura_rectangle_t* rect = girara_list_nth(priv->search_results, priv->search_current); + g_return_if_fail(priv->search.list != NULL); + if (priv->search.current >= 0 && priv->search.current < (signed) girara_list_size(priv->search.list)) { + zathura_rectangle_t* rect = girara_list_nth(priv->search.list, priv->search.current); zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect); redraw_rect(pageview, &rectangle); } int val = g_value_get_int(value); if (val < 0) { - priv->search_current = girara_list_size(priv->search_results); + priv->search.current = girara_list_size(priv->search.list); } else { - priv->search_current = val; - zathura_rectangle_t* rect = girara_list_nth(priv->search_results, priv->search_current); + priv->search.current = val; + zathura_rectangle_t* rect = girara_list_nth(priv->search.list, priv->search.current); zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect); - redraw_rect(pageview, &rectangle); + if (priv->search.draw) { + redraw_rect(pageview, &rectangle); + } } break; } + case PROP_DRAW_SEACH_RESULTS: + priv->search.draw = g_value_get_boolean(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); } @@ -240,16 +282,19 @@ zathura_page_widget_get_property(GObject* object, guint prop_id, GValue* value, switch (prop_id) { case PROP_LINKS_NUMBER: - g_value_set_int(value, priv->number_of_links); + g_value_set_int(value, priv->links.n); break; case PROP_SEARCH_RESULTS_LENGTH: - g_value_set_int(value, priv->search_results == NULL ? 0 : girara_list_size(priv->search_results)); + g_value_set_int(value, priv->search.list == NULL ? 0 : girara_list_size(priv->search.list)); break; case PROP_SEARCH_RESULTS_CURRENT: - g_value_set_int(value, priv->search_results == NULL ? -1 : priv->search_current); + g_value_set_int(value, priv->search.list == NULL ? -1 : priv->search.current); break; case PROP_SEARCH_RESULTS: - g_value_set_pointer(value, priv->search_results); + g_value_set_pointer(value, priv->search.list); + break; + case PROP_LAST_VIEW: + g_value_set_int(value, priv->last_view); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); @@ -282,6 +327,8 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); g_static_mutex_lock(&(priv->lock)); + zathura_document_t* document = zathura_page_get_document(priv->page); + #if GTK_MAJOR_VERSION == 2 GtkAllocation allocation; gtk_widget_get_allocation(widget, &allocation); @@ -295,7 +342,8 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) if (priv->surface != NULL) { cairo_save(cairo); - switch (priv->page->document->rotate) { + unsigned int rotation = zathura_document_get_rotation(document); + switch (rotation) { case 90: cairo_translate(cairo, page_width, 0); break; @@ -307,8 +355,8 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) break; } - if (priv->page->document->rotate != 0) { - cairo_rotate(cairo, priv->page->document->rotate * G_PI / 180.0); + if (rotation != 0) { + cairo_rotate(cairo, rotation * G_PI / 180.0); } cairo_set_source_surface(cairo, priv->surface, 0, 0); @@ -325,39 +373,42 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) if (font != NULL) { cairo_select_font_face(cairo, font, CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD); } + g_free(font); /* draw links */ - if (priv->draw_links == true && priv->number_of_links != 0) { + if (priv->links.draw == true && priv->links.n != 0) { unsigned int link_counter = 0; - GIRARA_LIST_FOREACH(priv->links, zathura_link_t*, iter, link) - zathura_rectangle_t rectangle = recalc_rectangle(priv->page, link->position); + GIRARA_LIST_FOREACH(priv->links.list, zathura_link_t*, iter, link) + if (link != NULL) { + zathura_rectangle_t rectangle = recalc_rectangle(priv->page, zathura_link_get_position(link)); - /* draw position */ - GdkColor color = priv->zathura->ui.colors.highlight_color; - cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency); - cairo_rectangle(cairo, rectangle.x1, rectangle.y1, - (rectangle.x2 - rectangle.x1), (rectangle.y2 - rectangle.y1)); - cairo_fill(cairo); + /* draw position */ + GdkColor color = priv->zathura->ui.colors.highlight_color; + cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency); + cairo_rectangle(cairo, rectangle.x1, rectangle.y1, + (rectangle.x2 - rectangle.x1), (rectangle.y2 - rectangle.y1)); + cairo_fill(cairo); - /* draw text */ - cairo_set_source_rgba(cairo, 0, 0, 0, 1); - cairo_set_font_size(cairo, 10); - cairo_move_to(cairo, rectangle.x1 + 1, rectangle.y2 - 1); - char* link_number = g_strdup_printf("%i", priv->link_offset + ++link_counter); - cairo_show_text(cairo, link_number); - g_free(link_number); - GIRARA_LIST_FOREACH_END(priv->links, zathura_link_t*, iter, link); + /* draw text */ + cairo_set_source_rgba(cairo, 0, 0, 0, 1); + cairo_set_font_size(cairo, 10); + cairo_move_to(cairo, rectangle.x1 + 1, rectangle.y2 - 1); + char* link_number = g_strdup_printf("%i", priv->links.offset + ++link_counter); + cairo_show_text(cairo, link_number); + g_free(link_number); + } + GIRARA_LIST_FOREACH_END(priv->links.list, zathura_link_t*, iter, link); } /* draw search results */ - if (priv->search_results != NULL) { + if (priv->search.list != NULL && priv->search.draw == true) { int idx = 0; - GIRARA_LIST_FOREACH(priv->search_results, zathura_rectangle_t*, iter, rect) + GIRARA_LIST_FOREACH(priv->search.list, zathura_rectangle_t*, iter, rect) zathura_rectangle_t rectangle = recalc_rectangle(priv->page, *rect); /* draw position */ - if (idx == priv->search_current) { + if (idx == priv->search.current) { GdkColor color = priv->zathura->ui.colors.highlight_color_active; cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency); } else { @@ -368,19 +419,24 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) (rectangle.x2 - rectangle.x1), (rectangle.y2 - rectangle.y1)); cairo_fill(cairo); ++idx; - GIRARA_LIST_FOREACH_END(priv->search_results, zathura_rectangle_t*, iter, rect); + GIRARA_LIST_FOREACH_END(priv->search.list, zathura_rectangle_t*, iter, rect); } /* draw selection */ - if (priv->selection.y2 != -1 && priv->selection.x2 != -1) { - GdkColor color = priv->zathura->ui.colors.highlight_color; - cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency); - cairo_rectangle(cairo, priv->selection.x1, priv->selection.y1, - (priv->selection.x2 - priv->selection.x1), (priv->selection.y2 - priv->selection.y1)); - cairo_fill(cairo); + if (priv->mouse.selection.y2 != -1 && priv->mouse.selection.x2 != -1) { + GdkColor color = priv->zathura->ui.colors.highlight_color; + cairo_set_source_rgba(cairo, color.red, color.green, color.blue, transparency); + cairo_rectangle(cairo, priv->mouse.selection.x1, priv->mouse.selection.y1, + (priv->mouse.selection.x2 - priv->mouse.selection.x1), (priv->mouse.selection.y2 - priv->mouse.selection.y1)); + cairo_fill(cairo); } } else { /* set background color */ - cairo_set_source_rgb(cairo, 255, 255, 255); + if (priv->zathura->global.recolor == true) { + GdkColor color = priv->zathura->ui.colors.recolor_light_color; + cairo_set_source_rgb(cairo, color.red, color.green, color.blue); + } else { + cairo_set_source_rgb(cairo, 255, 255, 255); + } cairo_rectangle(cairo, 0, 0, page_width, page_height); cairo_fill(cairo); @@ -389,7 +445,13 @@ zathura_page_widget_draw(GtkWidget* widget, cairo_t* cairo) /* write text */ if (render_loading == true) { - cairo_set_source_rgb(cairo, 0, 0, 0); + if (priv->zathura->global.recolor == true) { + GdkColor color = priv->zathura->ui.colors.recolor_dark_color; + cairo_set_source_rgb(cairo, color.red, color.green, color.blue); + } else { + cairo_set_source_rgb(cairo, 0, 0, 0); + } + const char* text = "Loading..."; cairo_select_font_face(cairo, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL); cairo_set_font_size(cairo, 16.0); @@ -470,9 +532,9 @@ zathura_page_widget_link_get(ZathuraPage* widget, unsigned int index) zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); g_return_val_if_fail(priv != NULL, NULL); - if (priv->links != NULL && index >= priv->link_offset && - girara_list_size(priv->links) >= index - priv->link_offset) { - return girara_list_nth(priv->links, index - priv->link_offset); + if (priv->links.list != NULL && index >= priv->links.offset && + girara_list_size(priv->links.list) > index - priv->links.offset) { + return girara_list_nth(priv->links.list, index - priv->links.offset); } else { return NULL; } @@ -489,20 +551,22 @@ cb_zathura_page_widget_button_press_event(GtkWidget* widget, GdkEventButton* but if (button->button == 1) { /* left click */ if (button->type == GDK_BUTTON_PRESS) { /* start the selection */ - priv->selection_basepoint.x = button->x; - priv->selection_basepoint.y = button->y; - priv->selection.x1 = button->x; - priv->selection.y1 = button->y; - priv->selection.x2 = button->x; - priv->selection.y2 = button->y; + priv->mouse.selection_basepoint.x = button->x; + priv->mouse.selection_basepoint.y = button->y; + + priv->mouse.selection.x1 = button->x; + priv->mouse.selection.y1 = button->y; + priv->mouse.selection.x2 = button->x; + priv->mouse.selection.y2 = button->y; } else if (button->type == GDK_2BUTTON_PRESS || button->type == GDK_3BUTTON_PRESS) { /* abort the selection */ - priv->selection_basepoint.x = -1; - priv->selection_basepoint.y = -1; - priv->selection.x1 = -1; - priv->selection.y1 = -1; - priv->selection.x2 = -1; - priv->selection.y2 = -1; + priv->mouse.selection_basepoint.x = -1; + priv->mouse.selection_basepoint.y = -1; + + priv->mouse.selection.x1 = -1; + priv->mouse.selection.y1 = -1; + priv->mouse.selection.x2 = -1; + priv->mouse.selection.y2 = -1; } return true; @@ -524,40 +588,35 @@ cb_zathura_page_widget_button_release_event(GtkWidget* widget, GdkEventButton* b } zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); + zathura_document_t* document = zathura_page_get_document(priv->page); - if (priv->selection.y2 == -1 && priv->selection.x2 == -1 ) { + if (priv->mouse.selection.y2 == -1 && priv->mouse.selection.x2 == -1 ) { /* simple single click */ /* get links */ - if (priv->links_got == false) { - priv->links = zathura_page_links_get(priv->page, NULL); - priv->links_got = true; - priv->number_of_links = (priv->links == NULL) ? 0 : girara_list_size(priv->links); + if (priv->links.retrieved == false) { + priv->links.list = zathura_page_links_get(priv->page, NULL); + priv->links.retrieved = true; + priv->links.n = (priv->links.list == NULL) ? 0 : girara_list_size(priv->links.list); } - if (priv->links != NULL && priv->number_of_links > 0) { - GIRARA_LIST_FOREACH(priv->links, zathura_link_t*, iter, link) - zathura_rectangle_t rect = recalc_rectangle(priv->page, link->position); + if (priv->links.list != NULL && priv->links.n > 0) { + GIRARA_LIST_FOREACH(priv->links.list, zathura_link_t*, iter, link) + zathura_rectangle_t rect = recalc_rectangle(priv->page, zathura_link_get_position(link)); if (rect.x1 <= button->x && rect.x2 >= button->x && rect.y1 <= button->y && rect.y2 >= button->y) { - switch (link->type) { - case ZATHURA_LINK_TO_PAGE: - page_set_delayed(priv->page->document->zathura, link->target.page_number); - return false; - case ZATHURA_LINK_EXTERNAL: - girara_xdg_open(link->target.value); - return false; - } + zathura_link_evaluate(priv->zathura, link); } - GIRARA_LIST_FOREACH_END(priv->links, zathura_link_t*, iter, link); + GIRARA_LIST_FOREACH_END(priv->links.list, zathura_link_t*, iter, link); } } else { - redraw_rect(ZATHURA_PAGE(widget), &priv->selection); - zathura_rectangle_t tmp = priv->selection; + redraw_rect(ZATHURA_PAGE(widget), &priv->mouse.selection); + zathura_rectangle_t tmp = priv->mouse.selection; - tmp.x1 /= priv->page->document->scale; - tmp.x2 /= priv->page->document->scale; - tmp.y1 /= priv->page->document->scale; - tmp.y2 /= priv->page->document->scale; + double scale = zathura_document_get_scale(document); + tmp.x1 /= scale; + tmp.x2 /= scale; + tmp.y1 /= scale; + tmp.y2 /= scale; char* text = zathura_page_get_text(priv->page, tmp, NULL); if (text != NULL) { @@ -566,10 +625,9 @@ cb_zathura_page_widget_button_release_event(GtkWidget* widget, GdkEventButton* b gtk_clipboard_set_text(gtk_clipboard_get(GDK_SELECTION_PRIMARY), text, -1); - if (priv->page != NULL && priv->page->document != NULL && priv->page->document->zathura != NULL) { - zathura_t* zathura = priv->page->document->zathura; + if (priv->page != NULL && document != NULL && priv->zathura != NULL) { char* stripped_text = g_strdelimit(g_strdup(text), "\n\t\r\n", ' '); - girara_notify(zathura->ui.session, GIRARA_INFO, _("Copied selected text to clipbard: %s"), stripped_text); + girara_notify(priv->zathura->ui.session, GIRARA_INFO, _("Copied selected text to clipboard: %s"), stripped_text); g_free(stripped_text); } } @@ -578,12 +636,13 @@ cb_zathura_page_widget_button_release_event(GtkWidget* widget, GdkEventButton* b } } - priv->selection_basepoint.x = -1; - priv->selection_basepoint.y = -1; - priv->selection.x1 = -1; - priv->selection.y1 = -1; - priv->selection.x2 = -1; - priv->selection.y2 = -1; + priv->mouse.selection_basepoint.x = -1; + priv->mouse.selection_basepoint.y = -1; + + priv->mouse.selection.x1 = -1; + priv->mouse.selection.y1 = -1; + priv->mouse.selection.x2 = -1; + priv->mouse.selection.y2 = -1; return false; } @@ -598,25 +657,25 @@ cb_zathura_page_widget_motion_notify(GtkWidget* widget, GdkEventMotion* event) } zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); - zathura_rectangle_t tmp = priv->selection; - if (event->x < priv->selection_basepoint.x) { + zathura_rectangle_t tmp = priv->mouse.selection; + if (event->x < priv->mouse.selection_basepoint.x) { tmp.x1 = event->x; - tmp.x2 = priv->selection_basepoint.x; + tmp.x2 = priv->mouse.selection_basepoint.x; } else { tmp.x2 = event->x; - tmp.x1 = priv->selection_basepoint.x; + tmp.x1 = priv->mouse.selection_basepoint.x; } - if (event->y < priv->selection_basepoint.y) { + if (event->y < priv->mouse.selection_basepoint.y) { tmp.y1 = event->y; - tmp.y2 = priv->selection_basepoint.y; + tmp.y2 = priv->mouse.selection_basepoint.y; } else { - tmp.y1 = priv->selection_basepoint.y; + tmp.y1 = priv->mouse.selection_basepoint.y; tmp.y2 = event->y; } - redraw_rect(ZATHURA_PAGE(widget), &priv->selection); + redraw_rect(ZATHURA_PAGE(widget), &priv->mouse.selection); redraw_rect(ZATHURA_PAGE(widget), &tmp); - priv->selection = tmp; + priv->mouse.selection = tmp; return false; } @@ -628,29 +687,33 @@ zathura_page_widget_popup_menu(GtkWidget* widget, GdkEventButton* event) g_return_if_fail(event != NULL); zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); - if (priv->images_got == false) { - priv->images = zathura_page_images_get(priv->page, NULL); - priv->images_got = true; +#if GTK_MAJOR_VERSION == 3 // FIXME + return; +#endif + + if (priv->images.retrieved == false) { + priv->images.list = zathura_page_images_get(priv->page, NULL); + priv->images.retrieved = true; } - if (priv->images == NULL) { + if (priv->images.list == NULL) { return; } /* search for underlaying image */ zathura_image_t* image = NULL; - GIRARA_LIST_FOREACH(priv->images, zathura_image_t*, iter, image_it) + GIRARA_LIST_FOREACH(priv->images.list, zathura_image_t*, iter, image_it) zathura_rectangle_t rect = recalc_rectangle(priv->page, image_it->position); - if (rect.x1 <= event->x && rect.x2 >= event->x && rect.y1 <= event->y && rect.y2 >= event->y) { - image = image_it; - } - GIRARA_LIST_FOREACH_END(priv->images, zathura_image_t*, iter, image_it); + if (rect.x1 <= event->x && rect.x2 >= event->x && rect.y1 <= event->y && rect.y2 >= event->y) { + image = image_it; + } + GIRARA_LIST_FOREACH_END(priv->images.list, zathura_image_t*, iter, image_it); if (image == NULL) { return; } - priv->current_image = image; + priv->images.current = image; /* setup menu */ GtkWidget* menu = gtk_menu_new(); @@ -661,7 +724,8 @@ zathura_page_widget_popup_menu(GtkWidget* widget, GdkEventButton* event) } menu_item_t; menu_item_t menu_items[] = { - { _("Copy image"), cb_menu_image_copy }, + { _("Copy image"), cb_menu_image_copy }, + { _("Save image as"), cb_menu_image_save }, }; for (unsigned int i = 0; i < LENGTH(menu_items); i++) { @@ -695,12 +759,13 @@ cb_zathura_page_widget_popup_menu(GtkWidget* widget) static void cb_menu_image_copy(GtkMenuItem* item, ZathuraPage* page) { +#if GTK_MAJOR_VERSION == 2 // FIXME g_return_if_fail(item != NULL); g_return_if_fail(page != NULL); zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(page); - g_return_if_fail(priv->current_image != NULL); + g_return_if_fail(priv->images.current != NULL); - cairo_surface_t* surface = zathura_page_image_get_cairo(priv->page, priv->current_image, NULL); + cairo_surface_t* surface = zathura_page_image_get_cairo(priv->page, priv->images.current, NULL); if (surface == NULL) { return; } @@ -721,7 +786,40 @@ cb_menu_image_copy(GtkMenuItem* item, ZathuraPage* page) gtk_clipboard_set_image(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD), pixbuf); gtk_clipboard_set_image(gtk_clipboard_get(GDK_SELECTION_PRIMARY), pixbuf); - priv->current_image = NULL; + /* reset */ + priv->images.current = NULL; +#endif +} + +static void +cb_menu_image_save(GtkMenuItem* item, ZathuraPage* page) +{ + g_return_if_fail(item != NULL); + g_return_if_fail(page != NULL); + zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(page); + g_return_if_fail(priv->images.current != NULL); + g_return_if_fail(priv->images.list != NULL); + + /* generate image identifier */ + unsigned int page_id = zathura_page_get_index(priv->page) + 1; + unsigned int image_id = 1; + + GIRARA_LIST_FOREACH(priv->images.list, zathura_image_t*, iter, image_it) + if (image_it == priv->images.current) { + break; + } + + image_id++; + GIRARA_LIST_FOREACH_END(priv->images.list, zathura_image_t*, iter, image_it); + + /* set command */ + char* export_command = g_strdup_printf(":export image-p%d-%d ", page_id, image_id); + girara_argument_t argument = { 0, export_command }; + sc_focus_inputbar(priv->zathura->ui.session, &argument, NULL, 0); + g_free(export_command); + + /* reset */ + priv->images.current = NULL; } void @@ -730,7 +828,7 @@ zathura_page_widget_update_view_time(ZathuraPage* widget) g_return_if_fail(ZATHURA_IS_PAGE(widget) == TRUE); zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); - if (priv->page->visible == true) { + if (zathura_page_get_visibility(priv->page) == true) { priv->last_view = g_get_real_time(); } } @@ -740,7 +838,7 @@ zathura_page_widget_purge_unused(ZathuraPage* widget, gint64 threshold) { g_return_if_fail(ZATHURA_IS_PAGE(widget) == TRUE); zathura_page_widget_private_t* priv = ZATHURA_PAGE_GET_PRIVATE(widget); - if (priv->page->visible == true || priv->surface == NULL || threshold <= 0) { + if (zathura_page_get_visibility(priv->page) == true || priv->surface == NULL || threshold <= 0) { return; } diff --git a/page-widget.h b/page-widget.h index 4bc3f24..53c64c5 100644 --- a/page-widget.h +++ b/page-widget.h @@ -45,10 +45,11 @@ struct zathura_page_widget_class_s { GType zathura_page_widget_get_type(void); /** * Create a page view widget. + * @param zathura the zathura instance * @param page the page to be displayed * @return a page view widget */ -GtkWidget* zathura_page_widget_new(zathura_page_t* page); +GtkWidget* zathura_page_widget_new(zathura_t* zathura, zathura_page_t* page); /** * Update the widget's surface. This should only be called from the render * thread. diff --git a/page.c b/page.c new file mode 100644 index 0000000..ff70a10 --- /dev/null +++ b/page.c @@ -0,0 +1,344 @@ +/* See LICENSE file for license and copyright information */ + +#include +#include +#include + +#include "document.h" +#include "page.h" +#include "plugin.h" +#include "utils.h" +#include "internal.h" +#include "types.h" + +struct zathura_page_s { + double height; /**< Page height */ + double width; /**< Page width */ + unsigned int index; /**< Page number */ + void* data; /**< Custom data */ + bool visible; /**< Page is visible */ + zathura_document_t* document; /**< Document */ +}; + +zathura_page_t* +zathura_page_new(zathura_document_t* document, unsigned int index, zathura_error_t* error) +{ + if (document == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + goto error_ret; + } + + /* init page */ + zathura_page_t* page = g_malloc0(sizeof(zathura_page_t)); + + page->index = index; + page->visible = false; + page->document = document; + + /* init plugin */ + zathura_plugin_t* plugin = zathura_document_get_plugin(document); + if (plugin->functions.page_init == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + goto error_ret; + } + + zathura_error_t ret = plugin->functions.page_init(page); + if (ret != ZATHURA_ERROR_OK) { + if (error != NULL) { + *error = ret; + } + goto error_free; + } + + return page; + +error_free: + + if (page != NULL) { + zathura_page_free(page); + } + +error_ret: + + return NULL; +} + +zathura_error_t +zathura_page_free(zathura_page_t* page) +{ + if (page == NULL) { + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + if (page->document == NULL) { + g_free(page); + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_clear == NULL) { + return ZATHURA_ERROR_NOT_IMPLEMENTED; + } + + zathura_error_t error = plugin->functions.page_clear(page, page->data); + + g_free(page); + + return error; +} + +zathura_document_t* +zathura_page_get_document(zathura_page_t* page) +{ + if (page == NULL) { + return NULL; + } + + return page->document; +} + +unsigned int +zathura_page_get_index(zathura_page_t* page) +{ + if (page == NULL) { + return 0; + } + + return page->index; +} + +double +zathura_page_get_width(zathura_page_t* page) +{ + if (page == NULL) { + return -1; + } + + return page->width; +} + +void +zathura_page_set_width(zathura_page_t* page, double width) +{ + if (page == NULL) { + return; + } + + page->width = width; +} + +double +zathura_page_get_height(zathura_page_t* page) +{ + if (page == NULL) { + return -1; + } + + return page->height; +} + +void +zathura_page_set_height(zathura_page_t* page, double height) +{ + if (page == NULL) { + return; + } + + page->height = height; +} + +bool +zathura_page_get_visibility(zathura_page_t* page) +{ + if (page == NULL) { + return false; + } + + return page->visible; +} + +void +zathura_page_set_visibility(zathura_page_t* page, bool visibility) +{ + if (page == NULL) { + return; + } + + page->visible = visibility; +} + +void* +zathura_page_get_data(zathura_page_t* page) +{ + if (page == NULL) { + return NULL; + } + + return page->data; +} + +void +zathura_page_set_data(zathura_page_t* page, void* data) +{ + if (page == NULL) { + return; + } + + page->data = data; +} + +girara_list_t* +zathura_page_search_text(zathura_page_t* page, const char* text, zathura_error_t* error) +{ + if (page == NULL || page->document == NULL || text == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_search_text == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return plugin->functions.page_search_text(page, page->data, text, error); +} + +girara_list_t* +zathura_page_links_get(zathura_page_t* page, zathura_error_t* error) +{ + if (page == NULL || page->document == NULL ) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_links_get == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return plugin->functions.page_links_get(page, page->data, error); +} + +zathura_error_t +zathura_page_links_free(girara_list_t* UNUSED(list)) +{ + return false; +} + +girara_list_t* +zathura_page_form_fields_get(zathura_page_t* page, zathura_error_t* error) +{ + if (page == NULL || page->document == NULL ) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_form_fields_get == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return plugin->functions.page_form_fields_get(page, page->data, error); +} + +zathura_error_t +zathura_page_form_fields_free(girara_list_t* UNUSED(list)) +{ + return ZATHURA_ERROR_NOT_IMPLEMENTED; +} + +girara_list_t* +zathura_page_images_get(zathura_page_t* page, zathura_error_t* error) +{ + if (page == NULL || page->document == NULL ) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_images_get == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return plugin->functions.page_images_get(page, page->data, error); +} + +cairo_surface_t* +zathura_page_image_get_cairo(zathura_page_t* page, zathura_image_t* image, zathura_error_t* error) +{ + if (page == NULL || page->document == NULL || image == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_image_get_cairo == NULL) { + if (error != NULL) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return plugin->functions.page_image_get_cairo(page, page->data, image, error); +} + +char* zathura_page_get_text(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_error_t* error) +{ + if (page == NULL || page->document == NULL ) { + if (error) { + *error = ZATHURA_ERROR_INVALID_ARGUMENTS; + } + return NULL; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_get_text == NULL) { + if (error) { + *error = ZATHURA_ERROR_NOT_IMPLEMENTED; + } + return NULL; + } + + return plugin->functions.page_get_text(page, page->data, rectangle, error); +} + +zathura_error_t +zathura_page_render(zathura_page_t* page, cairo_t* cairo, bool printing) +{ + if (page == NULL || page->document == NULL || cairo == NULL) { + return ZATHURA_ERROR_INVALID_ARGUMENTS; + } + + zathura_plugin_t* plugin = zathura_document_get_plugin(page->document); + if (plugin->functions.page_render_cairo == NULL) { + return ZATHURA_ERROR_NOT_IMPLEMENTED; + } + + return plugin->functions.page_render_cairo(page, page->data, cairo, printing); +} diff --git a/page.h b/page.h new file mode 100644 index 0000000..dbac902 --- /dev/null +++ b/page.h @@ -0,0 +1,206 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef PAGE_H +#define PAGE_H + +#include +#include + +#include "types.h" + +/** + * Get the page object + * + * @param document The document + * @param index Page number + * @param error Optional error + * @return Page object or NULL if an error occured + */ +zathura_page_t* zathura_page_new(zathura_document_t* document, unsigned int + index, zathura_error_t* error); + +/** + * Frees the page object + * + * @param page The page object + * @return ZATHURA_ERROR_OK when no error occured, otherwise see + * zathura_error_t + */ +zathura_error_t zathura_page_free(zathura_page_t* page); + +/** + * Returns the associated document + * + * @param page The page object + * @return The associated document + * @return NULL if an error occured + */ +zathura_document_t* zathura_page_get_document(zathura_page_t* page); + +/** + * Returns the set id of the page + * + * @param page The page object + * @return The id of the page + */ +unsigned int zathura_page_get_index(zathura_page_t* page); + +/** + * Returns the width of the page + * + * @param page The page object + * @return Width of the page + * @return -1 If an error occured + */ +double zathura_page_get_width(zathura_page_t* page); + +/** + * Sets the new width of the page + * + * @param page The page object + * @param width The new width of the page + */ +void zathura_page_set_width(zathura_page_t* page, double width); + +/** + * Returns the height of the page + * + * @param page The page object + * @return Height of the page + * @return -1 If an error occured + */ +double zathura_page_get_height(zathura_page_t* page); + +/** + * Sets the new height of the page + * + * @param page The page object + * @param height The new height of the page + */ +void zathura_page_set_height(zathura_page_t* page, double height); + +/** + * Returns the visibility of the page + * + * @param page The page object + * @return true if the page is visible + * @return false if the page is hidden + */ +bool zathura_page_get_visibility(zathura_page_t* page); + +/** + * Sets the visibility of the page + * + * @param page The page object + * @param visibility The new visibility value + */ +void zathura_page_set_visibility(zathura_page_t* page, bool visibility); + +/** + * Returns the custom data + * + * @param page The page object + * @return The custom data or NULL + */ +void* zathura_page_get_data(zathura_page_t* page); + +/** + * Sets the custom data + * + * @param page The page object + * @param data The custom data + */ +void zathura_page_set_data(zathura_page_t* page, void* data); + +/** + * Search page + * + * @param page The page object + * @param text Search item + * @param error Set to an error value (see \ref zathura_error_t) if an + * error occured + * @return List of results + */ +girara_list_t* zathura_page_search_text(zathura_page_t* page, const char* text, zathura_error_t* error); + +/** + * Get page links + * + * @param page The page object + * @param error Set to an error value (see \ref zathura_error_t) if an + * error occured + * @return List of links + */ +girara_list_t* zathura_page_links_get(zathura_page_t* page, zathura_error_t* error); + +/** + * Free page links + * + * @param list List of links + * @return ZATHURA_ERROR_OK when no error occured, otherwise see + * zathura_error_t + */ +zathura_error_t zathura_page_links_free(girara_list_t* list); + +/** + * Get list of form fields + * + * @param page The page object + * @param error Set to an error value (see \ref zathura_error_t) if an + * error occured + * @return List of form fields + */ +girara_list_t* zathura_page_form_fields_get(zathura_page_t* page, zathura_error_t* error); + +/** + * Free list of form fields + * + * @param list List of form fields + * @return ZATHURA_ERROR_OK when no error occured, otherwise see + * zathura_error_t + */ +zathura_error_t zathura_page_form_fields_free(girara_list_t* list); + +/** + * Get list of images + * + * @param page Page + * @param error Set to an error value (see \ref zathura_error_t) if an + * error occured + * @return List of images or NULL if an error occured + */ +girara_list_t* zathura_page_images_get(zathura_page_t* page, zathura_error_t* error); + +/** + * Get image + * + * @param page Page + * @param image Image identifier + * @param error Set to an error value (see \ref zathura_error_t) if an + * error occured + * @return The cairo image surface or NULL if an error occured + */ +cairo_surface_t* zathura_page_image_get_cairo(zathura_page_t* page, zathura_image_t* image, zathura_error_t* error); + +/** + * Get text for selection + * @param page Page + * @param rectangle Selection + * @param error Set to an error value (see \ref zathura_error_t) if an error + * occured + * @return The selected text (needs to be deallocated with g_free) + */ +char* zathura_page_get_text(zathura_page_t* page, zathura_rectangle_t rectangle, zathura_error_t* error); + +/** + * Render page + * + * @param page The page object + * @param cairo Cairo object + * @param printing render for printing + * @return ZATHURA_ERROR_OK when no error occured, otherwise see + * zathura_error_t + */ +zathura_error_t zathura_page_render(zathura_page_t* page, cairo_t* cairo, bool printing); + +#endif // PAGE_H diff --git a/plugin-api.h b/plugin-api.h new file mode 100644 index 0000000..95946c4 --- /dev/null +++ b/plugin-api.h @@ -0,0 +1,244 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef PLUGIN_API_H +#define PLUGIN_API_H + +#include "page.h" +#include "document.h" +#include "links.h" +#include "version.h" + +typedef struct zathura_plugin_functions_s zathura_plugin_functions_t; + +/** + * Functions register function + * + * @param functions The functions struct + */ +typedef void (*zathura_plugin_register_function_t)(zathura_plugin_functions_t* functions); + +/** + * Sets the functions register function of the plugin + * + * @param plugin The plugin + * @param register_function The register function that registers the document + * functions + */ +void zathura_plugin_set_register_functions_function(zathura_plugin_t* plugin, + zathura_plugin_register_function_t register_function); + +/** + * Sets the functions register function of the plugin + * + * @param plugin The plugin + * @param mime_type The mime type that should be added + */ +void zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type); + +/** + * Register a plugin. + * + * @param plugin_name the name of the plugin + * @param major the plugin's major version + * @param minor the plugin's minor version + * @param rev the plugin's revision + * @param register_functions function to register the plugin's document functions + * @param mimetypes a char array of mime types supported by the plugin + */ +#define ZATHURA_PLUGIN_REGISTER(plugin_name, major, minor, rev, register_functions, mimetypes) \ + unsigned int zathura_plugin_version_major(void) { return major; } \ + unsigned int zathura_plugin_version_minor(void) { return minor; } \ + unsigned int zathura_plugin_version_revision(void) { return rev; } \ + unsigned int zathura_plugin_api_version(void) { return ZATHURA_API_VERSION; } \ + unsigned int zathura_plugin_abi_version(void) { return ZATHURA_ABI_VERSION; } \ + \ + void zathura_plugin_register(zathura_plugin_t* plugin) \ + { \ + if (plugin == NULL) { \ + return; \ + } \ + zathura_plugin_set_register_functions_function(plugin, register_functions); \ + static const char* mime_types[] = mimetypes; \ + for (size_t s = 0; s != sizeof(mime_types) / sizeof(const char*); ++s) { \ + zathura_plugin_add_mimetype(plugin, mime_types[s]); \ + } \ + } \ + +#define ZATHURA_PLUGIN_MIMETYPES(...) __VA_ARGS__ + +/** + * Opens a document + */ +typedef zathura_error_t (*zathura_plugin_document_open_t)(zathura_document_t* document); + +/** + * Frees the document + */ +typedef zathura_error_t (*zathura_plugin_document_free_t)(zathura_document_t* document, void* data); + +/** + * Generates the document index + */ +typedef girara_tree_node_t* (*zathura_plugin_document_index_generate_t)(zathura_document_t* document, void* data, zathura_error_t* error); + +/** + * Save the document + */ +typedef zathura_error_t (*zathura_plugin_document_save_as_t)(zathura_document_t* document, void* data, const char* path); + +/** + * Get list of attachments + */ +typedef girara_list_t* (*zathura_plugin_document_attachments_get_t)(zathura_document_t* document, void* data, zathura_error_t* error); + +/** + * Save attachment to a file + */ +typedef zathura_error_t (*zathura_plugin_document_attachment_save_t)(zathura_document_t* document, void* data, const char* attachment, const char* file); + +/** + * Get document information + */ +typedef girara_list_t* (*zathura_plugin_document_get_information_t)(zathura_document_t* document, void* data, zathura_error_t* error); + +/** + * Gets the page object + */ +typedef zathura_error_t (*zathura_plugin_page_init_t)(zathura_page_t* page); + +/** + * Free page + */ +typedef zathura_error_t (*zathura_plugin_page_clear_t)(zathura_page_t* page, void* data); + +/** + * Search text + */ +typedef girara_list_t* (*zathura_plugin_page_search_text_t)(zathura_page_t* page, void* data, const char* text, zathura_error_t* error); + +/** + * Get links on a page + */ +typedef girara_list_t* (*zathura_plugin_page_links_get_t)(zathura_page_t* page, void* data, zathura_error_t* error); + +/** + * Get form fields + */ +typedef girara_list_t* (*zathura_plugin_page_form_fields_get_t)(zathura_page_t* page, void* data, zathura_error_t* error); + +/** + * Get list of images + */ +typedef girara_list_t* (*zathura_plugin_page_images_get_t)(zathura_page_t* page, void* data, zathura_error_t* error); + +/** + * Get the image + */ +typedef cairo_surface_t* (*zathura_plugin_page_image_get_cairo_t)(zathura_page_t* page, void* data, zathura_image_t* image, zathura_error_t* error); + +/** + * Get text for selection + */ +typedef char* (*zathura_plugin_page_get_text_t)(zathura_page_t* page, void* data, zathura_rectangle_t rectangle, zathura_error_t* error); + +/** + * Renders the page + */ +typedef zathura_image_buffer_t* (*zathura_plugin_page_render_t)(zathura_page_t* page, void* data, zathura_error_t* error); + +/** + * Renders the page + */ +typedef zathura_error_t (*zathura_plugin_page_render_cairo_t)(zathura_page_t* page, void* data, cairo_t* cairo, bool printing); + + +struct zathura_plugin_functions_s +{ + /** + * Opens a document + */ + zathura_plugin_document_open_t document_open; + + /** + * Frees the document + */ + zathura_plugin_document_free_t document_free; + + /** + * Generates the document index + */ + zathura_plugin_document_index_generate_t document_index_generate; + + /** + * Save the document + */ + zathura_plugin_document_save_as_t document_save_as; + + /** + * Get list of attachments + */ + zathura_plugin_document_attachments_get_t document_attachments_get; + + /** + * Save attachment to a file + */ + zathura_plugin_document_attachment_save_t document_attachment_save; + + /** + * Get document information + */ + zathura_plugin_document_get_information_t document_get_information; + + /** + * Gets the page object + */ + zathura_plugin_page_init_t page_init; + + /** + * Free page + */ + zathura_plugin_page_clear_t page_clear; + + /** + * Search text + */ + zathura_plugin_page_search_text_t page_search_text; + + /** + * Get links on a page + */ + zathura_plugin_page_links_get_t page_links_get; + + /** + * Get form fields + */ + zathura_plugin_page_form_fields_get_t page_form_fields_get; + + /** + * Get list of images + */ + zathura_plugin_page_images_get_t page_images_get; + + /** + * Get the image + */ + zathura_plugin_page_image_get_cairo_t page_image_get_cairo; + + /** + * Get text for selection + */ + zathura_plugin_page_get_text_t page_get_text; + + /** + * Renders the page + */ + zathura_plugin_page_render_t page_render; + + /** + * Renders the page + */ + zathura_plugin_page_render_cairo_t page_render_cairo; +}; + + +#endif // PLUGIN_API_H diff --git a/plugin.c b/plugin.c new file mode 100644 index 0000000..3197bb5 --- /dev/null +++ b/plugin.c @@ -0,0 +1,312 @@ +/* See LICENSE file for license and copyright information */ + +#include "plugin.h" + +#include +#include + +#include +#include +#include +#include +#include + +typedef unsigned int (*zathura_plugin_version_t)(void); + +/** + * Plugin manager + */ +struct zathura_plugin_manager_s +{ + girara_list_t* plugins; /**< List of plugins */ + girara_list_t* path; /**< List of plugin paths */ + girara_list_t* type_plugin_mapping; /**< List of type -> plugin mappings */ +}; + +static bool register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plugin); +static bool plugin_mapping_new(zathura_plugin_manager_t* plugin_manager, const gchar* type, zathura_plugin_t* plugin); +static void zathura_plugin_free(zathura_plugin_t* plugin); +static void zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping); + +zathura_plugin_manager_t* +zathura_plugin_manager_new() +{ + zathura_plugin_manager_t* plugin_manager = g_malloc0(sizeof(zathura_plugin_manager_t)); + + plugin_manager->plugins = girara_list_new2((girara_free_function_t) zathura_plugin_free); + plugin_manager->path = girara_list_new2(g_free); + plugin_manager->type_plugin_mapping = girara_list_new2((girara_free_function_t)zathura_type_plugin_mapping_free); + + if (plugin_manager->plugins == NULL + || plugin_manager->path == NULL + || plugin_manager->type_plugin_mapping == NULL) { + zathura_plugin_manager_free(plugin_manager); + return NULL; + } + + return plugin_manager; +} + +void +zathura_plugin_manager_add_dir(zathura_plugin_manager_t* plugin_manager, const char* dir) +{ + if (plugin_manager == NULL || plugin_manager->path == NULL) { + return; + } + + girara_list_append(plugin_manager->path, g_strdup(dir)); +} + +void +zathura_plugin_manager_load(zathura_plugin_manager_t* plugin_manager) +{ + if (plugin_manager == NULL || plugin_manager->path == NULL) { + return; + } + + GIRARA_LIST_FOREACH(plugin_manager->path, char*, iter, plugindir) + /* read all files in the plugin directory */ + GDir* dir = g_dir_open(plugindir, 0, NULL); + if (dir == NULL) { + girara_error("could not open plugin directory: %s", plugindir); + girara_list_iterator_next(iter); + continue; + } + + char* name = NULL; + while ((name = (char*) g_dir_read_name(dir)) != NULL) { + char* path = g_build_filename(plugindir, name, NULL); + if (g_file_test(path, G_FILE_TEST_IS_REGULAR) == 0) { + girara_info("%s is not a regular file. Skipping.", path); + g_free(path); + continue; + } + + zathura_plugin_t* plugin = NULL; + + /* load plugin */ + GModule* handle = g_module_open(path, G_MODULE_BIND_LOCAL); + if (handle == NULL) { + girara_error("could not load plugin %s (%s)", path, g_module_error()); + g_free(path); + continue; + } + + /* resolve symbols and check API and ABI version*/ + zathura_plugin_api_version_t api_version = NULL; + if (g_module_symbol(handle, PLUGIN_API_VERSION_FUNCTION, (gpointer*) &api_version) == FALSE || + api_version == NULL) + { + girara_error("could not find '%s' function in plugin %s", PLUGIN_API_VERSION_FUNCTION, path); + g_free(path); + g_module_close(handle); + continue; + } + + if (api_version() != ZATHURA_API_VERSION) { + girara_error("plugin %s has been built againt zathura with a different API version (plugin: %d, zathura: %d)", + path, api_version(), ZATHURA_API_VERSION); + g_free(path); + g_module_close(handle); + continue; + } + + zathura_plugin_abi_version_t abi_version = NULL; + if (g_module_symbol(handle, PLUGIN_ABI_VERSION_FUNCTION, (gpointer*) &abi_version) == FALSE || + abi_version == NULL) + { + girara_error("could not find '%s' function in plugin %s", PLUGIN_ABI_VERSION_FUNCTION, path); + g_free(path); + g_module_close(handle); + continue; + } + + if (abi_version() != ZATHURA_ABI_VERSION) { + girara_error("plugin %s has been built againt zathura with a different ABI version (plugin: %d, zathura: %d)", + path, abi_version(), ZATHURA_ABI_VERSION); + g_free(path); + g_module_close(handle); + continue; + } + + zathura_plugin_register_service_t register_service = NULL; + if (g_module_symbol(handle, PLUGIN_REGISTER_FUNCTION, (gpointer*) ®ister_service) == FALSE || + register_service == NULL) + { + girara_error("could not find '%s' function in plugin %s", PLUGIN_REGISTER_FUNCTION, path); + g_free(path); + g_module_close(handle); + continue; + } + + plugin = g_malloc0(sizeof(zathura_plugin_t)); + plugin->content_types = girara_list_new2(g_free); + plugin->handle = handle; + + register_service(plugin); + + /* register functions */ + if (plugin->register_function == NULL) { + girara_error("plugin has no document functions register function"); + g_free(path); + g_module_close(handle); + continue; + } + + plugin->register_function(&(plugin->functions)); + + bool ret = register_plugin(plugin_manager, plugin); + if (ret == false) { + girara_error("could not register plugin %s", path); + zathura_plugin_free(plugin); + } else { + girara_info("successfully loaded plugin %s", path); + + zathura_plugin_version_t major = NULL, minor = NULL, rev = NULL; + g_module_symbol(handle, PLUGIN_VERSION_MAJOR_FUNCTION, (gpointer*) &major); + g_module_symbol(handle, PLUGIN_VERSION_MINOR_FUNCTION, (gpointer*) &minor); + g_module_symbol(handle, PLUGIN_VERSION_REVISION_FUNCTION, (gpointer*) &rev); + if (major != NULL && minor != NULL && rev != NULL) { + girara_debug("plugin '%s': version %u.%u.%u", path, major(), minor(), rev()); + } + } + + g_free(path); + } + g_dir_close(dir); + GIRARA_LIST_FOREACH_END(zathura->plugins.path, char*, iter, plugindir); +} + +zathura_plugin_t* +zathura_plugin_manager_get_plugin(zathura_plugin_manager_t* plugin_manager, const char* type) +{ + if (plugin_manager == NULL || plugin_manager->type_plugin_mapping == NULL || type == NULL) { + return NULL; + } + + zathura_plugin_t* plugin = NULL; + GIRARA_LIST_FOREACH(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping) + if (g_content_type_equals(type, mapping->type)) { + plugin = mapping->plugin; + break; + } + GIRARA_LIST_FOREACH_END(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping); + + return plugin; +} + +void +zathura_plugin_manager_free(zathura_plugin_manager_t* plugin_manager) +{ + if (plugin_manager == NULL) { + return; + } + + if (plugin_manager->plugins != NULL) { + girara_list_free(plugin_manager->plugins); + } + + if (plugin_manager->path != NULL) { + girara_list_free(plugin_manager->path); + } + + if (plugin_manager->type_plugin_mapping != NULL) { + girara_list_free(plugin_manager->type_plugin_mapping); + } + + g_free(plugin_manager); +} + +static bool +register_plugin(zathura_plugin_manager_t* plugin_manager, zathura_plugin_t* plugin) +{ + if (plugin == NULL + || plugin->content_types == NULL + || plugin->register_function == NULL + || plugin_manager == NULL + || plugin_manager->plugins == NULL) { + girara_error("plugin: could not register\n"); + return false; + } + + bool at_least_one = false; + GIRARA_LIST_FOREACH(plugin->content_types, gchar*, iter, type) + if (plugin_mapping_new(plugin_manager, type, plugin) == false) { + girara_error("plugin: already registered for filetype %s\n", type); + } else { + at_least_one = true; + } + GIRARA_LIST_FOREACH_END(plugin->content_types, gchar*, iter, type); + + if (at_least_one == true) { + girara_list_append(plugin_manager->plugins, plugin); + } + + return at_least_one; +} + +static bool +plugin_mapping_new(zathura_plugin_manager_t* plugin_manager, const gchar* type, zathura_plugin_t* plugin) +{ + g_return_val_if_fail(plugin_manager != NULL, false); + g_return_val_if_fail(type != NULL, false); + g_return_val_if_fail(plugin != NULL, false); + + GIRARA_LIST_FOREACH(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping) + if (g_content_type_equals(type, mapping->type)) { + girara_list_iterator_free(iter); + return false; + } + GIRARA_LIST_FOREACH_END(plugin_manager->type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping); + + zathura_type_plugin_mapping_t* mapping = g_malloc(sizeof(zathura_type_plugin_mapping_t)); + mapping->type = g_strdup(type); + mapping->plugin = plugin; + girara_list_append(plugin_manager->type_plugin_mapping, mapping); + + return true; +} + +static void +zathura_type_plugin_mapping_free(zathura_type_plugin_mapping_t* mapping) +{ + if (mapping == NULL) { + return; + } + + g_free((void*)mapping->type); + g_free(mapping); +} + +static void +zathura_plugin_free(zathura_plugin_t* plugin) +{ + if (plugin == NULL) { + return; + } + + g_module_close(plugin->handle); + girara_list_free(plugin->content_types); + g_free(plugin); +} + +/* plugin-api.h */ +void +zathura_plugin_set_register_functions_function(zathura_plugin_t* plugin, zathura_plugin_register_function_t register_function) +{ + if (plugin == NULL || register_function == NULL) { + return; + } + + plugin->register_function = register_function; +} + +void +zathura_plugin_add_mimetype(zathura_plugin_t* plugin, const char* mime_type) +{ + if (plugin == NULL || mime_type == NULL) { + return; + } + + girara_list_append(plugin->content_types, g_content_type_from_mime_type(mime_type)); +} diff --git a/plugin.h b/plugin.h new file mode 100644 index 0000000..abc08cc --- /dev/null +++ b/plugin.h @@ -0,0 +1,101 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef PLUGIN_H +#define PLUGIN_H + +#include +#include + +#include "types.h" +#include "plugin-api.h" +#include "version.h" +#include "zathura.h" + +#define PLUGIN_REGISTER_FUNCTION "zathura_plugin_register" +#define PLUGIN_API_VERSION_FUNCTION "zathura_plugin_api_version" +#define PLUGIN_ABI_VERSION_FUNCTION "zathura_plugin_abi_version" +#define PLUGIN_VERSION_MAJOR_FUNCTION "zathura_plugin_version_major" +#define PLUGIN_VERSION_MINOR_FUNCTION "zathura_plugin_version_minor" +#define PLUGIN_VERSION_REVISION_FUNCTION "zathura_plugin_version_revision" + +/** + * Document plugin structure + */ +struct zathura_plugin_s +{ + girara_list_t* content_types; /**< List of supported content types */ + zathura_plugin_register_function_t register_function; /**< Document open function */ + zathura_plugin_functions_t functions; /**< Document functions */ + GModule* handle; /**< DLL handle */ +}; + +/** + * Creates a new instance of the plugin manager + * + * @return A plugin manager object or NULL if an error occured + */ +zathura_plugin_manager_t* zathura_plugin_manager_new(); + +/** + * Adds a plugin directory to the plugin manager + * + * @param plugin_manager The plugin manager + * @param dir Path to a directory with plugins + */ +void zathura_plugin_manager_add_dir(zathura_plugin_manager_t* plugin_manager, const char* dir); + +/** + * Loads all plugins available in the previously given directories + * + * @param plugin_manager The plugin manager + */ +void zathura_plugin_manager_load(zathura_plugin_manager_t* plugin_manager); + +/** + * Returns the (if available) associated plugin + * + * @param plugin_manager The plugin manager + * @param type The document type + * @return The plugin or NULL if no matching plugin is available + */ +zathura_plugin_t* zathura_plugin_manager_get_plugin(zathura_plugin_manager_t* plugin_manager, const char* type); + +/** + * Frees the plugin manager + * + * @param plugin_manager + */ +void zathura_plugin_manager_free(zathura_plugin_manager_t* plugin_manager); + +/** + * Plugin mapping + */ +typedef struct zathura_type_plugin_mapping_s +{ + const gchar* type; /**< Plugin type */ + zathura_plugin_t* plugin; /**< Mapped plugin */ +} zathura_type_plugin_mapping_t; + +/** + * Function prototype that is called to register a document plugin + * + * @param The document plugin + */ +typedef void (*zathura_plugin_register_service_t)(zathura_plugin_t*); + +/** + * Function prototype that is called to get the plugin's API version. + * + * @return plugin's API version + */ +typedef unsigned int (*zathura_plugin_api_version_t)(); + +/** + * Function prototype that is called to get the ABI version the plugin is built + * against. + * + * @return plugin's ABI version + */ +typedef unsigned int (*zathura_plugin_abi_version_t)(); + +#endif // PLUGIN_H diff --git a/po/Makefile b/po/Makefile index aaa9f32..b3d5ef0 100644 --- a/po/Makefile +++ b/po/Makefile @@ -37,7 +37,7 @@ update-po: ${PROJECT}.pot install: ${MOS} $(ECHO) installing translations $(QUIET)set -e && for f in $^ ; do \ - mkdir -p $(DESTDIR)$(LOCALEDIR)/`dirname $$f`; \ + mkdir -p -m 755 $(DESTDIR)$(LOCALEDIR)/`dirname $$f`; \ install -m 644 $$f $(DESTDIR)$(LOCALEDIR)/`dirname $$f` ; \ done diff --git a/po/de.po b/po/de.po index ea6a2e5..2383bc1 100644 --- a/po/de.po +++ b/po/de.po @@ -1,293 +1,359 @@ -# zathura - language file (german) +# zathura - language file (German) # See LICENSE file for license and copyright information +# +# Translators: msgid "" msgstr "" -"Project-Id-Version: zathura 0.1.1\n" -"Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-03-24 18:49+0100\n" -"PO-Revision-Date: 2012-03-05 17:26+0100\n" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-04-03 15:25+0000\n" "Last-Translator: Sebastian Ramacher \n" "Language-Team: pwmt.org \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" -#: ../callbacks.c:152 -msgid "Failed to run xdg-open." -msgstr "Konnte xdg-open nicht ausführen." - -#: ../callbacks.c:178 +#: ../callbacks.c:175 #, c-format msgid "Invalid input '%s' given." msgstr "Ungültige Eingabe '%s' angegeben." -#: ../callbacks.c:212 +#: ../callbacks.c:203 #, c-format msgid "Invalid index '%s' given." msgstr "Ungültiger Index '%s' angegeben." -#: ../commands.c:30 ../commands.c:65 ../commands.c:92 ../commands.c:134 -#: ../commands.c:230 ../commands.c:247 ../commands.c:273 ../commands.c:347 -#: ../commands.c:382 ../shortcuts.c:810 +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 msgid "No document opened." msgstr "Kein Dokument geöffnet." -#: ../commands.c:36 ../commands.c:71 ../commands.c:98 ../commands.c:352 +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 msgid "Invalid number of arguments given." msgstr "Ungültige Anzahl an Argumenten angegeben." -#: ../commands.c:44 +#: ../commands.c:47 #, c-format msgid "Bookmark successfuly updated: %s" msgstr "Lesezeichen erfolgreich aktualisiert: %s." -#: ../commands.c:50 +#: ../commands.c:53 #, c-format msgid "Could not create bookmark: %s" msgstr "Konnte Lesezeichen nicht erstellen: %s" -#: ../commands.c:54 +#: ../commands.c:57 #, c-format msgid "Bookmark successfuly created: %s" msgstr "Lesezeichen erfolgreich erstellt: %s" -#: ../commands.c:77 +#: ../commands.c:80 #, c-format msgid "Removed bookmark: %s" msgstr "Lesezeichen entfernt: %s" -#: ../commands.c:79 +#: ../commands.c:82 #, c-format msgid "Failed to remove bookmark: %s" msgstr "Konnte Lesezeichen nicht entfernen: %s" -#: ../commands.c:105 +#: ../commands.c:108 #, c-format msgid "No such bookmark: %s" msgstr "Lesezeichen existiert nicht: %s" -#: ../commands.c:174 +#: ../commands.c:159 ../commands.c:181 msgid "No information available." msgstr "Keine Information verfügbar." -#: ../commands.c:198 +#: ../commands.c:219 msgid "Too many arguments." msgstr "Zu viele Argumente angegeben." -#: ../commands.c:207 +#: ../commands.c:228 msgid "No arguments given." msgstr "Keine Argumente angegeben." -#: ../commands.c:253 ../commands.c:279 +#: ../commands.c:287 ../commands.c:313 msgid "Document saved." msgstr "Dokument gespeichert." -#: ../commands.c:255 ../commands.c:281 +#: ../commands.c:289 ../commands.c:315 msgid "Failed to save document." msgstr "Konnte Dokument nicht speichern." -#: ../commands.c:258 ../commands.c:284 +#: ../commands.c:292 ../commands.c:318 msgid "Invalid number of arguments." msgstr "Ungültige Anzahl an Argumenten." -#: ../commands.c:365 +#: ../commands.c:420 #, c-format msgid "Couldn't write attachment '%s' to '%s'." msgstr "Konnte Anhang '%s' nicht nach '%s' schreiben." -#: ../commands.c:367 +#: ../commands.c:422 #, c-format msgid "Wrote attachment '%s' to '%s'." msgstr "Anhang '%s' nach '%s' geschrieben." -#: ../commands.c:395 +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "Anhang '%s' nach '%s' geschrieben." + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "Konnte Anhang '%s' nicht nach '%s' schreiben." + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "Unbekannter Anhanng oder Bild '%s'." + +#: ../commands.c:509 msgid "Argument must be a number." msgstr "Das Argument ist keine Zahl." -#: ../page-widget.c:572 +#: ../completion.c:250 #, c-format -msgid "Copied selected text to clipbard: %s" -msgstr "Der gewählte Text wurde in die Zwischenablage kopiert: %s" +msgid "Page %d" +msgstr "Seite %d" -#: ../page-widget.c:664 -msgid "Copy image" -msgstr "Bild kopieren" +#: ../completion.c:293 +msgid "Attachments" +msgstr "Speichere Anhänge" -#: ../document.c:439 ../document.c:463 ../document.c:482 ../document.c:504 -#: ../document.c:523 ../document.c:545 ../document.c:564 ../document.c:607 -#: ../document.c:627 ../document.c:650 ../document.c:679 ../document.c:708 -#: ../document.c:732 ../document.c:753 ../document.c:774 -#, c-format -msgid "%s not implemented" -msgstr "%s ist nicht implementiert." - -#: ../shortcuts.c:729 -msgid "This document does not contain any index" -msgstr "Dieses Dokument beinhaltet kein Inhaltsverzeichnis." - -#: ../zathura.c:57 -msgid "Reparents to window specified by xid" -msgstr "Reparentiert zathura an das Fenster mit der xid" - -#: ../zathura.c:58 -msgid "Path to the config directory" -msgstr "Pfad zum Konfigurationsverzeichnis" - -#: ../zathura.c:59 -msgid "Path to the data directory" -msgstr "Pfad zum Datenverzeichnis" - -#: ../zathura.c:60 -msgid "Path to the directories containing plugins" -msgstr "Pfad zum Pluginverzeichnis" - -#: ../zathura.c:61 -msgid "Fork into the background" -msgstr "Forkt den Prozess in den Hintergrund" - -#: ../zathura.c:62 -msgid "Log level (debug, info, warning, error)" -msgstr "Log-Stufe (debug, info, warning, error)" - -#: ../zathura.c:228 ../zathura.c:608 -msgid "[No name]" -msgstr "[Kein Name]" +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "Bilder" #. zathura settings -#: ../config.c:83 +#: ../config.c:98 msgid "Database backend" msgstr "Datenbank Backend" -#: ../config.c:85 +#: ../config.c:100 msgid "Zoom step" msgstr "Vergrößerungsstufe" -#: ../config.c:87 +#: ../config.c:102 msgid "Padding between pages" msgstr "Abstand zwischen den Seiten" -#: ../config.c:89 +#: ../config.c:104 msgid "Number of pages per row" msgstr "Anzahl der Seiten in einer Reihe" -#: ../config.c:91 +#: ../config.c:106 msgid "Scroll step" msgstr "Schrittgröße beim Scrollen" -#: ../config.c:93 +#: ../config.c:108 msgid "Zoom minimum" msgstr "Minimale Vergrößerungsstufe" -#: ../config.c:95 +#: ../config.c:110 msgid "Zoom maximum" msgstr "Maximale Vergrößerungsstufe" -#: ../config.c:97 -msgid "Store unvisible pages only for some time (in seconds)" -msgstr "Lebensdauer für nicht angezeigte Seiten (in Sekunden)" +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "" -#: ../config.c:98 -msgid "Amount of seconds between the checks for invisible pages" -msgstr "Anzahl der Sekunden zwischen jeder Prüfung von nicht angezeigten Seiten" +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "" +"Anzahl der Sekunden zwischen jeder Prüfung von nicht angezeigten Seiten" -#: ../config.c:100 +#: ../config.c:115 msgid "Recoloring (dark color)" msgstr "Neufärben (Dunkle Farbe)" -#: ../config.c:102 +#: ../config.c:117 msgid "Recoloring (light color)" msgstr "Neufärben (Helle Farbe)" -#: ../config.c:104 +#: ../config.c:119 msgid "Color for highlighting" msgstr "Farbe für eine Markierung" -#: ../config.c:106 +#: ../config.c:121 msgid "Color for highlighting (active)" msgstr "Farbe für die aktuelle Markierung" -#: ../config.c:110 +#: ../config.c:125 msgid "Recolor pages" msgstr "Färbe die Seiten ein" -#: ../config.c:112 +#: ../config.c:127 msgid "Wrap scrolling" msgstr "Scroll-Umbruch" -#: ../config.c:114 +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "Gehe Anzahl der Seiten in einer Reihe weiter" + +#: ../config.c:131 msgid "Transparency for highlighting" msgstr "Transparenz einer Markierung" -#: ../config.c:116 +#: ../config.c:133 msgid "Render 'Loading ...'" msgstr "Zeige 'Lädt...'-Text beim Zeichnen einer Seite" -#: ../config.c:117 +#: ../config.c:134 msgid "Adjust to when opening file" msgstr "Seite einpassen" -#: ../config.c:119 +#: ../config.c:136 msgid "Show hidden files and directories" msgstr "Zeige versteckte Dateien und Ordner an" -#: ../config.c:121 +#: ../config.c:138 msgid "Show directories" msgstr "Zeige Ordner an" -#: ../config.c:123 +#: ../config.c:140 msgid "Always open on first page" msgstr "Öffne Dokument immer auf der ersten Seite" +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + #. define default inputbar commands -#: ../config.c:243 +#: ../config.c:266 msgid "Add a bookmark" msgstr "Füge Lesezeichen hinzu" -#: ../config.c:244 +#: ../config.c:267 msgid "Delete a bookmark" msgstr "Lösche ein Lesezeichen" -#: ../config.c:245 +#: ../config.c:268 msgid "List all bookmarks" msgstr "Liste all Lesezeichen auf" -#: ../config.c:246 +#: ../config.c:269 msgid "Close current file" msgstr "Schließe das aktuelle Dokument" -#: ../config.c:247 +#: ../config.c:270 msgid "Show file information" msgstr "Zeige Dokumentinformationen an" -#: ../config.c:248 +#: ../config.c:271 msgid "Show help" msgstr "Zeige Hilfe an" -#: ../config.c:249 +#: ../config.c:272 msgid "Open document" msgstr "Öffne Dokument" -#: ../config.c:250 +#: ../config.c:273 msgid "Close zathura" msgstr "Beende zathura" -#: ../config.c:251 +#: ../config.c:274 msgid "Print document" msgstr "Drucke Dokument" -#: ../config.c:252 +#: ../config.c:275 msgid "Save document" msgstr "Speichere Dokument" -#: ../config.c:253 +#: ../config.c:276 msgid "Save document (and force overwriting)" msgstr "Speichere Dokument (und überschreibe bestehende)" -#: ../config.c:254 +#: ../config.c:277 msgid "Save attachments" msgstr "Speichere Anhänge" -#: ../config.c:255 +#: ../config.c:278 msgid "Set page offset" msgstr "Setze den Seitenabstand" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "Der gewählte Text wurde in die Zwischenablage kopiert: %s" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Bild kopieren" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "Bild speichern als" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "Dieses Dokument beinhaltet kein Inhaltsverzeichnis." + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "Konnte xdg-open nicht ausführen." + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "Reparentiert zathura an das Fenster mit der xid" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "Pfad zum Konfigurationsverzeichnis" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "Pfad zum Datenverzeichnis" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "Pfad zum Pluginverzeichnis" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "Forkt den Prozess in den Hintergrund" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "Dokument Passwort" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "Log-Stufe (debug, info, warning, error)" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[Kein Name]" diff --git a/po/eo.po b/po/eo.po new file mode 100644 index 0000000..6f8c39f --- /dev/null +++ b/po/eo.po @@ -0,0 +1,358 @@ +# zathura - language file (Esperanto) +# See LICENSE file for license and copyright information +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-04-21 14:04+0000\n" +"Last-Translator: Sebastian Ramacher \n" +"Language-Team: LANGUAGE \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "Nevalida enigo '%s' uzata." + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "Nevalida indekso '%s' uzata." + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "Neniu dokumento malfermita." + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "Nevalida nombro da argumentoj uzata." + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "Paĝosigno sukcese aktualigita: %s" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "Neeble krei paĝosignon: %s" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "Paĝosigno sukcese kreita: %s" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "Paĝosigno forigita: %s" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "Neeble forigi paĝosignon: %s" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "Neniu paĝosigno: %s" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "Neniu informacio disponebla." + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "Tro multe da argumentoj." + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "Neniuj argumentoj uzata." + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "Dokumento konservita." + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "Neeble konservi dokumenton." + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "Nevalida nombro da argumentoj." + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "Neeble skribi kunsendaĵon '%s' en '%s'." + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "Skribis kunsendaĵon '%s' en '%s'." + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "Skribis kunsendaĵon '%s' en '%s'." + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "Neeble skribi kunsendaĵon '%s' en '%s'." + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "" + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "Argumento devas esti nombro." + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "Konservu kunsendaĵojn" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "" + +#: ../config.c:100 +msgid "Zoom step" +msgstr "Zompaŝo" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "Interpaĝa plenigo" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "Nombro da paĝoj po vico" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "Rulumpaŝo" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "Mimimuma zomo" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "Maksimuma zomo" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "Vivdaŭro (sekunda) de kaŝita paĝo" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "Nombro da sekundoj inter repurigo de kaŝmemoro" + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "Rekolorigo (malhela koloro)" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "Rekolorigo (hela koloro)" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "Koloro por fonlumo" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "Koloro por fonlumo (aktiva)" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "Rekoloru paĝojn" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "Ĉirkaŭflua rulumado" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "Travidebleco por fonlumo" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "Bildigu 'Ŝargado ...'" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "Adaptaĵo ĉe malfermo de dosiero" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "Montru kaŝitajn dosierojn kaj -ujojn" + +#: ../config.c:138 +msgid "Show directories" +msgstr "Montru dosierujojn" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "Ĉiam malfermu ĉe unua paĝo" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "Aldonu paĝosignon" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Forigu paĝosignon" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "Listigu ĉiujn paĝosignojn" + +#: ../config.c:269 +msgid "Close current file" +msgstr "Fermu nunan dosieron" + +#: ../config.c:270 +msgid "Show file information" +msgstr "Montru dosiera informacio" + +#: ../config.c:271 +msgid "Show help" +msgstr "Montru helpon" + +#: ../config.c:272 +msgid "Open document" +msgstr "Malfermu dokumenton" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "Fermu zathura" + +#: ../config.c:274 +msgid "Print document" +msgstr "Presu dokumenton" + +#: ../config.c:275 +msgid "Save document" +msgstr "Konservu dokumenton" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "Konservu dokumenton (deviga anstataŭo)" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "Konservu kunsendaĵojn" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "Agordu paĝdelokado" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "Selektita teksto estas kopiita en la poŝo: %s" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Kopiu bildon" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "Ĉi-tiu dokumento enhavas neniam indekson." + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "Fiaskis iro de xdg-open" + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "Vojo al la agorda dosierujo" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "Vojo al la datuma dosierujo" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "Vojoj al dosierujoj enhavantaj kromaĵojn" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "Nivelo de ĵurnalo (debug, info, warning, error)" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[Neniu nomo]" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..3570d88 --- /dev/null +++ b/po/es.po @@ -0,0 +1,360 @@ +# zathura - language file (Spanish) +# See LICENSE file for license and copyright information +# +# Translators: +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-04-03 15:25+0000\n" +"Last-Translator: Moritz Lipp \n" +"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/" +"zathura/language/es/)\n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "Entrada inválida: '%s'." + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "Índice invalido: '%s'." + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "Ningún documento abierto." + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "Número de argumentos inválido." + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "Favorito actualizado con éxitosamente: %s" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "Error al crear favorito: %s" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "Favorito creado con éxitosamente: %s" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "Favorito eliminado: %s" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "Error al eliminar el favorito: %s" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "No existe el favorito: %s" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "No hay información disponible." + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "Demasiados argumentos." + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "Ningún argumento recibido." + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "Documento guardado." + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "Error al guardar el documento." + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "Número de argumentos inválido." + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "No se pudo escribir el fichero adjunto '%s' a '%s'." + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "Escrito fichero adjunto '%s' a '%s'." + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "Escrito fichero adjunto '%s' a '%s'." + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "No se pudo escribir el fichero adjunto '%s' a '%s'." + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "" + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "El argumento ha de ser un número." + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "Guardar ficheros adjuntos" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "Base de datos" + +#: ../config.c:100 +msgid "Zoom step" +msgstr "Unidad de zoom" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "Separación entre páginas" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "Número de páginas por fila" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "Unidad de desplazamiento" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "Zoom mínimo" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "Zoom máximo" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "" +"Cantidad de segundos entre las comprobaciones de las páginas invisibles" + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "Recoloreado (color oscuro)" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "Recoloreado (color claro)" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "Color para destacar" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "Color para destacar (activo)" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "Recolorear páginas" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "Navegación/Scroll cíclica/o" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "Transparencia para el destacado" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "Renderizado 'Cargando ...'" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "Ajustarse al abrir un fichero" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "Mostrar directorios y ficheros ocultos" + +#: ../config.c:138 +msgid "Show directories" +msgstr "Mostrar directorios" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "Abrir siempre la primera página" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "Añadir Favorito" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Eliminar Favorito" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "Listar favoritos" + +#: ../config.c:269 +msgid "Close current file" +msgstr "Cerrar fichero actual" + +#: ../config.c:270 +msgid "Show file information" +msgstr "Mostrar información del fichero" + +#: ../config.c:271 +msgid "Show help" +msgstr "Mostrar ayuda" + +#: ../config.c:272 +msgid "Open document" +msgstr "Abrir documento" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "Salir de zathura" + +#: ../config.c:274 +msgid "Print document" +msgstr "Imprimir documento" + +#: ../config.c:275 +msgid "Save document" +msgstr "Guardar documento" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "Guardar documento (y sobreescribir)" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "Guardar ficheros adjuntos" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "Asignar el desplazamiento de página" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "Se ha copiado el texto seleccionado al portapapeles: %s" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Copiar imagen" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "Este documento no contiene ningún índice" + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "Error al tratar de ejecutar xdg-open" + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "Reasignar a la ventana especificada por xid" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "Ruta al directorio de configuración" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "Ruta para el directorio de datos" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "Ruta a los directorios que contienen los plugins" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "Fork, ejecutándose en background" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "Nivel de log (debug, info, warning, error)" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[Sin nombre]" diff --git a/po/es_CL.po b/po/es_CL.po new file mode 100644 index 0000000..fc16889 --- /dev/null +++ b/po/es_CL.po @@ -0,0 +1,361 @@ +# zathura - language file (Spanish (Chile)) +# See LICENSE file for license and copyright information +# +# Translators: +# , 2012. +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-04-03 15:26+0000\n" +"Last-Translator: watsh1ken \n" +"Language-Team: Spanish (Chile) (http://www.transifex.net/projects/p/zathura/" +"language/es_CL/)\n" +"Language: es_CL\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "Entrada inválida: '%s'." + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "Índice invalido: '%s'." + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "Ningún documento abierto." + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "Número de argumentos inválido." + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "Marcador actualizado exitosamente: %s" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "No se pudo crear marcador: %s" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "Marcador creado exitosamente: %s" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "Marcador eliminado: %s" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "Error al eliminar marcador: %s" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "No existe marcador: %s" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "No hay información disponible." + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "Demasiados argumentos." + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "Ningún argumento recibido." + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "Documento guardado." + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "Error al guardar el documento." + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "Número de argumentos inválido." + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "No se pudo escribir el fichero adjunto '%s' a '%s'." + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "Fichero adjunto escrito '%s' a '%s'." + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "Fichero adjunto escrito '%s' a '%s'." + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "No se pudo escribir el fichero adjunto '%s' a '%s'." + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "" + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "El argumento debe ser un número." + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "Guardar archivos adjuntos" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "Fin de la base de datos." + +#: ../config.c:100 +msgid "Zoom step" +msgstr "Unidad de zoom" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "Separación entre páginas" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "Numero de páginas por fila" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "Unidad de desplazamiento" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "Zoom mínimo" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "Zoom máximo" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "" +"Cantidad de segundos entre las comprobaciones de las páginas invisibles" + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "Recolorando (color oscuro)" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "Recolorando (color claro)" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "Color para destacar" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "Color para destacar (activo)" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "Recolorar páginas" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "Scroll cíclico" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "Transparencia para lo destacado" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "Renderizando 'Cargando...'" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "Ajustar al abrirse un archivo" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "Mostrar archivos ocultos y directorios" + +#: ../config.c:138 +msgid "Show directories" +msgstr "Mostrar directorios" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "Siempre abrir en primera página" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "Agregar un marcador" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Eliminar un marcador" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "Listar todos los marcadores" + +#: ../config.c:269 +msgid "Close current file" +msgstr "Cerrar archivo actual" + +#: ../config.c:270 +msgid "Show file information" +msgstr "Mostrar información del archivo" + +#: ../config.c:271 +msgid "Show help" +msgstr "Mostrar ayuda" + +#: ../config.c:272 +msgid "Open document" +msgstr "Abrir documento" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "Cerrar zathura" + +#: ../config.c:274 +msgid "Print document" +msgstr "Imprimir documento" + +#: ../config.c:275 +msgid "Save document" +msgstr "Guardar documento" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "Guardar documento (y forzar sobreescritura)" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "Guardar archivos adjuntos" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "Asignar desplazamiento de la página" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "Texto seleccionado copiado al portapapeles: %s" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Copiar imagen" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "Este document no contiene índice" + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "Error al ejecutar xdg-open." + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "Reasignar a la ventana especificada por xid" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "Ruta al directorio de configuración" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "Ruta al directorio de datos" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "Ruta al directorio que contiene plugins" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "Ejecución en background" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "Nivel de log (debug, info, warning, error)" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[Sin nombre]" diff --git a/po/et.po b/po/et.po new file mode 100644 index 0000000..3e66bb7 --- /dev/null +++ b/po/et.po @@ -0,0 +1,360 @@ +# zathura - language file (Estonian) +# See LICENSE file for license and copyright information +# +# Translators: +# Rivo Zängov , 2012. +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-04-03 15:25+0000\n" +"Last-Translator: Rivo Zängov \n" +"Language-Team: Estonian (http://www.transifex.net/projects/p/zathura/" +"language/et/)\n" +"Language: et\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "" + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "" + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "" + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "" + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "" + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "" + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "" + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "" + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "" + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "" + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "" + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "" + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "" + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "" + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "" + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "" + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "Salvesta manused" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "" + +#: ../config.c:100 +msgid "Zoom step" +msgstr "" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "" + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "Esiletõstmise värv" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "Esiletõstmise värv (aktiivne)" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "" + +#: ../config.c:138 +msgid "Show directories" +msgstr "Näita kaustasid" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "Ava alati esimene leht" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "Lisa järjehoidja" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Kustuta järjehoidja" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "Näita kõiki järjehoidjaid" + +#: ../config.c:269 +msgid "Close current file" +msgstr "Sulge praegune fail" + +#: ../config.c:270 +msgid "Show file information" +msgstr "Näita faili infot" + +#: ../config.c:271 +msgid "Show help" +msgstr "Näita abiinfot" + +#: ../config.c:272 +msgid "Open document" +msgstr "Ava dokument" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "Sule zathura" + +#: ../config.c:274 +msgid "Print document" +msgstr "Prindi dokument" + +#: ../config.c:275 +msgid "Save document" +msgstr "Salvesta dokument" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "Salvesta manused" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Kopeeri pilt" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "" + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "" + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[Nime pole]" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..0cb6841 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,360 @@ +# zathura - language file (French) +# See LICENSE file for license and copyright information +# +# Translators: +# Quentin Stiévenart , 2012. +# Stéphane Aulery , 2012. +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-06-06 00:02+0000\n" +"Last-Translator: Stéphane Aulery \n" +"Language-Team: French (http://www.transifex.net/projects/p/zathura/language/fr/)\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: fr\n" +"Plural-Forms: nplurals=2; plural=(n > 1)\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "Entrée invalide : '%s'" + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "Index invalide : '%s'" + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "Aucun document ouvert." + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "Nombre d'arguments invalide." + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "Marque page mis à jour avec succès : %s" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "Impossible de créer le marque page: %s" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "Marque page créé avec succès : %s" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "Marque page supprimé : %s" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "Échec lors de la suppression du marque page : %s" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "Aucun marque page : %s" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "Aucune information disponible." + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "Trop d'arguments." + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "Aucun argument passé." + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "Document enregistré." + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "Échec lors de l'enregistrement du document." + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "Nombre d'arguments invalide." + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "Impossible d'écrire la pièce jointe '%s' dans '%s'." + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "Ecriture de la pièce jointe '%s' dans '%s'." + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "Écriture de l'image '%s' dans '%s'." + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "Impossible d'écrire l'image '%s' dans '%s'." + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "Image '%s' inconnue" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "Pièce jointe ou image '%s' inconnue." + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "L'argument doit être un nombre." + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "Page %d" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "Pièces jointes" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "Images" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "Gestionnaire de base de données" + +#: ../config.c:100 +msgid "Zoom step" +msgstr "Facteur de zoom" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "Espacement entre les pages" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "Nombre de page par rangée" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "Facteur de défilement" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "Zoom minimum" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "Zoom maximum" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "Durée de vie (en secondes) d'une page cachée" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "Délai en secondes entre chaque purge du cache." + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "Recolorisation (couleurs sombres)" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "Recolorisation (couleurs claires)" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "Couleur de surbrillance" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "Couleur de surbrillance (active)" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "Recoloriser les pages" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "Défiler lors du renvoi à la ligne" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "Augmenter le nombre de pages par rangée" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "Transparence de la surbrillance" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "Rendu 'Chargement...'" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "Ajuster à l'ouverture du fichier" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "Montrer les fichiers et dossiers cachés" + +#: ../config.c:138 +msgid "Show directories" +msgstr "Montrer les dossiers" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "Toujours ouvrir à la première page" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "Surligner les résultats de la recherche" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "Effacer les résultats de recherche en cas d'abandon" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "Ajouter un marque-page" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Supprimer un marque-page" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "Lister tous les marque-pages" + +#: ../config.c:269 +msgid "Close current file" +msgstr "Fermer le fichier actuel" + +#: ../config.c:270 +msgid "Show file information" +msgstr "Montrer les informations sur le fichier" + +#: ../config.c:271 +msgid "Show help" +msgstr "Afficher l'aide" + +#: ../config.c:272 +msgid "Open document" +msgstr "Ouvrir un document" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "Quitter Zathura" + +#: ../config.c:274 +msgid "Print document" +msgstr "Imprimer un document" + +#: ../config.c:275 +msgid "Save document" +msgstr "Sauver un document" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "Sauver un document (et forcer l'écrasement)" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "Enregistrer les pièces jointes" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "Régler le décalage de page" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "Marquer l'emplacement actuel dans le document" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "Supprimer les marques indiquées" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "Ne pas surligner les résultats de la recherche actuelle" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "Surligner les résultats de la recherche actuelle" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "Copie du texte sélectionné dans le presse-papiers : %s" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Copier l'image" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "Enregistrer l'image sous" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "Ce document ne contient pas d'index" + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "Échec lors du lancement de xdg-open" + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "Rattacher à la fenêtre spécifiée par xid" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "Chemin vers le dossier de configuration" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "Chemin vers le dossier de données" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "Chemin vers le dossier de plugins" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "Forker en arrière-plan" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "Mot de passe du document" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "Niveau d'affichage (debug, info, warning, error)" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[Sans nom]" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..831029e --- /dev/null +++ b/po/pl.po @@ -0,0 +1,361 @@ +# zathura - language file (Polish) +# See LICENSE file for license and copyright information +# +# Translators: +# p , 2012. +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-04-03 16:07+0000\n" +"Last-Translator: p \n" +"Language-Team: Polish (http://www.transifex.net/projects/p/zathura/language/" +"pl/)\n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2)\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "Nieprawidłowy argument: %s" + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "Nieprawidłowy indeks: %s" + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "Nie otwarto żadnego pliku" + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "Nieprawidłowa liczba parametrów polecenia" + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "Zaktualizowano zakładkę: %s" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "Nie można stworzyć zakładki: %s" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "Utworzono zakładkę: %s" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "Usunięto zakładkę: %s" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "Nie można usunąć zakładki: %s" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "Nie znaleziono zakładki: %s" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "Brak informacji o pliku" + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "Za dużo parametrów polecenia" + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "Nie podano parametrów polecenia" + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "Zapisano dokument" + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "Błąd zapisu" + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "Niewłaściwa liczba parametrów polecenia" + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "Nie można dodać załącznika %s do pliku %s" + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "Zapisano załącznik %s do pliku %s" + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "Zapisano załącznik %s do pliku %s" + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "Nie można dodać załącznika %s do pliku %s" + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "" + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "Parametr polecenia musi być liczbą" + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "Zapisz załączniki" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "Baza danych" + +#: ../config.c:100 +msgid "Zoom step" +msgstr "Skok powiększenia" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "Odstęp pomiędzy stronami" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "Liczba stron w wierszu" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "Skok przewijania" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "Minimalne powiększenie" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "Maksymalne powiększenie" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "Czas życia niewidocznej strony (w sekundach)" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "Okres sprawdzania widoczności stron (w sekundach)" + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "Ciemny kolor negatywu" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "Jasny kolor negatywu" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "Kolor wyróżnienia" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "Kolor wyróżnienia bieżącego elementu" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "Negatyw" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "Zawijanie dokumentu" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "Przezroczystość wyróżnienia" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "Wyświetlaj: „Wczytywanie pliku...”" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "Dopasowanie widoku pliku" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "Wyświetl ukryte pliki i katalogi" + +#: ../config.c:138 +msgid "Show directories" +msgstr "Wyświetl katalogi" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "Zawsze otwieraj na pierwszej stronie" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "Dodaj zakładkę" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Usuń zakładkę" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "Wyświetl zakładki" + +#: ../config.c:269 +msgid "Close current file" +msgstr "Zamknij plik" + +#: ../config.c:270 +msgid "Show file information" +msgstr "Wyświetl informacje o pliku" + +#: ../config.c:271 +msgid "Show help" +msgstr "Wyświetl pomoc" + +#: ../config.c:272 +msgid "Open document" +msgstr "Otwórz plik" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "Zakończ" + +#: ../config.c:274 +msgid "Print document" +msgstr "Wydrukuj" + +#: ../config.c:275 +msgid "Save document" +msgstr "Zapisz" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "Zapisz (nadpisując istniejący plik)" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "Zapisz załączniki" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "Ustaw przesunięcie numerów stron" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "Zaznaczony tekst skopiowano do schowka: %s" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Skopiuj obrazek" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "Dokument nie zawiera indeksu" + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "Wystąpił problem z uruchomieniem xdg-open" + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "Przypisz proces do rodzica o danym xid" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "Ścieżka do katalogu konfiguracyjnego" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "Ścieżka do katalogu danych" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "Ścieżka do katalogu wtyczek" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "Forkuj w tle" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "Szczegółowość komunikatów (debug, info, warning, error)" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[bez nazwy]" diff --git a/po/ta_IN.po b/po/ta_IN.po new file mode 100644 index 0000000..2c31acd --- /dev/null +++ b/po/ta_IN.po @@ -0,0 +1,360 @@ +# zathura - language file (Tamil (India)) +# See LICENSE file for license and copyright information +# +# Translators: +# , 2012. +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-04-03 15:25+0000\n" +"Last-Translator: mankand007 \n" +"Language-Team: Tamil (India) (http://www.transifex.net/projects/p/zathura/" +"language/ta_IN/)\n" +"Language: ta_IN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1)\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "கொடுக்கப்பட்ட உள்ளீடு(input) '%s' தவறு" + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "கொடுக்கப்பட்ட index '%s' தவறு" + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "எந்தக் ஆவணமும் திறக்கப்படவில்லை" + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "கொடுக்கப்பட்ட arguments-களின் எண்ணிக்கை தவறு" + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "Bookmark வெற்றிகரமாக நிகழ்நிலை(update) படுத்தப்பட்டது: %s" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "Bookmark-ஐ உருவாக்க முடியவில்லை: %s" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "Bookmark வெற்றிகரமாக உருவாக்கப்பட்டது: %s" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "Bookmark அழிக்கப்பட்டது: %s" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "Bookmark-ஐ அழிக்க இயலவில்லை: %s" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "அந்தப் பெயரில் எந்த bookmark-ம் இல்லை: %s" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "எந்தத் தகவலும் இல்லை" + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "Argumentகளின் எண்ணிக்கை மிகவும் அதிகம்" + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "எந்த argument-ம் தரப்படவில்லை" + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "கோப்பு சேமிக்கப்பட்டது" + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "ஆவணத்தை சேமிக்க இயலவில்லை" + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "கொடுக்கப்பட்ட argument-களின் எண்ணிக்கை தவறு" + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "" + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "" + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "" + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "" + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "" + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "Argument ஒரு எண்ணாக இருக்க வேண்டும்" + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "இணைப்புகளைச் சேமிக்கவும்" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "" + +#: ../config.c:100 +msgid "Zoom step" +msgstr "Zoom அமைப்பு" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "இரு பக்கங்களுக்கிடையில் உள்ள நிரப்பல்(padding)" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "ஒரு வரிசையில் எத்தனை பக்கங்களைக் காட்ட வேண்டும்" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "திரை உருளல்(scroll) அளவு" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "முடிந்தவரை சிறியதாகக் காட்டு" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "முடிந்தவரை பெரிதாகக் காட்டு" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "" + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "" + +#: ../config.c:138 +msgid "Show directories" +msgstr "" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "புதிய bookmark உருவாக்கு" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Bookmark-ஐ அழித்துவிடு" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "அனைத்து bookmark-களையும் பட்டியலிடு" + +#: ../config.c:269 +msgid "Close current file" +msgstr "" + +#: ../config.c:270 +msgid "Show file information" +msgstr "ஆவணம் பற்றிய தகவல்களைக் காட்டு" + +#: ../config.c:271 +msgid "Show help" +msgstr "உதவியைக் காட்டு" + +#: ../config.c:272 +msgid "Open document" +msgstr "ஒரு ஆவணத்தைத் திற" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "zathura-வை விட்டு வெளியேறு" + +#: ../config.c:274 +msgid "Print document" +msgstr "ஆவணத்தை அச்சிடு" + +#: ../config.c:275 +msgid "Save document" +msgstr "ஆவணத்தை சேமிக்கவும்" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "இணைப்புகளைச் சேமிக்கவும்" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "படத்தை ஒரு பிரதியெடு" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "இந்த ஆவணத்தில் எந்த index-ம் இல்லை" + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "xdg-open-ஐ இயக்க முடியவில்லை" + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "பெயரற்ற ஆவணம்" diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 0000000..d5f33f3 --- /dev/null +++ b/po/tr.po @@ -0,0 +1,361 @@ +# zathura - language file (Turkish) +# See LICENSE file for license and copyright information +# +# Translators: +# , 2012. +# , 2012. +msgid "" +msgstr "" +"Project-Id-Version: zathura\n" +"Report-Msgid-Bugs-To: http://bt.pwmt.org/\n" +"POT-Creation-Date: 2012-05-08 19:21+0200\n" +"PO-Revision-Date: 2012-05-01 20:38+0000\n" +"Last-Translator: hsngrms \n" +"Language-Team: Turkish (http://www.transifex.net/projects/p/zathura/language/" +"tr/)\n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#: ../callbacks.c:175 +#, c-format +msgid "Invalid input '%s' given." +msgstr "Hatalı girdi '%s'" + +#: ../callbacks.c:203 +#, c-format +msgid "Invalid index '%s' given." +msgstr "Hatalı dizin '%s'" + +#: ../commands.c:33 ../commands.c:68 ../commands.c:95 ../commands.c:137 +#: ../commands.c:251 ../commands.c:281 ../commands.c:307 ../commands.c:396 +#: ../commands.c:496 ../shortcuts.c:440 ../shortcuts.c:891 +msgid "No document opened." +msgstr "Açık belge yok." + +#: ../commands.c:39 ../commands.c:74 ../commands.c:101 ../commands.c:401 +msgid "Invalid number of arguments given." +msgstr "Yanlış sayıda argüman" + +#: ../commands.c:47 +#, c-format +msgid "Bookmark successfuly updated: %s" +msgstr "Yer imi başarıyla güncellendi: %s" + +#: ../commands.c:53 +#, c-format +msgid "Could not create bookmark: %s" +msgstr "Yer imi yaratılamadı: %s" + +#: ../commands.c:57 +#, c-format +msgid "Bookmark successfuly created: %s" +msgstr "Yer imi yaratıldı: %s" + +#: ../commands.c:80 +#, c-format +msgid "Removed bookmark: %s" +msgstr "Yer imi silindi: %s" + +#: ../commands.c:82 +#, c-format +msgid "Failed to remove bookmark: %s" +msgstr "Yer imi silinemedi: %s" + +#: ../commands.c:108 +#, c-format +msgid "No such bookmark: %s" +msgstr "Böyle bir yer imi yok: %s" + +#: ../commands.c:159 ../commands.c:181 +msgid "No information available." +msgstr "Bilgi mevcut değil." + +#: ../commands.c:219 +msgid "Too many arguments." +msgstr "Çok fazla sayıda argüman." + +#: ../commands.c:228 +msgid "No arguments given." +msgstr "Argüman verilmedi." + +#: ../commands.c:287 ../commands.c:313 +msgid "Document saved." +msgstr "Belge kaydedildi." + +#: ../commands.c:289 ../commands.c:315 +msgid "Failed to save document." +msgstr "Belge kaydedilemedi." + +#: ../commands.c:292 ../commands.c:318 +msgid "Invalid number of arguments." +msgstr "Yanlış sayıda argüman." + +#: ../commands.c:420 +#, c-format +msgid "Couldn't write attachment '%s' to '%s'." +msgstr "'%s' eki '%s' konumuna yazılamadı." + +#: ../commands.c:422 +#, c-format +msgid "Wrote attachment '%s' to '%s'." +msgstr "'%s' eki '%s' konumuna yazıldı." + +#: ../commands.c:466 +#, c-format +msgid "Wrote image '%s' to '%s'." +msgstr "'%s' eki '%s' konumuna yazıldı." + +#: ../commands.c:468 +#, c-format +msgid "Couldn't write image '%s' to '%s'." +msgstr "'%s' eki '%s' konumuna yazılamadı." + +#: ../commands.c:475 +#, c-format +msgid "Unknown image '%s'." +msgstr "" + +#: ../commands.c:479 +#, c-format +msgid "Unknown attachment or image '%s'." +msgstr "" + +#: ../commands.c:509 +msgid "Argument must be a number." +msgstr "Argüman bir sayı olmalı." + +#: ../completion.c:250 +#, c-format +msgid "Page %d" +msgstr "" + +#: ../completion.c:293 +msgid "Attachments" +msgstr "Ekleri kaydet" + +#. add images +#: ../completion.c:324 +msgid "Images" +msgstr "" + +#. zathura settings +#: ../config.c:98 +msgid "Database backend" +msgstr "Veritabanı arkayüzü" + +#: ../config.c:100 +msgid "Zoom step" +msgstr "Yakınlaşma/uzaklaşma aralığı" + +#: ../config.c:102 +msgid "Padding between pages" +msgstr "Sayfalar arasındaki boşluk" + +#: ../config.c:104 +msgid "Number of pages per row" +msgstr "Satır başına sayfa sayısı" + +#: ../config.c:106 +msgid "Scroll step" +msgstr "Kaydırma aralığı" + +#: ../config.c:108 +msgid "Zoom minimum" +msgstr "En fazla uzaklaşma" + +#: ../config.c:110 +msgid "Zoom maximum" +msgstr "En fazla yakınlaşma" + +#: ../config.c:112 +msgid "Life time (in seconds) of a hidden page" +msgstr "Gizli pencerenin açık kalma süresi (saniye)" + +#: ../config.c:113 +msgid "Amount of seconds between each cache purge" +msgstr "Önbellek temizliği yapılma sıklığı, saniye cinsinden" + +#: ../config.c:115 +msgid "Recoloring (dark color)" +msgstr "Renk değişimi (koyu renk)" + +#: ../config.c:117 +msgid "Recoloring (light color)" +msgstr "Renk değişimi (açık renk)" + +#: ../config.c:119 +msgid "Color for highlighting" +msgstr "İşaretleme rengi" + +#: ../config.c:121 +msgid "Color for highlighting (active)" +msgstr "İşaretleme rengi (etkin)" + +#: ../config.c:125 +msgid "Recolor pages" +msgstr "Sayga rengini değiştir" + +#: ../config.c:127 +msgid "Wrap scrolling" +msgstr "Kaydırmayı sarmala" + +#: ../config.c:129 +msgid "Advance number of pages per row" +msgstr "Satır başına sayfa sayısı" + +#: ../config.c:131 +msgid "Transparency for highlighting" +msgstr "Ön plana çıkarmak için saydamlaştır" + +#: ../config.c:133 +msgid "Render 'Loading ...'" +msgstr "'Yüklüyor ...' yazısını göster" + +#: ../config.c:134 +msgid "Adjust to when opening file" +msgstr "Dosya açarken ayarla" + +#: ../config.c:136 +msgid "Show hidden files and directories" +msgstr "Gizli dosyaları ve dizinleri göster" + +#: ../config.c:138 +msgid "Show directories" +msgstr "Dizinleri göster" + +#: ../config.c:140 +msgid "Always open on first page" +msgstr "Her zaman ilk sayfayı aç" + +#: ../config.c:142 +msgid "Highlight search results" +msgstr "" + +#: ../config.c:144 +msgid "Clear search results on abort" +msgstr "" + +#. define default inputbar commands +#: ../config.c:266 +msgid "Add a bookmark" +msgstr "Yer imi ekle" + +#: ../config.c:267 +msgid "Delete a bookmark" +msgstr "Yer imi sil" + +#: ../config.c:268 +msgid "List all bookmarks" +msgstr "Yer imlerini listele" + +#: ../config.c:269 +msgid "Close current file" +msgstr "Geçerli dosyayı kapat" + +#: ../config.c:270 +msgid "Show file information" +msgstr "Dosya bilgisi göster" + +#: ../config.c:271 +msgid "Show help" +msgstr "Yardım bilgisi göster" + +#: ../config.c:272 +msgid "Open document" +msgstr "Belge aç" + +#: ../config.c:273 +msgid "Close zathura" +msgstr "Zathura'yı kapat" + +#: ../config.c:274 +msgid "Print document" +msgstr "Belge yazdır" + +#: ../config.c:275 +msgid "Save document" +msgstr "Belgeyi kaydet" + +#: ../config.c:276 +msgid "Save document (and force overwriting)" +msgstr "Belgeyi kaydet (ve sormadan üzerine yaz)" + +#: ../config.c:277 +msgid "Save attachments" +msgstr "Ekleri kaydet" + +#: ../config.c:278 +msgid "Set page offset" +msgstr "Sayfa derinliğini ayarla" + +#: ../config.c:279 +msgid "Mark current location within the document" +msgstr "Bu belgede bu konumu işaretle" + +#: ../config.c:280 +msgid "Delete the specified marks" +msgstr "Seçilen işaretlemeleri sil" + +#: ../config.c:281 +msgid "Don't highlight current search results" +msgstr "" + +#: ../config.c:282 +msgid "Highlight current search results" +msgstr "" + +#: ../page-widget.c:611 +#, c-format +msgid "Copied selected text to clipboard: %s" +msgstr "Seçili metin panoya kopyalandı: %s" + +#: ../page-widget.c:708 +msgid "Copy image" +msgstr "Resim kopyala" + +#: ../page-widget.c:709 +msgid "Save image as" +msgstr "" + +#: ../shortcuts.c:797 +msgid "This document does not contain any index" +msgstr "Bu belge fihrist içermiyor" + +#: ../utils.c:346 +msgid "Failed to run xdg-open." +msgstr "xdg-open çalıştırılamadı" + +#: ../zathura.c:73 +msgid "Reparents to window specified by xid" +msgstr "Xid tarafından belirlendiği gibi bir üst seviye pencereye bağlı" + +#: ../zathura.c:74 +msgid "Path to the config directory" +msgstr "Ayar dizini adresi" + +#: ../zathura.c:75 +msgid "Path to the data directory" +msgstr "Veri dizini adresi" + +#: ../zathura.c:76 +msgid "Path to the directories containing plugins" +msgstr "Eklentileri içeren dizinin adresi" + +#: ../zathura.c:77 +msgid "Fork into the background" +msgstr "Arka planda işlemden çocuk oluştur" + +#: ../zathura.c:78 +msgid "Document password" +msgstr "" + +#: ../zathura.c:79 +msgid "Log level (debug, info, warning, error)" +msgstr "Kayıt seviyesi (hata ayıklama, bilgi, uyarı, hata)" + +#: ../zathura.c:251 ../zathura.c:799 +msgid "[No name]" +msgstr "[İsimsiz]" diff --git a/print.c b/print.c index e6d683f..867382d 100644 --- a/print.c +++ b/print.c @@ -3,10 +3,19 @@ #include "print.h" #include "document.h" #include "render.h" +#include "page.h" #include #include +static void cb_print_draw_page(GtkPrintOperation* print_operation, + GtkPrintContext* context, gint page_number, zathura_t* zathura); +static void cb_print_end(GtkPrintOperation* print_operation, GtkPrintContext* + context, zathura_t* zathura); +static void cb_print_request_page_setup(GtkPrintOperation* print_operation, + GtkPrintContext* context, gint page_number, GtkPageSetup* setup, zathura_t* + zathura); + void print(zathura_t* zathura) { @@ -25,12 +34,14 @@ print(zathura_t* zathura) } gtk_print_operation_set_allow_async(print_operation, TRUE); - gtk_print_operation_set_n_pages(print_operation, zathura->document->number_of_pages); - gtk_print_operation_set_current_page(print_operation, zathura->document->current_page_number); + gtk_print_operation_set_n_pages(print_operation, zathura_document_get_number_of_pages(zathura->document)); + gtk_print_operation_set_current_page(print_operation, zathura_document_get_current_page_number(zathura->document)); + gtk_print_operation_set_use_full_page(print_operation, TRUE); /* print operation signals */ - g_signal_connect(print_operation, "draw-page", G_CALLBACK(cb_print_draw_page), zathura); - g_signal_connect(print_operation, "end-print", G_CALLBACK(cb_print_end), zathura); + g_signal_connect(print_operation, "draw-page", G_CALLBACK(cb_print_draw_page), zathura); + g_signal_connect(print_operation, "end-print", G_CALLBACK(cb_print_end), zathura); + g_signal_connect(print_operation, "request_page_setup", G_CALLBACK(cb_print_request_page_setup), zathura); /* print */ GtkPrintOperationResult result = gtk_print_operation_run(print_operation, @@ -54,24 +65,27 @@ print(zathura_t* zathura) g_object_unref(print_operation); } -void +static void cb_print_end(GtkPrintOperation* UNUSED(print_operation), GtkPrintContext* UNUSED(context), zathura_t* zathura) { - if (zathura == NULL || zathura->ui.session == NULL || zathura->document == NULL - || zathura->document->file_path == NULL) { + if (zathura == NULL || zathura->ui.session == NULL || zathura->document == NULL) { return; } - girara_statusbar_item_set_text(zathura->ui.session, - zathura->ui.statusbar.file, zathura->document->file_path); + const char* file_path = zathura_document_get_path(zathura->document); + + if (file_path != NULL) { + girara_statusbar_item_set_text(zathura->ui.session, + zathura->ui.statusbar.file, file_path); + } } -void +static void cb_print_draw_page(GtkPrintOperation* UNUSED(print_operation), GtkPrintContext* context, gint page_number, zathura_t* zathura) { - if (context == NULL || zathura == NULL || zathura->document->pages == NULL || + if (context == NULL || zathura == NULL || zathura->document == NULL || zathura->ui.session == NULL || zathura->ui.statusbar.file == NULL) { return; } @@ -83,11 +97,34 @@ cb_print_draw_page(GtkPrintOperation* UNUSED(print_operation), GtkPrintContext* g_free(tmp); /* render page */ - cairo_t* cairo = gtk_print_context_get_cairo_context(context); - zathura_page_t* page = zathura->document->pages[page_number]; + cairo_t* cairo = gtk_print_context_get_cairo_context(context); + zathura_page_t* page = zathura_document_get_page(zathura->document, page_number); if (cairo == NULL || page == NULL) { return; } + girara_debug("printing page %d ...", page_number); + render_lock(zathura->sync.render_thread); zathura_page_render(page, cairo, true); + render_unlock(zathura->sync.render_thread); +} + +static void +cb_print_request_page_setup(GtkPrintOperation* UNUSED(print_operation), + GtkPrintContext* UNUSED(context), gint page_number, GtkPageSetup* setup, + zathura_t* zathura) +{ + if (zathura == NULL || zathura->document == NULL) { + return; + } + + zathura_page_t* page = zathura_document_get_page(zathura->document, page_number); + double width = zathura_page_get_width(page); + double height = zathura_page_get_height(page); + + if (width > height) { + gtk_page_setup_set_orientation(setup, GTK_PAGE_ORIENTATION_LANDSCAPE); + } else { + gtk_page_setup_set_orientation(setup, GTK_PAGE_ORIENTATION_PORTRAIT); + } } diff --git a/print.h b/print.h index f7b603d..3833d94 100644 --- a/print.h +++ b/print.h @@ -12,25 +12,4 @@ */ void print(zathura_t* zathura); -/** - * Callback that is executed for every page that should be printed - * - * @param print_operation Print operation object - * @param context Print context - * @param page_number Current page number - * @param zathura Zathura object - */ -void cb_print_draw_page(GtkPrintOperation* print_operation, GtkPrintContext* - context, gint page_number, zathura_t* zathura); - -/** - * Emitted after all pages have been rendered - * - * @param print_operation Print operation - * @param context Print context - * @param zathura Zathura object - */ -void cb_print_end(GtkPrintOperation* print_operation, GtkPrintContext* context, - zathura_t* zathura); - #endif // PRINT_H diff --git a/render.c b/render.c index 55fdd5e..77a9f97 100644 --- a/render.c +++ b/render.c @@ -9,15 +9,18 @@ #include "render.h" #include "zathura.h" #include "document.h" +#include "page.h" #include "page-widget.h" #include "utils.h" static void render_job(void* data, void* user_data); static bool render(zathura_t* zathura, zathura_page_t* page); +static gint render_thread_sort(gconstpointer a, gconstpointer b, gpointer data); struct render_thread_s { GThreadPool* pool; /**< Pool of threads */ + GStaticMutex mutex; /**< Render lock */ }; static void @@ -29,8 +32,9 @@ render_job(void* data, void* user_data) return; } + girara_debug("rendring page %d ...", zathura_page_get_index(page)); if (render(zathura, page) != true) { - girara_error("Rendering failed (page %d)\n", page->number); + girara_error("Rendering failed (page %d)\n", zathura_page_get_index(page)); } } @@ -45,6 +49,9 @@ render_init(zathura_t* zathura) goto error_free; } + g_thread_pool_set_sort_function(render_thread->pool, render_thread_sort, zathura); + g_static_mutex_init(&render_thread->mutex); + return render_thread; error_free: @@ -64,6 +71,7 @@ render_free(render_thread_t* render_thread) g_thread_pool_free(render_thread->pool, TRUE, TRUE); } + g_static_mutex_free(&render_thread->mutex); g_free(render_thread); } @@ -110,16 +118,20 @@ render(zathura_t* zathura, zathura_page_t* page) cairo_restore(cairo); cairo_save(cairo); - if (fabs(zathura->document->scale - 1.0f) > FLT_EPSILON) { - cairo_scale(cairo, zathura->document->scale, zathura->document->scale); + double scale = zathura_document_get_scale(zathura->document); + if (fabs(scale - 1.0f) > FLT_EPSILON) { + cairo_scale(cairo, scale, scale); } - if (zathura_page_render(page, cairo, false) != ZATHURA_PLUGIN_ERROR_OK) { + render_lock(zathura->sync.render_thread); + if (zathura_page_render(page, cairo, false) != ZATHURA_ERROR_OK) { + render_unlock(zathura->sync.render_thread); cairo_destroy(cairo); cairo_surface_destroy(surface); return false; } + render_unlock(zathura->sync.render_thread); cairo_restore(cairo); cairo_destroy(cairo); @@ -161,7 +173,8 @@ render(zathura_t* zathura, zathura_page_t* page) /* update the widget */ gdk_threads_enter(); - zathura_page_widget_update_surface(ZATHURA_PAGE(page->drawing_area), surface); + GtkWidget* widget = zathura_page_get_widget(zathura, page); + zathura_page_widget_update_surface(ZATHURA_PAGE(widget), surface); gdk_threads_leave(); return true; @@ -170,17 +183,68 @@ render(zathura_t* zathura, zathura_page_t* page) void render_all(zathura_t* zathura) { - if (zathura->document == NULL) { + if (zathura == NULL || zathura->document == NULL) { return; } /* unmark all pages */ - for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) { - zathura_page_t* page = zathura->document->pages[page_id]; + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); unsigned int page_height = 0, page_width = 0; page_calc_height_width(page, &page_height, &page_width, true); - gtk_widget_set_size_request(page->drawing_area, page_width, page_height); - gtk_widget_queue_resize(page->drawing_area); + GtkWidget* widget = zathura_page_get_widget(zathura, page); + gtk_widget_set_size_request(widget, page_width, page_height); + gtk_widget_queue_resize(widget); } } + +static gint +render_thread_sort(gconstpointer a, gconstpointer b, gpointer data) +{ + if (a == NULL || b == NULL || data == NULL) { + return 0; + } + + zathura_page_t* page_a = (zathura_page_t*) a; + zathura_page_t* page_b = (zathura_page_t*) b; + zathura_t* zathura = (zathura_t*) data; + + unsigned int page_a_index = zathura_page_get_index(page_a); + unsigned int page_b_index = zathura_page_get_index(page_b); + + unsigned int last_view_a = 0; + unsigned int last_view_b = 0; + + g_object_get(zathura->pages[page_a_index], "last-view", &last_view_a, NULL); + g_object_get(zathura->pages[page_b_index], "last-view", &last_view_b, NULL); + + if (last_view_a > last_view_b) { + return -1; + } else if (last_view_b > last_view_a) { + return 1; + } + + return 0; +} + +void +render_lock(render_thread_t* render_thread) +{ + if (render_thread == NULL) { + return; + } + + g_static_mutex_lock(&render_thread->mutex); +} + +void +render_unlock(render_thread_t* render_thread) +{ + if (render_thread == NULL) { + return; + } + + g_static_mutex_unlock(&render_thread->mutex); +} diff --git a/render.h b/render.h index 435ef83..2d7a12c 100644 --- a/render.h +++ b/render.h @@ -44,4 +44,19 @@ bool render_page(render_thread_t* render_thread, zathura_page_t* page); */ void render_all(zathura_t* zathura); +/** + * Lock the render thread. This is useful if you want to render on your own (e.g + * for printing). + * + * @param render_thread The render thread object. + */ +void render_lock(render_thread_t* render_thread); + +/** + * Unlock the render thread. + * + * @param render_thread The render thread object. + */ +void render_unlock(render_thread_t* render_thread); + #endif // RENDER_H diff --git a/shortcuts.c b/shortcuts.c index 42a8244..0e9c91c 100644 --- a/shortcuts.c +++ b/shortcuts.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include "callbacks.h" @@ -15,20 +14,10 @@ #include "zathura.h" #include "render.h" #include "utils.h" +#include "page.h" +#include "print.h" #include "page-widget.h" -static void -readjust_view_after_zooming(zathura_t *zathura, float old_zoom) { - GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); - GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window); - GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window); - - gdouble valx = gtk_adjustment_get_value(hadjustment) / old_zoom * zathura->document->scale; - gdouble valy = gtk_adjustment_get_value(vadjustment) / old_zoom * zathura->document->scale; - set_adjustment(hadjustment, valx); - set_adjustment(vadjustment, valy); -} - bool sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t)) @@ -37,14 +26,21 @@ sc_abort(girara_session_t* session, girara_argument_t* UNUSED(argument), g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; + bool clear_search = true; + girara_setting_get(session, "abort-clear-search", &clear_search); + if (zathura->document != NULL) { - for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; ++page_id) { - zathura_page_t* page = zathura->document->pages[page_id]; + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page_id = 0; page_id < number_of_pages; ++page_id) { + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); if (page == NULL) { continue; } - g_object_set(page->drawing_area, "draw-links", FALSE, NULL); + g_object_set(zathura_page_get_widget(zathura, page), "draw-links", FALSE, NULL); + if (clear_search) { + g_object_set(zathura_page_get_widget(zathura, page), "search-results", NULL, NULL); + } } } @@ -70,9 +66,9 @@ sc_adjust_window(girara_session_t* session, girara_argument_t* argument, goto error_ret; } - float old_zoom = zathura->document->scale; - zathura->document->adjust_mode = argument->n; - if (argument->n == ADJUST_NONE) { + float old_zoom = zathura_document_get_scale(zathura->document); + zathura_document_set_adjust_mode(zathura->document, argument->n); + if (argument->n == ZATHURA_ADJUST_NONE) { /* there is nothing todo */ goto error_ret; } @@ -83,33 +79,72 @@ sc_adjust_window(girara_session_t* session, girara_argument_t* argument, gint width = allocation.width; gint height = allocation.height; - /* calculate total width and max-height */ - double total_width = 0; - double max_height = 0; + /* correct view size */ + if (gtk_widget_get_visible(GTK_WIDGET(session->gtk.inputbar)) == true) { + gtk_widget_get_allocation(session->gtk.inputbar, &allocation); + width += allocation.width; + height += allocation.height; + } + /* calculate total width and max-height */ + double total_width = 0; + double total_height = 0; + double max_height = 0; + double max_width = 0; + + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); for (unsigned int page_id = 0; page_id < pages_per_row; page_id++) { - if (page_id == zathura->document->number_of_pages) { + if (page_id == number_of_pages) { break; } - zathura_page_t* page = zathura->document->pages[page_id]; + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); if (page == NULL) { goto error_ret; } - if (page->height > max_height) { - max_height = page->height; + unsigned int page_height = zathura_page_get_height(page); + unsigned int page_width = zathura_page_get_width(page); + + if (page_height > max_height) { + max_height = page_height; } - total_width += page->width; + if (page_width > max_width) { + max_width = page_width; + } + + total_width += page_width; + total_height += page_height; } - if (argument->n == ADJUST_WIDTH) { - zathura->document->scale = width / total_width; - } else if (argument->n == ADJUST_BESTFIT) { - zathura->document->scale = height / max_height; - } else { - goto error_ret; + unsigned int rotation = zathura_document_get_rotation(zathura->document); + switch (argument->n) { + case ZATHURA_ADJUST_WIDTH: + if (rotation == 0 || rotation == 180) { + zathura_document_set_scale(zathura->document, width / total_width); + } else { + zathura_document_set_scale(zathura->document, width / total_height); + } + break; + case ZATHURA_ADJUST_BESTFIT: + if (total_width < total_height) { + if (rotation == 0 || rotation == 180) { + zathura_document_set_scale(zathura->document, height / max_height); + } else { + zathura_document_set_scale(zathura->document, width / total_height); + } + } else { + if (rotation == 0 || rotation == 180) { + zathura_document_set_scale(zathura->document, width / total_width); + } else { + zathura_document_set_scale(zathura->document, height / total_width); + } + } + + break; + default: + goto error_ret; } /* keep position */ @@ -158,22 +193,19 @@ sc_focus_inputbar(girara_session_t* session, girara_argument_t* argument, girara /* append filepath */ if (argument->n == APPEND_FILEPATH && zathura->document != NULL) { - char* file_path = g_strdup(zathura->document->file_path); + const char* file_path = zathura_document_get_path(zathura->document); if (file_path == NULL) { return false; } - char* path = dirname(file_path); - char* tmp = g_strdup_printf("%s%s/", (char*) argument->data, (g_strcmp0(path, "/") == 0) ? "" : path); - - if (tmp == NULL) { - g_free(file_path); - return false; - } + char* path = g_path_get_dirname(file_path); + char* escaped = girara_escape_string(path); + char* tmp = g_strdup_printf("%s%s/", (char*) argument->data, (g_strcmp0(path, "/") == 0) ? "" : escaped); + g_free(path); + g_free(escaped); gtk_entry_set_text(session->gtk.inputbar_entry, tmp); g_free(tmp); - g_free(file_path); } /* we save the X clipboard that will be clear by "grab_focus" */ @@ -206,25 +238,27 @@ sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument), /* set pages to draw links */ bool show_links = false; unsigned int page_offset = 0; - for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) { - zathura_page_t* page = zathura->document->pages[page_id]; + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); if (page == NULL) { continue; } - g_object_set(page->drawing_area, "search-results", NULL, NULL); - if (page->visible == true) { - g_object_set(page->drawing_area, "draw-links", TRUE, NULL); + GtkWidget* page_widget = zathura_page_get_widget(zathura, page); + g_object_set(page_widget, "search-results", NULL, NULL); + if (zathura_page_get_visibility(page) == true) { + g_object_set(page_widget, "draw-links", TRUE, NULL); int number_of_links = 0; - g_object_get(page->drawing_area, "number-of-links", &number_of_links, NULL); + g_object_get(page_widget, "number-of-links", &number_of_links, NULL); if (number_of_links != 0) { show_links = true; } - g_object_set(page->drawing_area, "offset-links", page_offset, NULL); + g_object_set(page_widget, "offset-links", page_offset, NULL); page_offset += number_of_links; } else { - g_object_set(page->drawing_area, "draw-links", FALSE, NULL); + g_object_set(page_widget, "draw-links", FALSE, NULL); } } @@ -247,15 +281,16 @@ sc_goto(girara_session_t* session, girara_argument_t* argument, girara_event_t* if (t != 0) { /* add offset */ - if (zathura->document->page_offset > 0) { - t += zathura->document->page_offset; + unsigned int page_offset = zathura_document_get_page_offset(zathura->document); + if (page_offset > 0) { + t += page_offset; } page_set(zathura, t - 1); } else if (argument->n == TOP) { page_set(zathura, 0); } else if (argument->n == BOTTOM) { - page_set(zathura, zathura->document->number_of_pages - 1); + page_set(zathura, zathura_document_get_number_of_pages(zathura->document) - 1); } return false; @@ -307,9 +342,6 @@ sc_mouse_scroll(girara_session_t* session, girara_argument_t* argument, girara_e set_adjustment(x_adj, gtk_adjustment_get_value(x_adj) - (event->x - x)); set_adjustment(y_adj, gtk_adjustment_get_value(y_adj) - (event->y - y)); - - x = event->x; - y = event->y; break; /* unhandled events */ @@ -358,13 +390,21 @@ sc_navigate(girara_session_t* session, girara_argument_t* argument, g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(zathura->document != NULL, false); - int number_of_pages = zathura->document->number_of_pages; - int new_page = zathura->document->current_page_number; + int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + int new_page = zathura_document_get_current_page_number(zathura->document); bool scroll_wrap = false; girara_setting_get(session, "scroll-wrap", &scroll_wrap); - t = (t == 0) ? 1 : t; + bool columns_per_row_offset = false; + girara_setting_get(session, "advance-pages-per-row", &columns_per_row_offset); + + int offset = 1; + if (columns_per_row_offset == true) { + girara_setting_get(session, "pages-per-row", &offset); + } + + t = (t == 0) ? (unsigned int) offset : t; if (argument->n == NEXT) { if (scroll_wrap == true) { new_page = new_page + t; @@ -388,6 +428,24 @@ sc_navigate(girara_session_t* session, girara_argument_t* argument, return false; } +bool +sc_print(girara_session_t* session, girara_argument_t* UNUSED(argument), + girara_event_t* UNUSED(event), unsigned int UNUSED(t)) +{ + g_return_val_if_fail(session != NULL, false); + g_return_val_if_fail(session->global.data != NULL, false); + zathura_t* zathura = session->global.data; + + if (zathura->document == NULL) { + girara_notify(session, GIRARA_ERROR, _("No document opened.")); + return false; + } + + print(zathura); + + return true; +} + bool sc_recolor(girara_session_t* session, girara_argument_t* UNUSED(argument), girara_event_t* UNUSED(event), unsigned int UNUSED(t)) @@ -425,14 +483,14 @@ sc_reload(girara_session_t* session, girara_argument_t* UNUSED(argument), bool sc_rotate(girara_session_t* session, girara_argument_t* argument, - girara_event_t* UNUSED(event), unsigned int UNUSED(t)) + girara_event_t* UNUSED(event), unsigned int t) { g_return_val_if_fail(session != NULL, false); g_return_val_if_fail(session->global.data != NULL, false); zathura_t* zathura = session->global.data; g_return_val_if_fail(zathura->document != NULL, false); - unsigned int page_number = zathura->document->current_page_number; + unsigned int page_number = zathura_document_get_current_page_number(zathura->document); int angle = 90; if (argument != NULL && argument->n == ROTATE_CCW) { @@ -440,7 +498,13 @@ sc_rotate(girara_session_t* session, girara_argument_t* argument, } /* update rotate value */ - zathura->document->rotate = (zathura->document->rotate + angle) % 360; + t = (t == 0) ? 1 : t; + unsigned int rotation = zathura_document_get_rotation(zathura->document); + zathura_document_set_rotation(zathura->document, (rotation + angle * t) % 360); + + /* update scale */ + girara_argument_t new_argument = { zathura_document_get_adjust_mode(zathura->document), NULL }; + sc_adjust_window(zathura->ui.session, &new_argument, NULL, 0); /* render all pages again */ render_all(zathura); @@ -533,8 +597,8 @@ sc_search(girara_session_t* session, girara_argument_t* argument, g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(zathura->document != NULL, false); - const int num_pages = zathura->document->number_of_pages; - const int cur_page = zathura->document->current_page_number; + const int num_pages = zathura_document_get_number_of_pages(zathura->document); + const int cur_page = zathura_document_get_current_page_number(zathura->document); int diff = argument->n == FORWARD ? 1 : -1; zathura_page_t* target_page = NULL; @@ -542,13 +606,15 @@ sc_search(girara_session_t* session, girara_argument_t* argument, for (int page_id = 0; page_id < num_pages; ++page_id) { int tmp = cur_page + diff * page_id; - zathura_page_t* page = zathura->document->pages[(tmp + num_pages) % num_pages]; + zathura_page_t* page = zathura_document_get_page(zathura->document, (tmp + num_pages) % num_pages); if (page == NULL) { continue; } + GtkWidget* page_widget = zathura_page_get_widget(zathura, page); + int num_search_results = 0, current = -1; - g_object_get(page->drawing_area, "search-current", ¤t, + g_object_get(page_widget, "search-current", ¤t, "search-length", &num_search_results, NULL); if (num_search_results == 0 || current == -1) { continue; @@ -563,13 +629,14 @@ sc_search(girara_session_t* session, girara_argument_t* argument, target_idx = current - 1; } else { /* the next result is on a different page */ - g_object_set(page->drawing_area, "search-current", -1, NULL); + g_object_set(page_widget, "search-current", -1, NULL); for (int npage_id = 1; page_id < num_pages; ++npage_id) { int ntmp = cur_page + diff * (page_id + npage_id); - zathura_page_t* npage = zathura->document->pages[(ntmp + 2*num_pages) % num_pages]; - zathura->document->current_page_number = npage->number; - g_object_get(npage->drawing_area, "search-length", &num_search_results, NULL); + zathura_page_t* npage = zathura_document_get_page(zathura->document, (ntmp + 2*num_pages) % num_pages); + zathura_document_set_current_page_number(zathura->document, zathura_page_get_index(npage)); + GtkWidget* npage_page_widget = zathura_page_get_widget(zathura, npage); + g_object_get(npage_page_widget, "search-length", &num_search_results, NULL); if (num_search_results != 0) { target_page = npage; target_idx = diff == 1 ? 0 : num_search_results - 1; @@ -583,13 +650,14 @@ sc_search(girara_session_t* session, girara_argument_t* argument, if (target_page != NULL) { girara_list_t* results = NULL; - g_object_set(target_page->drawing_area, "search-current", target_idx, NULL); - g_object_get(target_page->drawing_area, "search-results", &results, NULL); + GtkWidget* page_widget = zathura_page_get_widget(zathura, target_page); + g_object_set(page_widget, "search-current", target_idx, NULL); + g_object_get(page_widget, "search-results", &results, NULL); zathura_rectangle_t* rect = girara_list_nth(results, target_idx); zathura_rectangle_t rectangle = recalc_rectangle(target_page, *rect); page_offset_t offset; - page_calculate_offset(target_page, &offset); + page_calculate_offset(zathura, target_page, &offset); 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)); @@ -770,11 +838,24 @@ sc_toggle_index(girara_session_t* session, girara_argument_t* UNUSED(argument), gtk_widget_show(treeview); } + static double vvalue = 0; + static double hvalue = 0; + if (gtk_widget_get_visible(GTK_WIDGET(zathura->ui.index))) { girara_set_view(session, zathura->ui.page_widget_alignment); gtk_widget_hide(GTK_WIDGET(zathura->ui.index)); girara_mode_set(zathura->ui.session, zathura->modes.normal); + + /* reset adjustment */ + position_set_delayed(zathura, hvalue, vvalue); } else { + /* save adjustment */ + GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); + GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(session->gtk.view)); + + vvalue = gtk_adjustment_get_value(vadjustment); + hvalue = gtk_adjustment_get_value(hadjustment); + girara_set_view(session, zathura->ui.index); gtk_widget_show(GTK_WIDGET(zathura->ui.index)); girara_mode_set(zathura->ui.session, zathura->modes.index); @@ -826,9 +907,9 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* gtk_window_unfullscreen(GTK_WINDOW(session->gtk.window)); /* reset scale */ - zathura->document->scale = zoom; + zathura_document_set_scale(zathura->document, zoom); render_all(zathura); - page_set_delayed(zathura, zathura->document->current_page_number); + page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document)); } else { /* backup pages per row */ girara_setting_get(session, "pages-per-row", &pages_per_row); @@ -838,10 +919,10 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* girara_setting_set(session, "pages-per-row", &int_value); /* back up zoom */ - zoom = zathura->document->scale; + zoom = zathura_document_get_scale(zathura->document); /* adjust window */ - girara_argument_t argument = { ADJUST_BESTFIT, NULL }; + girara_argument_t argument = { ZATHURA_ADJUST_BESTFIT, NULL }; sc_adjust_window(session, &argument, NULL, 0); /* hide status and inputbar */ @@ -850,7 +931,7 @@ sc_toggle_fullscreen(girara_session_t* session, girara_argument_t* /* set full screen */ gtk_window_fullscreen(GTK_WINDOW(session->gtk.window)); - page_set_delayed(zathura, zathura->document->current_page_number); + page_set_delayed(zathura, zathura_document_get_current_page_number(zathura->document)); } fullscreen = fullscreen ? false : true; @@ -882,24 +963,25 @@ sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t* g_return_val_if_fail(argument != NULL, false); g_return_val_if_fail(zathura->document != NULL, false); - zathura->document->adjust_mode = ADJUST_NONE; + zathura_document_set_adjust_mode(zathura->document, ZATHURA_ADJUST_NONE); /* retreive zoom step value */ int value = 1; girara_setting_get(zathura->ui.session, "zoom-step", &value); - float zoom_step = value / 100.0f; - float old_zoom = zathura->document->scale; + t = (t == 0) ? 1 : t; + float zoom_step = value / 100.0f * t; + float old_zoom = zathura_document_get_scale(zathura->document); /* specify new zoom value */ if (argument->n == ZOOM_IN) { - zathura->document->scale += zoom_step; + zathura_document_set_scale(zathura->document, old_zoom + zoom_step); } else if (argument->n == ZOOM_OUT) { - zathura->document->scale -= zoom_step; + zathura_document_set_scale(zathura->document, old_zoom - zoom_step); } else if (argument->n == ZOOM_SPECIFIC) { - zathura->document->scale = t / 100.0f; + zathura_document_set_scale(zathura->document, t / 100.0f); } else { - zathura->document->scale = 1.0; + zathura_document_set_scale(zathura->document, 1.0); } /* zoom limitations */ @@ -911,10 +993,11 @@ sc_zoom(girara_session_t* session, girara_argument_t* argument, girara_event_t* float zoom_min = zoom_min_int * 0.01f; float zoom_max = zoom_max_int * 0.01f; - if (zathura->document->scale < zoom_min) { - zathura->document->scale = zoom_min; - } else if (zathura->document->scale > zoom_max) { - zathura->document->scale = zoom_max; + float scale = zathura_document_get_scale(zathura->document); + if (scale < zoom_min) { + zathura_document_set_scale(zathura->document, zoom_min); + } else if (scale > zoom_max) { + zathura_document_set_scale(zathura->document, zoom_max); } /* keep position */ diff --git a/shortcuts.h b/shortcuts.h index 56bed86..191c1af 100644 --- a/shortcuts.h +++ b/shortcuts.h @@ -105,6 +105,17 @@ bool sc_mouse_zoom(girara_session_t* session, girara_argument_t* argument, girar */ bool sc_navigate(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t); +/** + * Calls the print dialog + * + * @param session The used girara session + * @param argument The used argument + * @param event Girara event + * @param t Number of executions + * @return true if no error occured otherwise false + */ +bool sc_print(girara_session_t* session, girara_argument_t* argument, girara_event_t* event, unsigned int t); + /** * Recolor the pages * diff --git a/tests/test_document.c b/tests/test_document.c new file mode 100644 index 0000000..4cfbcc7 --- /dev/null +++ b/tests/test_document.c @@ -0,0 +1,24 @@ +/* See LICENSE file for license and copyright information */ + +#include + +#include "../document.h" + +START_TEST(test_open) { + fail_unless(zathura_document_open(NULL, NULL, NULL, NULL) == NULL, "Could create document", NULL); + fail_unless(zathura_document_open(NULL, "fl", NULL, NULL) == NULL, "Could create document", NULL); + fail_unless(zathura_document_open(NULL, "fl", "pw", NULL) == NULL, "Could create document", NULL); +} END_TEST + +Suite* suite_document() +{ + TCase* tcase = NULL; + Suite* suite = suite_create("Document"); + + /* basic */ + tcase = tcase_create("basic"); + tcase_add_test(tcase, test_open); + suite_add_tcase(suite, tcase); + + return suite; +} diff --git a/tests/tests.c b/tests/tests.c index 1f21807..5e3098f 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -4,8 +4,19 @@ #include #include -Suite* suite_session(); -Suite* suite_utils(); +#define LENGTH(x) (sizeof(x)/sizeof((x)[0])) + +extern Suite* suite_session(); +extern Suite* suite_utils(); +extern Suite* suite_document(); + +typedef Suite* (*suite_create_fnt_t)(void); + +const suite_create_fnt_t suites[] = { + suite_utils, + suite_document, + suite_session, +}; int main(int argc, char* argv[]) @@ -17,19 +28,14 @@ main(int argc, char* argv[]) /* init gtk */ gtk_init(&argc, &argv); - /* test session */ - suite = suite_session(); - suite_runner = srunner_create(suite); - srunner_run_all(suite_runner, CK_NORMAL); - number_failed += srunner_ntests_failed(suite_runner); - srunner_free(suite_runner); - - /* test utils */ - suite = suite_utils(); - suite_runner = srunner_create(suite); - srunner_run_all(suite_runner, CK_NORMAL); - number_failed += srunner_ntests_failed(suite_runner); - srunner_free(suite_runner); + /* run test suites */ + for (unsigned int i = 0; i < LENGTH(suites); i++) { + suite = suites[i](); + suite_runner = srunner_create(suite); + srunner_run_all(suite_runner, CK_NORMAL); + number_failed += srunner_ntests_failed(suite_runner); + srunner_free(suite_runner); + } return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/types.c b/types.c new file mode 100644 index 0000000..8027920 --- /dev/null +++ b/types.c @@ -0,0 +1,109 @@ +/* See LICENSE file for license and copyright information */ + +#include +#include +#include + +#include "types.h" +#include "links.h" +#include "internal.h" + +zathura_index_element_t* +zathura_index_element_new(const char* title) +{ + if (title == NULL) { + return NULL; + } + + zathura_index_element_t* res = g_malloc0(sizeof(zathura_index_element_t)); + + res->title = g_strdup(title); + + return res; +} + +void +zathura_index_element_free(zathura_index_element_t* index) +{ + if (index == NULL) { + return; + } + + g_free(index->title); + zathura_link_free(index->link); + g_free(index); +} + +zathura_image_buffer_t* +zathura_image_buffer_create(unsigned int width, unsigned int height) +{ + zathura_image_buffer_t* image_buffer = malloc(sizeof(zathura_image_buffer_t)); + + if (image_buffer == NULL) { + return NULL; + } + + image_buffer->data = calloc(width * height * 3, sizeof(unsigned char)); + + if (image_buffer->data == NULL) { + free(image_buffer); + return NULL; + } + + image_buffer->width = width; + image_buffer->height = height; + image_buffer->rowstride = width * 3; + + return image_buffer; +} + +void +zathura_image_buffer_free(zathura_image_buffer_t* image_buffer) +{ + if (image_buffer == NULL) { + return; + } + + free(image_buffer->data); + free(image_buffer); +} + +girara_list_t* +zathura_document_information_entry_list_new() +{ + girara_list_t* list = girara_list_new2((girara_free_function_t) + zathura_document_information_entry_free); + + return list; +} + +zathura_document_information_entry_t* +zathura_document_information_entry_new(zathura_document_information_type_t type, + const char* value) +{ + if (value == NULL) { + return NULL; + } + + zathura_document_information_entry_t* entry = + g_malloc0(sizeof(zathura_document_information_entry_t)); + + entry->type = type; + entry->value = g_strdup(value); + + return entry; +} + +void +zathura_document_information_entry_free(zathura_document_information_entry_t* entry) +{ + if (entry == NULL) { + return; + } + + if (entry->value != NULL) { + g_free(entry->value); + } + + g_free(entry); +} diff --git a/types.h b/types.h new file mode 100644 index 0000000..8aade9a --- /dev/null +++ b/types.h @@ -0,0 +1,242 @@ +/* See LICENSE file for license and copyright information */ + +#ifndef TYPES_H +#define TYPES_H + +#include + +#include "macros.h" + +/** + * Document + */ +typedef struct zathura_document_s zathura_document_t; +/** + * Page + */ +typedef struct zathura_page_s zathura_page_t; +/** + * Zathura + */ +typedef struct zathura_s zathura_t; + +/** + * Plugin manager + */ +typedef struct zathura_plugin_manager_s zathura_plugin_manager_t; + +/** + * Error types + */ +typedef enum zathura_plugin_error_e +{ + ZATHURA_ERROR_OK, /**< No error occured */ + ZATHURA_ERROR_UNKNOWN, /**< An unknown error occured */ + ZATHURA_ERROR_OUT_OF_MEMORY, /**< Out of memory */ + ZATHURA_ERROR_NOT_IMPLEMENTED, /**< The called function has not been implemented */ + ZATHURA_ERROR_INVALID_ARGUMENTS, /**< Invalid arguments have been passed */ + ZATHURA_ERROR_INVALID_PASSWORD /**< The provided password is invalid */ +} zathura_error_t; + +/** + * Possible information entry types + */ +typedef enum zathura_document_information_type_e +{ + ZATHURA_DOCUMENT_INFORMATION_TITLE, /**< Title of the document */ + ZATHURA_DOCUMENT_INFORMATION_AUTHOR, /**< Author of the document */ + ZATHURA_DOCUMENT_INFORMATION_SUBJECT, /**< Subject of the document */ + ZATHURA_DOCUMENT_INFORMATION_KEYWORDS, /**< Keywords of the document */ + ZATHURA_DOCUMENT_INFORMATION_CREATOR, /**< Creator of the document */ + ZATHURA_DOCUMENT_INFORMATION_PRODUCER, /**< Producer of the document */ + ZATHURA_DOCUMENT_INFORMATION_CREATION_DATE, /**< Creation data */ + ZATHURA_DOCUMENT_INFORMATION_MODIFICATION_DATE, /**< Modification data */ + ZATHURA_DOCUMENT_INFORMATION_OTHER /**< Any other information */ +} zathura_document_information_type_t; + +/** + * Plugin + */ +typedef struct zathura_plugin_s zathura_plugin_t; + +/** + * Document information entry + * + * Represents a single entry in the returned list from the \ref + * zathura_document_get_information function + */ +typedef struct zathura_document_information_entry_s zathura_document_information_entry_t; + +/** + * Image buffer + */ +typedef struct zathura_image_buffer_s +{ + unsigned char* data; /**< Image buffer data */ + unsigned int height; /**< Height of the image */ + unsigned int width; /**< Width of the image */ + unsigned int rowstride; /**< Rowstride of the image */ +} zathura_image_buffer_t; + +/** + * Adjust mode + */ +typedef enum zathura_adjust_mode_e +{ + ZATHURA_ADJUST_NONE, /**< No adjustment */ + ZATHURA_ADJUST_BESTFIT, /**< Adjust to best-fit */ + ZATHURA_ADJUST_WIDTH /**< Adjust to width */ +} zathura_adjust_mode_t; + +/** + * Creates an image buffer + * + * @param width Width of the image stored in the buffer + * @param height Height of the image stored in the buffer + * @return Image buffer or NULL if an error occured + */ +zathura_image_buffer_t* zathura_image_buffer_create(unsigned int width, unsigned int height); + +/** + * Frees the image buffer + * + * @param buffer The image buffer + */ +void zathura_image_buffer_free(zathura_image_buffer_t* buffer); + +/** + * Rectangle structure. + * The coordinate system has its origin in the left upper corner. The x axes + * goes to the right, the y access goes down. + */ +typedef struct zathura_rectangle_s +{ + double x1; /**< X coordinate of point 1 */ + double y1; /**< Y coordinate of point 1 */ + double x2; /**< X coordinate of point 2 */ + double y2; /**< Y coordinate of point 2 */ +} zathura_rectangle_t; + +/** + * Image structure + */ +typedef struct zathura_image_s +{ + zathura_rectangle_t position; /**< Coordinates of the image */ + void* data; /**< Custom data of the plugin */ +} zathura_image_t; + +/** + * Possible link types + */ +typedef enum zathura_link_type_e +{ + ZATHURA_LINK_INVALID, /**< Invalid type */ + ZATHURA_LINK_NONE, /**< No action */ + ZATHURA_LINK_GOTO_DEST, /**< Links to a page */ + ZATHURA_LINK_GOTO_REMOTE, /**< Links to a page */ + ZATHURA_LINK_URI, /**< Links to an external source */ + ZATHURA_LINK_LAUNCH, /**< Links to an external source */ + ZATHURA_LINK_NAMED /**< Links to an external source */ +} zathura_link_type_t; + +typedef enum zathura_link_destination_type_e +{ + ZATHURA_LINK_DESTINATION_UNKNOWN, + ZATHURA_LINK_DESTINATION_XYZ, + ZATHURA_LINK_DESTINATION_FIT, + ZATHURA_LINK_DESTINATION_FITH, + ZATHURA_LINK_DESTINATION_FITV, + ZATHURA_LINK_DESTINATION_FITR, + ZATHURA_LINK_DESTINATION_FITB, + ZATHURA_LINK_DESTINATION_FITBH, + ZATHURA_LINK_DESTINATION_FITBV +} zathura_link_destination_type_t; + +typedef struct zathura_link_target_s +{ + zathura_link_destination_type_t destination_type; + char* value; /**< Value */ + unsigned int page_number; /**< Page number */ + double left; /**< Left coordinate */ + double right; /**< Right coordinate */ + double top; /**< Top coordinate */ + double bottom; /**< Bottom coordinate */ + double scale; /**< Scale */ +} zathura_link_target_t; + +/** + * Link + */ +typedef struct zathura_link_s zathura_link_t; + +/** + * Index element + */ +typedef struct zathura_index_element_s +{ + char* title; /**< Title of the element */ + zathura_link_t* link; +} zathura_index_element_t; + +/** + * Form type + */ +typedef enum zathura_form_type_e +{ + ZATHURA_FORM_CHECKBOX, /**< Checkbox */ + ZATHURA_FORM_TEXTFIELD /**< Textfield */ +} zathura_form_type_t; + +/** + * Form element + */ +typedef struct zathura_form_s +{ + zathura_rectangle_t position; /**< Position */ + zathura_form_type_t type; /**< Type */ +} zathura_form_t; + +/** + * Create new index element + * + * @param title Title of the index element + * @return Index element + */ +zathura_index_element_t* zathura_index_element_new(const char* title); + +/** + * Free index element + * + * @param index The index element + */ +void zathura_index_element_free(zathura_index_element_t* index); + +/** + * Creates a list that should be used to store \ref + * zathura_document_information_entry_t entries + * + * @return A list or NULL if an error occured + */ +girara_list_t* zathura_document_information_entry_list_new(); + +/** + * Creates a new document information entry + * + * @param type The type + * @param value The value + * + * @return A new entry or NULL if an error occured + */ +zathura_document_information_entry_t* +zathura_document_information_entry_new(zathura_document_information_type_t + type, const char* value); + +/** + * Frees a document information entry + * + * @param entry The entry that should be freed + */ +void zathura_document_information_entry_free(zathura_document_information_entry_t* entry); + +#endif // TYPES_H diff --git a/utils.c b/utils.c index 5c5bcbc..135861f 100644 --- a/utils.c +++ b/utils.c @@ -8,10 +8,18 @@ #include #include #include +#include +#include +#include +#include +#include "links.h" #include "utils.h" #include "zathura.h" +#include "internal.h" #include "document.h" +#include "page.h" +#include "plugin.h" #include @@ -44,7 +52,7 @@ file_get_extension(const char* path) bool file_valid_extension(zathura_t* zathura, const char* path) { - if (zathura == NULL || path == NULL) { + if (zathura == NULL || path == NULL || zathura->plugins.manager == NULL) { return false; } @@ -53,16 +61,10 @@ file_valid_extension(zathura_t* zathura, const char* path) return false; } - bool result = false; - GIRARA_LIST_FOREACH(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping) - if (g_content_type_equals(content_type, mapping->type)) { - result = true; - break; - } - GIRARA_LIST_FOREACH_END(zathura->plugins.type_plugin_mapping, zathura_type_plugin_mapping_t*, iter, mapping); - + zathura_plugin_t* plugin = zathura_plugin_manager_get_plugin(zathura->plugins.manager, content_type); g_free((void*)content_type); - return result; + + return (plugin == NULL) ? false : true; } bool @@ -149,11 +151,14 @@ document_index_build(GtkTreeModel* model, GtkTreeIter* parent, GIRARA_LIST_FOREACH(list, girara_tree_node_t*, iter, node) zathura_index_element_t* index_element = (zathura_index_element_t*)girara_node_get_data(node); + zathura_link_type_t type = zathura_link_get_type(index_element->link); + zathura_link_target_t target = zathura_link_get_target(index_element->link); + gchar* description = NULL; - if (index_element->type == ZATHURA_LINK_TO_PAGE) { - description = g_strdup_printf("Page %d", index_element->target.page_number); + if (type == ZATHURA_LINK_GOTO_DEST) { + description = g_strdup_printf("Page %d", target.page_number); } else { - description = g_strdup(index_element->target.uri); + description = g_strdup(target.value); } GtkTreeIter tree_iter; @@ -170,13 +175,13 @@ document_index_build(GtkTreeModel* model, GtkTreeIter* parent, } void -page_calculate_offset(zathura_page_t* page, page_offset_t* offset) +page_calculate_offset(zathura_t* zathura, zathura_page_t* page, page_offset_t* offset) { - g_return_if_fail(page != NULL && page->document != NULL && page->document->zathura != NULL && offset != NULL); - zathura_document_t* document = page->document; - zathura_t* zathura = document->zathura; + g_return_if_fail(page != NULL); + g_return_if_fail(offset != NULL); + GtkWidget* widget = zathura_page_get_widget(zathura, page); - g_return_if_fail(gtk_widget_translate_coordinates(page->drawing_area, + g_return_if_fail(gtk_widget_translate_coordinates(widget, zathura->ui.page_widget, 0, 0, &(offset->x), &(offset->y)) == true); } @@ -215,39 +220,53 @@ zathura_rectangle_t rotate_rectangle(zathura_rectangle_t rectangle, unsigned int zathura_rectangle_t recalc_rectangle(zathura_page_t* page, zathura_rectangle_t rectangle) { - if (page == NULL || page->document == NULL) { - return rectangle; + if (page == NULL) { + goto error_ret; } + zathura_document_t* document = zathura_page_get_document(page); + + if (document == NULL) { + goto error_ret; + } + + double page_height = zathura_page_get_height(page); + double page_width = zathura_page_get_width(page); + double scale = zathura_document_get_scale(document); + zathura_rectangle_t tmp; - switch (page->document->rotate) { + switch (zathura_document_get_rotation(document)) { case 90: - tmp.x1 = (page->height - rectangle.y2) * page->document->scale; - tmp.x2 = (page->height - rectangle.y1) * page->document->scale; - tmp.y1 = rectangle.x1 * page->document->scale; - tmp.y2 = rectangle.x2 * page->document->scale; + tmp.x1 = (page_height - rectangle.y2) * scale; + tmp.x2 = (page_height - rectangle.y1) * scale; + tmp.y1 = rectangle.x1 * scale; + tmp.y2 = rectangle.x2 * scale; break; case 180: - tmp.x1 = (page->width - rectangle.x2) * page->document->scale; - tmp.x2 = (page->width - rectangle.x1) * page->document->scale; - tmp.y1 = (page->height - rectangle.y2) * page->document->scale; - tmp.y2 = (page->height - rectangle.y1) * page->document->scale; + tmp.x1 = (page_width - rectangle.x2) * scale; + tmp.x2 = (page_width - rectangle.x1) * scale; + tmp.y1 = (page_height - rectangle.y2) * scale; + tmp.y2 = (page_height - rectangle.y1) * scale; break; case 270: - tmp.x1 = rectangle.y1 * page->document->scale; - tmp.x2 = rectangle.y2 * page->document->scale; - tmp.y1 = (page->width - rectangle.x2) * page->document->scale; - tmp.y2 = (page->width - rectangle.x1) * page->document->scale; + tmp.x1 = rectangle.y1 * scale; + tmp.x2 = rectangle.y2 * scale; + tmp.y1 = (page_width - rectangle.x2) * scale; + tmp.y2 = (page_width - rectangle.x1) * scale; break; default: - tmp.x1 = rectangle.x1 * page->document->scale; - tmp.x2 = rectangle.x2 * page->document->scale; - tmp.y1 = rectangle.y1 * page->document->scale; - tmp.y2 = rectangle.y2 * page->document->scale; + tmp.x1 = rectangle.x1 * scale; + tmp.x2 = rectangle.x2 * scale; + tmp.y1 = rectangle.y1 * scale; + tmp.y2 = rectangle.y2 * scale; } return tmp; + +error_ret: + + return rectangle; } void @@ -262,11 +281,62 @@ page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned { g_return_if_fail(page != NULL && page_height != NULL && page_width != NULL); - if (rotate && page->document->rotate % 180) { - *page_width = ceil(page->height * page->document->scale); - *page_height = ceil(page->width * page->document->scale); + zathura_document_t* document = zathura_page_get_document(page); + if (document == NULL) { + return; + } + + double height = zathura_page_get_height(page); + double width = zathura_page_get_width(page); + double scale = zathura_document_get_scale(document); + + if (rotate && zathura_document_get_rotation(document) % 180) { + *page_width = ceil(height * scale); + *page_height = ceil(width * scale); } else { - *page_width = ceil(page->width * page->document->scale); - *page_height = ceil(page->height * page->document->scale); + *page_width = ceil(width * scale); + *page_height = ceil(height * scale); + } +} + +GtkWidget* +zathura_page_get_widget(zathura_t* zathura, zathura_page_t* page) +{ + if (zathura == NULL || page == NULL || zathura->pages == NULL) { + return NULL; + } + + unsigned int page_number = zathura_page_get_index(page); + + return zathura->pages[page_number]; +} + +void +readjust_view_after_zooming(zathura_t *zathura, float old_zoom) { + if (zathura == NULL || zathura->document == NULL) { + return; + } + + GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); + GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window); + GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window); + + double scale = zathura_document_get_scale(zathura->document); + gdouble valx = gtk_adjustment_get_value(hadjustment) / old_zoom * scale; + gdouble valy = gtk_adjustment_get_value(vadjustment) / old_zoom * scale; + + position_set_delayed(zathura, valx, valy); +} + +void +document_draw_search_results(zathura_t* zathura, bool value) +{ + if (zathura == NULL || zathura->document == NULL || zathura->pages == NULL) { + return; + } + + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + g_object_set(zathura->pages[page_id], "draw-search-results", (value == true) ? TRUE : FALSE, NULL); } } diff --git a/utils.h b/utils.h index 418ba58..504c7e2 100644 --- a/utils.h +++ b/utils.h @@ -58,11 +58,12 @@ void document_index_build(GtkTreeModel* model, GtkTreeIter* parent, girara_tree_ * Calculates the offset of the page to the top of the viewing area as * well as to the left side of it. The result has to be freed. * + * @param zathura Zathura session * @param page The Page * @param offset Applied offset * @return The calculated offset or NULL if an error occured */ -void page_calculate_offset(zathura_page_t* page, page_offset_t* offset); +void page_calculate_offset(zathura_t* zathura, zathura_page_t* page, page_offset_t* offset); /** * Rotate a rectangle by 0, 90, 180 or 270 degree @@ -103,5 +104,30 @@ void set_adjustment(GtkAdjustment* adjust, gdouble value); void page_calc_height_width(zathura_page_t* page, unsigned int* page_height, unsigned int* page_width, bool rotate); +/** + * Returns the page widget of the page + * + * @param zathura The zathura instance + * @param page The page object + * @return The page widget of the page + * @return NULL if an error occured + */ +GtkWidget* zathura_page_get_widget(zathura_t* zathura, zathura_page_t* page); + +/** + * Re-adjust view + * + * @param zathura Zathura instance + * @param old_zoom Old zoom value + */ +void readjust_view_after_zooming(zathura_t* zathura, float old_zoom); + +/** + * Set if the search results should be drawn or not + * + * @param zathura Zathura instance + * @param value true if they should be drawn, otherwise false + */ +void document_draw_search_results(zathura_t* zathura, bool value); #endif // UTILS_H diff --git a/version.h.in b/version.h.in index 91fbe70..d35d791 100644 --- a/version.h.in +++ b/version.h.in @@ -4,7 +4,7 @@ #define ZATHURA_VERSION_H #define ZATHURA_VERSION_MAJOR ZVMAJOR -#define ZATHUAR_VERSION_MINOR ZVMINOR +#define ZATHURA_VERSION_MINOR ZVMINOR #define ZATHURA_VERSION_REV ZVREV #define ZATHURA_VERSION "ZVMAJOR.ZVMINOR.ZVREV" #define ZATHURA_API_VERSION ZVAPI diff --git a/zathura.1.rst b/zathura.1.rst index e558480..8c3a496 100644 --- a/zathura.1.rst +++ b/zathura.1.rst @@ -14,7 +14,6 @@ SYNOPOSIS ========= | zathura [OPTION]... | zathura [OPTION]... FILE -| zathura [OPTION]... FILE PASSWORD DESCRIPTION =========== @@ -37,6 +36,9 @@ OPTIONS -p [path], --plugins-dir [path] Path to the directory containing plugins +-w [password], --password [password] + The documents password + --fork Fork into the background @@ -133,6 +135,8 @@ blist List bookmarks close Close document +exec + Execute an external command info Show document information help diff --git a/zathura.c b/zathura.c index 031888b..fd5acf0 100644 --- a/zathura.c +++ b/zathura.c @@ -26,8 +26,11 @@ #include "shortcuts.h" #include "zathura.h" #include "utils.h" +#include "marks.h" #include "render.h" +#include "page.h" #include "page-widget.h" +#include "plugin.h" typedef struct zathura_document_info_s { @@ -36,6 +39,19 @@ typedef struct zathura_document_info_s const char* password; } zathura_document_info_t; +typedef struct page_set_delayed_s +{ + zathura_t* zathura; + unsigned int page; +} page_set_delayed_t; + +typedef struct position_set_delayed_s +{ + zathura_t* zathura; + double position_x; + double position_y; +} position_set_delayed_t; + static gboolean document_info_open(gpointer data); static gboolean purge_pages(gpointer data); @@ -50,20 +66,21 @@ zathura_init(int argc, char* argv[]) Window embed = 0; #endif - gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL; + gchar* config_dir = NULL, *data_dir = NULL, *plugin_path = NULL, *loglevel = NULL, *password = NULL; bool forkback = false; GOptionEntry entries[] = { - { "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 }, - { "debug", 'l', 0, G_OPTION_ARG_STRING, &loglevel, _("Log level (debug, info, warning, error)"), "level" }, + { "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 }, + { "password", 'w', 0, G_OPTION_ARG_STRING, &password, _("Document password"), "password" }, + { "debug", 'l', 0, G_OPTION_ARG_STRING, &loglevel, _("Log level (debug, info, warning, error)"), "level" }, { NULL, '\0', 0, 0, NULL, NULL, NULL } }; - GOptionContext* context = g_option_context_new(" [file] [password]"); + GOptionContext* context = g_option_context_new(" [file1] [file2] [...]"); g_option_context_add_main_entries(context, entries, NULL); GError* error = NULL; @@ -101,12 +118,12 @@ zathura_init(int argc, char* argv[]) zathura_t* zathura = g_malloc0(sizeof(zathura_t)); /* plugins */ - zathura->plugins.plugins = girara_list_new2( - (girara_free_function_t)zathura_document_plugin_free); - zathura->plugins.path = girara_list_new2(g_free); - zathura->plugins.type_plugin_mapping = girara_list_new2( - (girara_free_function_t)zathura_type_plugin_mapping_free); + zathura->plugins.manager = zathura_plugin_manager_new(); + if (zathura->plugins.manager == NULL) { + goto error_free; + } + /* configuration and data */ if (config_dir != NULL) { zathura->config.config_dir = g_strdup(config_dir); } else { @@ -116,7 +133,7 @@ zathura_init(int argc, char* argv[]) } if (data_dir != NULL) { - zathura->config.data_dir = g_strdup(config_dir); + zathura->config.data_dir = g_strdup(data_dir); } else { gchar* path = girara_get_xdg_path(XDG_DATA); zathura->config.data_dir = g_build_filename(path, "zathura", NULL); @@ -129,12 +146,16 @@ zathura_init(int argc, char* argv[]) if (plugin_path != NULL) { girara_list_t* paths = girara_split_path_array(plugin_path); - girara_list_merge(zathura->plugins.path, paths); + GIRARA_LIST_FOREACH(paths, char*, iter, path) + zathura_plugin_manager_add_dir(zathura->plugins.manager, path); + GIRARA_LIST_FOREACH_END(paths, char*, iter, path); girara_list_free(paths); } else { #ifdef ZATHURA_PLUGINDIR girara_list_t* paths = girara_split_path_array(ZATHURA_PLUGINDIR); - girara_list_merge(zathura->plugins.path, paths); + GIRARA_LIST_FOREACH(paths, char*, iter, path) + zathura_plugin_manager_add_dir(zathura->plugins.manager, path); + GIRARA_LIST_FOREACH_END(paths, char*, iter, path); girara_list_free(paths); #endif } @@ -144,14 +165,15 @@ zathura_init(int argc, char* argv[]) goto error_out; } - zathura->ui.session->global.data = zathura; + zathura->ui.session->global.data = zathura; /* global settings */ zathura->global.recolor = false; zathura->global.update_page_number = true; + zathura->global.arguments = argv; /* load plugins */ - zathura_document_plugins_load(zathura); + zathura_plugin_manager_load(zathura->plugins.manager); /* configuration */ config_load_default(zathura); @@ -180,11 +202,12 @@ zathura_init(int argc, char* argv[]) zathura->ui.session->gtk.embed = embed; if (girara_session_init(zathura->ui.session, "zathura") == false) { - goto error_out; + goto error_free; } /* girara events */ - zathura->ui.session->events.buffer_changed = cb_buffer_changed; + zathura->ui.session->events.buffer_changed = cb_buffer_changed; + zathura->ui.session->events.unknown_command = cb_unknown_command; /* page view */ zathura->ui.page_widget = gtk_table_new(0, 0, TRUE); @@ -270,8 +293,19 @@ zathura_init(int argc, char* argv[]) document_info->zathura = zathura; document_info->path = argv[1]; - document_info->password = (argc >= 2) ? argv[2] : NULL; + document_info->password = password; gdk_threads_add_idle(document_info_open, document_info); + + /* open additional files */ + for (int i = 2; i < argc; i++) { + char* new_argv[] = { + *(zathura->global.arguments), + argv[i], + NULL + }; + + g_spawn_async(NULL, new_argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL, NULL, NULL); + } } /* add even to purge old pages */ @@ -333,9 +367,7 @@ zathura_free(zathura_t* zathura) } /* free registered plugins */ - girara_list_free(zathura->plugins.type_plugin_mapping); - girara_list_free(zathura->plugins.plugins); - girara_list_free(zathura->plugins.path); + zathura_plugin_manager_free(zathura->plugins.manager); /* free config variables */ g_free(zathura->config.config_dir); @@ -431,18 +463,94 @@ document_info_open(gpointer data) bool document_open(zathura_t* zathura, const char* path, const char* password) { - if (path == NULL) { + if (zathura == NULL || zathura->plugins.manager == NULL || path == NULL) { goto error_out; } - zathura_document_t* document = zathura_document_open(zathura, path, password); + zathura_error_t error = ZATHURA_ERROR_OK; + zathura_document_t* document = zathura_document_open(zathura->plugins.manager, path, password, &error); if (document == NULL) { + if (error == ZATHURA_ERROR_INVALID_PASSWORD) { + zathura_password_dialog_info_t* password_dialog_info = malloc(sizeof(zathura_password_dialog_info_t)); + if (password_dialog_info != NULL) { + password_dialog_info->zathura = zathura; + + if (path != NULL) { + password_dialog_info->path = g_strdup(path); + girara_dialog(zathura->ui.session, "Enter password:", true, NULL, + (girara_callback_inputbar_activate_t) cb_password_dialog, password_dialog_info); + goto error_out; + } else { + free(password_dialog_info); + } + } + goto error_out; + } goto error_out; } + const char* file_path = zathura_document_get_path(document); + unsigned int number_of_pages = zathura_document_get_number_of_pages(document); + + /* read history file */ + zathura_fileinfo_t file_info = { 0, 0, 1, 0, 1, 0, 0 }; + bool known_file = zathura_db_get_fileinfo(zathura->database, file_path, &file_info); + + /* set page offset */ + zathura_document_set_page_offset(document, file_info.page_offset); + + /* check for valid scale value */ + if (file_info.scale <= FLT_EPSILON) { + girara_warning("document info: '%s' has non positive scale", file_path); + zathura_document_set_scale(document, 1); + } else { + zathura_document_set_scale(document, file_info.scale); + } + + /* check current page number */ + if (file_info.current_page > number_of_pages) { + girara_warning("document info: '%s' has an invalid page number", file_path); + zathura_document_set_current_page_number(document, 0); + } else { + zathura_document_set_current_page_number(document, file_info.current_page); + } + + /* check for valid rotation */ + if (file_info.rotation % 90 != 0) { + girara_warning("document info: '%s' has an invalid rotation", file_path); + zathura_document_set_rotation(document, 0); + } else { + zathura_document_set_rotation(document, file_info.rotation % 360); + } + + /* jump to first page if setting enabled */ + bool always_first_page = false; + girara_setting_get(zathura->ui.session, "open-first-page", &always_first_page); + if (always_first_page == true) { + zathura_document_set_current_page_number(document, 0); + } + + /* apply open adjustment */ + char* adjust_open = "best-fit"; + if (known_file == false && girara_setting_get(zathura->ui.session, "adjust-open", &(adjust_open)) == true) { + if (g_strcmp0(adjust_open, "best-fit") == 0) { + zathura_document_set_adjust_mode(document, ZATHURA_ADJUST_BESTFIT); + } else if (g_strcmp0(adjust_open, "width") == 0) { + zathura_document_set_adjust_mode(document, ZATHURA_ADJUST_WIDTH); + } else { + zathura_document_set_adjust_mode(document, ZATHURA_ADJUST_NONE); + } + g_free(adjust_open); + } else { + zathura_document_set_adjust_mode(document, ZATHURA_ADJUST_NONE); + } + + /* update statusbar */ + girara_statusbar_item_set_text(zathura->ui.session, zathura->ui.statusbar.file, file_path); + /* install file monitor */ - gchar* file_uri = g_filename_to_uri(document->file_path, NULL, NULL); + gchar* file_uri = g_filename_to_uri(file_path, NULL, NULL); if (file_uri == NULL) { goto error_free; } @@ -463,25 +571,64 @@ document_open(zathura_t* zathura, const char* path, const char* password) } if (zathura->file_monitor.file_path == NULL) { - zathura->file_monitor.file_path = g_strdup(document->file_path); + zathura->file_monitor.file_path = g_strdup(file_path); if (zathura->file_monitor.file_path == NULL) { goto error_free; } } - if (document->password != NULL) { + if (password != NULL) { g_free(zathura->file_monitor.password); - zathura->file_monitor.password = g_strdup(document->password); + zathura->file_monitor.password = g_strdup(password); if (zathura->file_monitor.password == NULL) { goto error_free; } } + /* create marks list */ + zathura->global.marks = girara_list_new2((girara_free_function_t) mark_free); + if (zathura->global.marks == NULL) { + goto error_free; + } + zathura->document = document; + /* create blank pages */ + zathura->pages = calloc(number_of_pages, sizeof(GtkWidget*)); + if (zathura->pages == NULL) { + goto error_free; + } + + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + zathura_page_t* page = zathura_document_get_page(document, page_id); + if (page == NULL) { + goto error_free; + } + + GtkWidget* page_widget = zathura_page_widget_new(zathura, page); + if (page_widget == NULL) { + goto error_free; + } + + zathura->pages[page_id] = page_widget; + + /* set widget size */ + unsigned int page_height = 0; + unsigned int page_width = 0; + page_calc_height_width(page, &page_height, &page_width, true); + + gtk_widget_set_size_request(page_widget, page_width, page_height); + } + /* view mode */ int pages_per_row = 1; - girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row); + if (file_info.pages_per_row > 0) { + pages_per_row = file_info.pages_per_row; + } else { + girara_setting_get(zathura->ui.session, "pages-per-row", &pages_per_row); + } + + girara_setting_set(zathura->ui.session, "pages-per-row", &pages_per_row); page_widget_set_mode(zathura, pages_per_row); girara_set_view(zathura->ui.session, zathura->ui.page_widget_alignment); @@ -493,22 +640,29 @@ document_open(zathura_t* zathura, const char* path, const char* password) goto error_free; } - /* create blank pages */ - for (unsigned int page_id = 0; page_id < document->number_of_pages; page_id++) { - zathura_page_t* page = document->pages[page_id]; - gtk_widget_realize(page->drawing_area); + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + gtk_widget_realize(zathura->pages[page_id]); } /* bookmarks */ - zathura_bookmarks_load(zathura, zathura->document->file_path); - - page_set_delayed(zathura, document->current_page_number); - cb_view_vadjustment_value_changed(NULL, zathura); + zathura_bookmarks_load(zathura, file_path); /* update title */ - girara_set_window_title(zathura->ui.session, document->file_path); + girara_set_window_title(zathura->ui.session, file_path); - free(file_uri); + g_free(file_uri); + + /* adjust window */ + girara_argument_t argument = { zathura_document_get_adjust_mode(document), NULL }; + sc_adjust_window(zathura->ui.session, &argument, NULL, 0); + + /* set position */ + if (file_info.position_x != 0 || file_info.position_y != 0) { + position_set_delayed(zathura, file_info.position_x, file_info.position_y); + } else { + page_set_delayed(zathura, zathura_document_get_current_page_number(document)); + cb_view_vadjustment_value_changed(NULL, zathura); + } return true; @@ -540,10 +694,10 @@ document_save(zathura_t* zathura, const char* path, bool overwrite) return false; } - zathura_plugin_error_t error = zathura_document_save_as(zathura->document, file_path); + zathura_error_t error = zathura_document_save_as(zathura->document, file_path); g_free(file_path); - return (error == ZATHURA_PLUGIN_ERROR_OK) ? true : false; + return (error == ZATHURA_ERROR_OK) ? true : false; } static void @@ -587,19 +741,56 @@ document_close(zathura_t* zathura, bool keep_monitor) } } - /* 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); + /* remove marks */ + if (zathura->global.marks != NULL) { + girara_list_free(zathura->global.marks); + zathura->global.marks = NULL; + } + /* store file information */ + const char* path = zathura_document_get_path(zathura->document); + + zathura_fileinfo_t file_info = { 0, 0, 1, 0, 1, 0, 0 }; + file_info.current_page = zathura_document_get_current_page_number(zathura->document); + file_info.page_offset = zathura_document_get_page_offset(zathura->document); + file_info.scale = zathura_document_get_scale(zathura->document); + file_info.rotation = zathura_document_get_rotation(zathura->document); + + girara_setting_get(zathura->ui.session, "pages-per-row", &(file_info.pages_per_row)); + + /* get position */ + GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(zathura->ui.session->gtk.view); + GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window); + GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window); + + file_info.position_x = gtk_adjustment_get_value(hadjustment); + file_info.position_y = gtk_adjustment_get_value(vadjustment); + + /* save file info */ + zathura_db_set_fileinfo(zathura->database, path, &file_info); + + /* release render thread */ render_free(zathura->sync.render_thread); zathura->sync.render_thread = NULL; - gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer)1); + /* remove widgets */ + gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer) 1); + for (unsigned int i = 0; i < zathura_document_get_number_of_pages(zathura->document); i++) { + g_object_unref(zathura->pages[i]); + } + free(zathura->pages); + zathura->pages = NULL; + /* remove document */ zathura_document_free(zathura->document); zathura->document = NULL; + /* remove index */ + if (zathura->ui.index != NULL) { + g_object_ref_sink(zathura->ui.index); + zathura->ui.index = NULL; + } + gtk_widget_hide(zathura->ui.page_widget); statusbar_page_number_update(zathura); @@ -614,12 +805,6 @@ document_close(zathura_t* zathura, bool keep_monitor) return true; } -typedef struct page_set_delayed_s -{ - zathura_t* zathura; - unsigned int page; -} page_set_delayed_t; - static gboolean page_set_delayed_impl(gpointer data) { @@ -633,8 +818,8 @@ page_set_delayed_impl(gpointer data) 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) { + if (zathura == NULL || zathura->document == NULL || + (page_id >= zathura_document_get_number_of_pages(zathura->document))) { return false; } @@ -648,26 +833,22 @@ page_set_delayed(zathura_t* zathura, unsigned int page_id) bool page_set(zathura_t* zathura, unsigned int page_id) { - if (zathura == NULL || zathura->document == NULL || zathura->document->pages == NULL) { - goto error_out; - } - - if (page_id >= zathura->document->number_of_pages) { + if (zathura == NULL || zathura->document == NULL) { goto error_out; } /* render page */ - zathura_page_t* page = zathura->document->pages[page_id]; + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); if (page == NULL) { goto error_out; } - zathura->document->current_page_number = page_id; + zathura_document_set_current_page_number(zathura->document, page_id); zathura->global.update_page_number = false; page_offset_t offset; - page_calculate_offset(page, &offset); + page_calculate_offset(zathura, page, &offset); 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)); @@ -690,8 +871,11 @@ statusbar_page_number_update(zathura_t* zathura) return; } + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + unsigned int current_page_number = zathura_document_get_current_page_number(zathura->document); + if (zathura->document != NULL) { - char* page_number_text = g_strdup_printf("[%d/%d]", zathura->document->current_page_number + 1, zathura->document->number_of_pages); + char* page_number_text = g_strdup_printf("[%d/%d]", current_page_number + 1, 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 { @@ -713,12 +897,16 @@ page_widget_set_mode(zathura_t* zathura, unsigned int pages_per_row) gtk_container_foreach(GTK_CONTAINER(zathura->ui.page_widget), remove_page_from_table, (gpointer)0); - gtk_table_resize(GTK_TABLE(zathura->ui.page_widget), ceil(zathura->document->number_of_pages / pages_per_row), pages_per_row); - for (unsigned int i = 0; i < zathura->document->number_of_pages; i++) + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + gtk_table_resize(GTK_TABLE(zathura->ui.page_widget), ceil(number_of_pages / pages_per_row), pages_per_row); + for (unsigned int i = 0; i < number_of_pages; i++) { int x = i % pages_per_row; int y = i / pages_per_row; - 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); + + zathura_page_t* page = zathura_document_get_page(zathura->document, i); + GtkWidget* page_widget = zathura_page_get_widget(zathura, page); + gtk_table_attach(GTK_TABLE(zathura->ui.page_widget), page_widget, x, x + 1, y, y + 1, GTK_SHRINK, GTK_SHRINK, 0, 0); } gtk_widget_show_all(zathura->ui.page_widget); @@ -738,9 +926,42 @@ gboolean purge_pages(gpointer data) 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); + unsigned int number_of_pages = zathura_document_get_number_of_pages(zathura->document); + for (unsigned int page_id = 0; page_id < number_of_pages; page_id++) { + zathura_page_t* page = zathura_document_get_page(zathura->document, page_id); + GtkWidget* page_widget = zathura_page_get_widget(zathura, page); + zathura_page_widget_purge_unused(ZATHURA_PAGE(page_widget), threshold); } return TRUE; } + +static gboolean +position_set_delayed_impl(gpointer data) +{ + position_set_delayed_t* p = (position_set_delayed_t*) data; + + GtkScrolledWindow *window = GTK_SCROLLED_WINDOW(p->zathura->ui.session->gtk.view); + GtkAdjustment* vadjustment = gtk_scrolled_window_get_vadjustment(window); + GtkAdjustment* hadjustment = gtk_scrolled_window_get_hadjustment(window); + + set_adjustment(hadjustment, p->position_x); + set_adjustment(vadjustment, p->position_y); + + g_free(p); + + return FALSE; +} + +bool +position_set_delayed(zathura_t* zathura, double position_x, double position_y) +{ + position_set_delayed_t* p = g_malloc0(sizeof(position_set_delayed_t)); + + p->zathura = zathura; + p->position_x = position_x; + p->position_y = position_y; + + gdk_threads_add_idle(position_set_delayed_impl, p); + + return FALSE; +} diff --git a/zathura.h b/zathura.h index fc56686..9e40dcb 100644 --- a/zathura.h +++ b/zathura.h @@ -7,21 +7,15 @@ #include #include #include "macros.h" +#include "types.h" enum { NEXT, PREVIOUS, LEFT, RIGHT, UP, DOWN, BOTTOM, TOP, HIDE, HIGHLIGHT, DELETE_LAST_WORD, DELETE_LAST_CHAR, DEFAULT, ERROR, WARNING, NEXT_GROUP, PREVIOUS_GROUP, ZOOM_IN, ZOOM_OUT, ZOOM_ORIGINAL, ZOOM_SPECIFIC, FORWARD, - BACKWARD, ADJUST_BESTFIT, ADJUST_WIDTH, ADJUST_NONE, CONTINUOUS, DELETE_LAST, - ADD_MARKER, EVAL_MARKER, EXPAND, EXPAND_ALL, COLLAPSE_ALL, COLLAPSE, SELECT, - GOTO_DEFAULT, GOTO_LABELS, GOTO_OFFSET, HALF_UP, HALF_DOWN, FULL_UP, - FULL_DOWN, HALF_LEFT, HALF_RIGHT, FULL_LEFT, FULL_RIGHT, NEXT_CHAR, PREVIOUS_CHAR, - DELETE_TO_LINE_START, APPEND_FILEPATH, ROTATE_CW, ROTATE_CCW }; - -/* forward declaration for types from document.h */ -struct zathura_document_s; -struct zathura_page_s; -typedef struct zathura_document_s zathura_document_t; -typedef struct zathura_page_s zathura_page_t; + BACKWARD, CONTINUOUS, DELETE_LAST, EXPAND, EXPAND_ALL, COLLAPSE_ALL, COLLAPSE, + SELECT, GOTO_DEFAULT, GOTO_LABELS, GOTO_OFFSET, HALF_UP, HALF_DOWN, FULL_UP, + FULL_DOWN, HALF_LEFT, HALF_RIGHT, FULL_LEFT, FULL_RIGHT, NEXT_CHAR, + PREVIOUS_CHAR, DELETE_TO_LINE_START, APPEND_FILEPATH, ROTATE_CW, ROTATE_CCW }; /* forward declaration for types form database.h */ typedef struct _ZathuraDatabase zathura_database_t; @@ -30,7 +24,7 @@ typedef struct _ZathuraDatabase zathura_database_t; struct render_thread_s; typedef struct render_thread_s render_thread_t; -typedef struct zathura_s +struct zathura_s { struct { @@ -63,9 +57,7 @@ typedef struct zathura_s struct { - girara_list_t* plugins; /**< List of plugins */ - girara_list_t* path; /**< List of plugin paths */ - girara_list_t* type_plugin_mapping; /**< List of type -> plugin mappings */ + void* manager; /**< Plugin manager */ } plugins; struct @@ -84,6 +76,8 @@ typedef struct zathura_s { bool recolor; /**< Recoloring mode switch */ bool update_page_number; /**< Update current page number */ + girara_list_t* marks; /**< Marker */ + char** arguments; /**> Arguments that were passed at startup */ } global; struct @@ -106,6 +100,7 @@ typedef struct zathura_s } stdin_support; zathura_document_t* document; /**< The current document */ + GtkWidget** pages; /**< The page widgets */ zathura_database_t* database; /**< The database */ /** @@ -117,7 +112,7 @@ typedef struct zathura_s gchar* file_path; /**< Save file path */ gchar* password; /**< Save password */ } file_monitor; -} zathura_t; +}; /** * Initializes zathura @@ -184,6 +179,16 @@ bool page_set(zathura_t* zathura, unsigned int page_id); */ bool page_set_delayed(zathura_t* zathura, unsigned int page_id); +/** + * Moves to the given position + * + * @param zathura Zathura session + * @param position_x X coordinate + * @param position_y Y coordinate + * @return If no error occured true, otherwise false, is returned. + */ +bool position_set_delayed(zathura_t* zathura, double position_x, double position_y); + /** * Builds the box structure to show the rendered pages * diff --git a/zathura.pc.in b/zathura.pc.in index 3ab163f..e76b38d 100644 --- a/zathura.pc.in +++ b/zathura.pc.in @@ -6,4 +6,4 @@ Description: document viewer Version: ${version} URL: http://pwmt.org/projects/zathura Cflags: ${INC_PATH} -Requires.private: girara-gtk${GTK_VERSION} gtk+-${GTK_VERSION}.0 +Requires.private: girara-gtk${GTK_VERSION} cairo diff --git a/zathurarc.5.rst b/zathurarc.5.rst index f6821db..0c23b35 100644 --- a/zathurarc.5.rst +++ b/zathurarc.5.rst @@ -279,7 +279,7 @@ n-completion-items ^^^^^^^^^^^^^^^^^^ Defines the maximum number of displayed completion entries. -* Value-type: Integer +* Value type: Integer * Default value: 15 completion-bg @@ -287,7 +287,7 @@ completion-bg Defines the background color that is used for command line completion entries -* Value-type: String +* Value type: String * Default value: #232323 completion-fg @@ -295,7 +295,7 @@ completion-fg Defines the foreground color that is used for command line completion entries -* Value-type: String +* Value type: String * Default value: #DDDDDD completion-group-bg @@ -303,7 +303,7 @@ completion-group-bg Defines the background color that is used for command line completion group elements -* Value-type: String +* Value type: String * Default value: #000000 completion-group-fg @@ -311,7 +311,7 @@ completion-group-fg Defines the foreground color that is used for command line completion group elements -* Value-type: String +* Value type: String * Default value: #DEDEDE completion-highlight-bg @@ -319,7 +319,7 @@ completion-highlight-bg Defines the background color that is used for the current command line completion element -* Value-type: String +* Value type: String * Default value: #9FBC00 completion-highlight-fg @@ -327,133 +327,140 @@ completion-highlight-fg Defines the foreground color that is used for the current command line completion element -* Value-type: String +* Value type: String * Default value: #232323 default-fg ^^^^^^^^^^ Defines the default foreground color -* Value-type: String +* Value type: String * Default value: #DDDDDD default-bg ^^^^^^^^^^ Defines the default background color -* Value-type: String +* Value type: String * Default value: #000000 +exec-command +^^^^^^^^^^^^ +Defines a command the should be prepanded to any command run with exec. + +* Value type: String +* Default value: + font ^^^^ Defines the font that will be used -* Value-type: String +* Value type: String * Default value: monospace normal 9 inputbar-bg ^^^^^^^^^^^ Defines the background color for the inputbar -* Value-type: String +* Value type: String * Default value: #131313 inputbar-fg ^^^^^^^^^^^ Defines the foreground color for the inputbar -* Value-type: String +* Value type: String * Default value: #9FBC00 notification-error-bg ^^^^^^^^^^^^^^^^^^^^^ Defines the background color for an error notification -* Value-type: String +* Value type: String * Default value: #FFFFFF notification-error-fg ^^^^^^^^^^^^^^^^^^^^^ Defines the foreground color for an error notification -* Value-type: String +* Value type: String * Default value: #FF1212 notification-warning-bg ^^^^^^^^^^^^^^^^^^^^^^^ Defines the background color for a warning notification -* Value-type: String +* Value type: String * Default value: #FFFFFF notification-warning-fg ^^^^^^^^^^^^^^^^^^^^^^^ Defines the foreground color for a warning notification -* Value-type: String +* Value type: String * Default value: #FFF712 tabbar-fg ^^^^^^^^^ Defines the foreground color for a tab -* Value-type: String +* Value type: String * Default value: #FFFFFF tabbar-bg ^^^^^^^^^ Defines the background color for a tab -* Value-type: String +* Value type: String * Default value: #000000 tabbar-focus-fg ^^^^^^^^^^^^^^^ Defines the foreground color for the focused tab -* Value-type: String +* Value type: String * Default value: #9FBC00 tabbar-focus-bg ^^^^^^^^^^^^^^^ Defines the background color for the focused tab -* Value-type: String +* Value type: String * Default value: #000000 show-scrollbars ^^^^^^^^^^^^^^^ Defines if scrollbars should be shown or not -* Value-type: Boolean +* Value type: Boolean * Default value: false statusbar-bg ^^^^^^^^^^^^ Defines the background color of the statusbar -* Value-type: String +* Value type: String * Default value: #000000 statusbar-fg ^^^^^^^^^^^^ Defines the foreground color of the statusbar -* Value-type: String +* Value type: String * Default value: #FFFFFF window-height ^^^^^^^^^^^^^ Defines the window height on startup -* Value-type: Integer +* Value type: Integer * Default value: 600 window-width ^^^^^^^^^^^^ Defines the window width on startup -* Value-type: Integer +* Value type: Integer * Default value: 800 zathura @@ -461,20 +468,34 @@ zathura This section describes settings concerning the behaviour of zathura. +abort-clear-search +^^^^^^^^^^^^^^^^^^ +Defines if the search results should be cleared on abort. + +* Value type: Boolean +* Default value: true + adjust-open ^^^^^^^^^^^ Defines which auto adjustment mode should be used if a document is loaded. Possible options are "best-fit" and "width". -* Value-type: String +* Value type: String * Default value: best-fit +advance-pages-per-row +^^^^^^^^^^^^^^^^^^^^^ +Defines if the number of pages per row should be honored when advancing a page. + +* Value type: Boolean +* Default value: false + highlight-color ^^^^^^^^^^^^^^^ Defines the color that is used for highlighting parts of the document (e.g.: show search results) -* Value-type: String +* Value type: String * Default value: #9FBC00 highlight-active-color @@ -482,21 +503,21 @@ highlight-active-color Defines the color that is used to show the current selected highlighted element (e.g: current search result) -* Value-type: String +* Value type: String * Default value: #00BC00 highlight-transparency ^^^^^^^^^^^^^^^^^^^^^^ Defines the opacity of a highlighted element -* Value-type: Float +* Value type: Float * Default value: 0.5 page-padding ^^^^^^^^^^^^ The page padding defines the gap in pixels between each rendered page. -* Value-type: Integer +* Value type: Integer * Default value: 1 page-store-threshold @@ -504,84 +525,84 @@ page-store-threshold Pages that are not visible get unloaded after some time. Every page that has not been visible for page-store-treshold seconds will be unloaded. -* Value-type: Integer +* Value type: Integer * Default value: 30 page-store-interval ^^^^^^^^^^^^^^^^^^^ Defines the amount of seconds between the check to unload invisible pages. -* Value-type: Integer +* Value type: Integer * Default value: 30 pages-per-row ^^^^^^^^^^^^^ Defines the number of pages that are rendered next to each other in a row. -* Value-type: Integer +* Value type: Integer * Default value: 1 recolor ^^^^^^^ En/Disables recoloring -* Value-type: Boolean +* Value type: Boolean * Default value: false recolor-darkcolor ^^^^^^^^^^^^^^^^^ Defines the color value that is used to represent dark colors in recoloring mode -* Value-type: String +* Value type: String * Default value: #FFFFFF recolor-lightcolor ^^^^^^^^^^^^^^^^^^ Defines the color value that is used to represent light colors in recoloring mode -* Value-type: String +* Value type: String * Default value: #000000 render-loading ^^^^^^^^^^^^^^ Defines if the "Loading..." text should be displayed if a page is rendered. -* Value-type: Boolean +* Value type: Boolean * Default value: true scroll-step ^^^^^^^^^^^ Defines the step size of scrolling by calling the scroll command once -* Value-type: Float +* Value type: Float * Default value: 40 scroll-wrap ^^^^^^^^^^^ Defines if the last/first page should be wrapped -* Value-type: Boolean +* Value type: Boolean * Default value: false zoom-max ^^^^^^^^ Defines the maximum percentage that the zoom level can be -* Value-type: Integer +* Value type: Integer * Default value: 1000 zoom-min ^^^^^^^^ Defines the minimum percentage that the zoom level can be -* Value-type: Integer +* Value type: Integer * Default value: 10 zoom-step ^^^^^^^^^ Defines the amount of percent that is zoomed in or out on each command. -* Value-type: Integer +* Value type: Integer * Default value: 10 SEE ALSO