diff --git a/commands.c b/commands.c index bca85d6..dbd46ea 100644 --- a/commands.c +++ b/commands.c @@ -402,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; } diff --git a/completion.c b/completion.c index c485977..641282e 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, 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/page-widget.c b/page-widget.c index d66750b..5299889 100644 --- a/page-widget.c +++ b/page-widget.c @@ -58,6 +58,7 @@ 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 { @@ -682,7 +683,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++) { @@ -743,10 +745,42 @@ 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); + /* reset */ priv->current_image = 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->current_image != NULL); + g_return_if_fail(priv->images != 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, zathura_image_t*, iter, image_it) + if (image_it == priv->current_image) { + break; + } + + image_id++; + GIRARA_LIST_FOREACH_END(priv->images, 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->current_image = NULL; +} + void zathura_page_widget_update_view_time(ZathuraPage* widget) {