Follow links with sc_follow

This commit is contained in:
Moritz Lipp 2012-02-07 17:31:47 +01:00
parent ba0ee61dfe
commit 3547f80af9
4 changed files with 118 additions and 8 deletions

View File

@ -6,6 +6,7 @@
#include <girara/utils.h> #include <girara/utils.h>
#include <stdlib.h> #include <stdlib.h>
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include <string.h>
#include "callbacks.h" #include "callbacks.h"
#include "zathura.h" #include "zathura.h"
@ -13,6 +14,7 @@
#include "document.h" #include "document.h"
#include "utils.h" #include "utils.h"
#include "shortcuts.h" #include "shortcuts.h"
#include "page_view_widget.h"
gboolean gboolean
cb_destroy(GtkWidget* UNUSED(widget), gpointer UNUSED(data)) cb_destroy(GtkWidget* UNUSED(widget), gpointer UNUSED(data))
@ -146,3 +148,63 @@ cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
} }
bool bool
cb_sc_follow(GtkEntry* entry, girara_session_t* session)
{
g_return_val_if_fail(session != NULL, FALSE);
g_return_val_if_fail(session->global.data != NULL, FALSE);
zathura_t* zathura = session->global.data;
char* input = gtk_editable_get_chars(GTK_EDITABLE(entry), 0, -1);
if (input == NULL) {
goto error_ret;
} else if (strlen(input) == 0) {
goto error_free;
}
int index = atoi(input);
if (index == 0 && g_strcmp0(input, "0") != 0) {
girara_notify(session, GIRARA_WARNING, "Invalid input '%s' given.", input);
goto error_free;
}
/* set pages to draw links */
bool invalid_index = true;
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) {
zathura_page_t* page = zathura->document->pages[page_id];
if (page == NULL || page->visible == false) {
continue;
}
zathura_link_t* link = zathura_page_view_link_get(ZATHURA_PAGE_VIEW(page->drawing_area), index);
if (link != NULL) {
switch (link->type) {
case ZATHURA_LINK_TO_PAGE:
page_set_delayed(zathura, link->target.page_number);
break;
case ZATHURA_LINK_EXTERNAL:
girara_xdg_open(link->target.value);
break;
}
invalid_index = false;
break;
}
}
if (invalid_index == true) {
girara_notify(session, GIRARA_WARNING, "Invalid index '%s' given.", input);
}
g_free(input);
return TRUE;
error_free:
g_free(input);
error_ret:
return FALSE;
}

View File

@ -51,4 +51,13 @@ void cb_pages_per_row_value_changed(girara_session_t* GIRARA_UNUSED(session), co
void cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path, void cb_index_row_activated(GtkTreeView* tree_view, GtkTreePath* path,
GtkTreeViewColumn* column, void* zathura); GtkTreeViewColumn* column, void* zathura);
/**
* Called when input has been passed to the sc_follow dialog
*
* @param entry The dialog inputbar
* @param session The girara session
* @return TRUE
*/
bool cb_sc_follow(GtkEntry* entry, girara_session_t* session);
#endif // CALLBACKS_H #endif // CALLBACKS_H

View File

@ -18,6 +18,8 @@ typedef struct zathura_page_view_private_s {
bool links_got; /**< True if we already tried to retrieve the list of links */ bool links_got; /**< True if we already tried to retrieve the list of links */
bool draw_links; /**< True if links should be drawn */ bool draw_links; /**< True if links should be drawn */
girara_list_t* search_results; /** True if search results should be drawn */ girara_list_t* search_results; /** True if search results should be drawn */
unsigned int link_offset; /**< Offset to the links */
unsigned int number_of_links; /**< Offset to the links */
} zathura_page_view_private_t; } zathura_page_view_private_t;
#define ZATHURA_PAGE_VIEW_GET_PRIVATE(obj) \ #define ZATHURA_PAGE_VIEW_GET_PRIVATE(obj) \
@ -26,6 +28,7 @@ typedef struct zathura_page_view_private_s {
static gboolean zathura_page_view_expose(GtkWidget* widget, GdkEventExpose* event); static gboolean zathura_page_view_expose(GtkWidget* widget, GdkEventExpose* event);
static void zathura_page_view_finalize(GObject* object); static void zathura_page_view_finalize(GObject* object);
static void zathura_page_view_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec); static void zathura_page_view_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec);
static void zathura_page_view_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec);
static void zathura_page_view_size_allocate(GtkWidget* widget, GdkRectangle* allocation); static void zathura_page_view_size_allocate(GtkWidget* widget, GdkRectangle* allocation);
static void redraw_rect(ZathuraPageView* widget, zathura_rectangle_t* rectangle); static void redraw_rect(ZathuraPageView* widget, zathura_rectangle_t* rectangle);
static void redraw_all_rects(ZathuraPageView* widget, girara_list_t* rectangles); static void redraw_all_rects(ZathuraPageView* widget, girara_list_t* rectangles);
@ -35,6 +38,8 @@ enum properties_e
PROP_0, PROP_0,
PROP_PAGE, PROP_PAGE,
PROP_DRAW_LINKS, PROP_DRAW_LINKS,
PROP_LINKS_OFFSET,
PROP_LINKS_NUMBER,
PROP_SEARCH_RESULTS PROP_SEARCH_RESULTS
}; };
@ -52,12 +57,17 @@ zathura_page_view_class_init(ZathuraPageViewClass* class)
GObjectClass* object_class = G_OBJECT_CLASS(class); GObjectClass* object_class = G_OBJECT_CLASS(class);
object_class->finalize = zathura_page_view_finalize; object_class->finalize = zathura_page_view_finalize;
object_class->set_property = zathura_page_view_set_property; object_class->set_property = zathura_page_view_set_property;
object_class->get_property = zathura_page_view_get_property;
/* add properties */ /* add properties */
g_object_class_install_property(object_class, PROP_PAGE, 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_param_spec_pointer("page", "page", "the page to draw", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property(object_class, PROP_DRAW_LINKS, 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_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,
g_param_spec_int("offset-links", "offset-links", "Offset for the link numbers", 0, INT_MAX, 0, G_PARAM_WRITABLE));
g_object_class_install_property(object_class, PROP_LINKS_NUMBER,
g_param_spec_int("number-of-links", "number-of-links", "Number of links", 0, INT_MAX, 0, G_PARAM_READABLE));
g_object_class_install_property(object_class, PROP_SEARCH_RESULTS, g_object_class_install_property(object_class, PROP_SEARCH_RESULTS,
g_param_spec_pointer("search-results", "search-results", "Set to the list of search results", G_PARAM_WRITABLE)); g_param_spec_pointer("search-results", "search-results", "Set to the list of search results", G_PARAM_WRITABLE));
} }
@ -66,10 +76,11 @@ static void
zathura_page_view_init(ZathuraPageView* widget) zathura_page_view_init(ZathuraPageView* widget)
{ {
zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(widget); zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(widget);
priv->page = NULL; priv->page = NULL;
priv->surface = NULL; priv->surface = NULL;
priv->links = NULL; priv->links = NULL;
priv->links_got = false; priv->links_got = false;
priv->link_offset = 0;
g_static_mutex_init(&(priv->lock)); g_static_mutex_init(&(priv->lock));
/* we want mouse events */ /* we want mouse events */
@ -127,6 +138,9 @@ zathura_page_view_set_property(GObject* object, guint prop_id, const GValue* val
GIRARA_LIST_FOREACH_END(priv->links, zathura_link_t*, iter, link); GIRARA_LIST_FOREACH_END(priv->links, zathura_link_t*, iter, link);
} }
break; break;
case PROP_LINKS_OFFSET:
priv->link_offset = g_value_get_int(value);
break;
case PROP_SEARCH_RESULTS: case PROP_SEARCH_RESULTS:
if (priv->search_results != NULL) { if (priv->search_results != NULL) {
redraw_all_rects(pageview, priv->search_results); redraw_all_rects(pageview, priv->search_results);
@ -137,6 +151,20 @@ zathura_page_view_set_property(GObject* object, guint prop_id, const GValue* val
priv->draw_links = false; priv->draw_links = false;
redraw_all_rects(pageview, priv->search_results); redraw_all_rects(pageview, priv->search_results);
} }
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
}
}
static void
zathura_page_view_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
{
ZathuraPageView* pageview = ZATHURA_PAGE_VIEW(object);
zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(pageview);
switch (prop_id) {
case PROP_LINKS_NUMBER:
g_value_set_int(value, priv->number_of_links);
break; break;
default: default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
@ -202,13 +230,14 @@ zathura_page_view_expose(GtkWidget* widget, GdkEventExpose* event)
/* draw links */ /* draw links */
if (priv->draw_links == true) { if (priv->draw_links == true) {
unsigned int link_counter = 0;
GIRARA_LIST_FOREACH(priv->links, zathura_link_t*, iter, link) GIRARA_LIST_FOREACH(priv->links, zathura_link_t*, iter, link)
zathura_rectangle_t rectangle = recalc_rectangle(priv->page, link->position); zathura_rectangle_t rectangle = recalc_rectangle(priv->page, link->position);
/* draw text */ /* draw text */
cairo_set_font_size(cairo, 10); cairo_set_font_size(cairo, 10);
cairo_move_to(cairo, rectangle.x1 + 1, rectangle.y1 - 1); cairo_move_to(cairo, rectangle.x1 + 1, rectangle.y1 - 1);
char* link_number = g_strdup_printf("%i", 0); char* link_number = g_strdup_printf("%i", priv->link_offset + ++link_counter);
cairo_show_text(cairo, link_number); cairo_show_text(cairo, link_number);
g_free(link_number); g_free(link_number);
@ -324,5 +353,10 @@ zathura_page_view_link_get(ZathuraPageView* widget, unsigned int index)
zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(widget); zathura_page_view_private_t* priv = ZATHURA_PAGE_VIEW_GET_PRIVATE(widget);
g_return_val_if_fail(priv != NULL, NULL); g_return_val_if_fail(priv != NULL, NULL);
return girara_list_nth(priv->links, index); 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);
} else {
return NULL;
}
} }

View File

@ -122,6 +122,7 @@ sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
} }
/* set pages to draw links */ /* set pages to draw links */
unsigned int page_offset = 0;
for (unsigned int page_id = 0; page_id < zathura->document->number_of_pages; page_id++) { 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_t* page = zathura->document->pages[page_id];
if (page == NULL) { if (page == NULL) {
@ -129,14 +130,18 @@ sc_follow(girara_session_t* session, girara_argument_t* UNUSED(argument),
} }
if (page->visible == true) { if (page->visible == true) {
int number_of_links = 0;
g_object_get(page->drawing_area, "number-of-links", &number_of_links, NULL);
g_object_set(page->drawing_area, "draw-links", TRUE, NULL); g_object_set(page->drawing_area, "draw-links", TRUE, NULL);
g_object_set(page->drawing_area, "offset-links", page_offset, NULL);
page_offset += number_of_links;
} else { } else {
g_object_set(page->drawing_area, "draw-links", FALSE, NULL); g_object_set(page->drawing_area, "draw-links", FALSE, NULL);
} }
} }
/* ask for input */ /* ask for input */
girara_dialog(zathura->ui.session, "Follow link:", FALSE, NULL, NULL); girara_dialog(zathura->ui.session, "Follow link:", FALSE, NULL, (girara_callback_inputbar_activate_t) cb_sc_follow);
return false; return false;
} }