[poppler] [PATCH 6/6] Tagged-PDF: Pane in poppler-glib demo showing the structure
Adrian Perez
aperez at igalia.com
Wed May 29 16:47:31 PDT 2013
From: Adrian Perez de Castro <aperez at igalia.com>
Adds a new pane in poppler-glib-demo showing the structure for Tagged-PDF
documents. It also serves as an example on how to to use the API for
PopplerStructure and PopplerStructureElement.
---
glib/demo/Makefile.am | 2 +
glib/demo/main.c | 2 +
glib/demo/taggedstruct.c | 230 +++++++++++++++++++++++++++++++++++++++++++++++
glib/demo/taggedstruct.h | 31 +++++++
4 files changed, 265 insertions(+)
create mode 100644 glib/demo/taggedstruct.c
create mode 100644 glib/demo/taggedstruct.h
diff --git a/glib/demo/Makefile.am b/glib/demo/Makefile.am
index 28fc22d..6d9143a 100644
--- a/glib/demo/Makefile.am
+++ b/glib/demo/Makefile.am
@@ -43,6 +43,8 @@ poppler_glib_demo_SOURCES = \
selections.h \
selections.c \
text.h \
+ taggedstruct.h \
+ taggedstruct.c \
text.c \
transitions.h \
transitions.c \
diff --git a/glib/demo/main.c b/glib/demo/main.c
index 2523800..f07700e 100644
--- a/glib/demo/main.c
+++ b/glib/demo/main.c
@@ -34,6 +34,7 @@
#include "attachments.h"
#include "layers.h"
#include "text.h"
+#include "taggedstruct.h"
#include "find.h"
#include "print.h"
#include "selections.h"
@@ -65,6 +66,7 @@ static const PopplerGlibDemo demo_list[] = {
{ "Attachments", pgd_attachments_create_widget },
{ "Layers", pgd_layers_create_widget },
{ "Text", pgd_text_create_widget },
+ { "Tagged Structure", pgd_taggedstruct_create_widget },
{ "Find", pgd_find_create_widget },
{ "Print", pgd_print_create_widget }
};
diff --git a/glib/demo/taggedstruct.c b/glib/demo/taggedstruct.c
new file mode 100644
index 0000000..f40ae8d
--- /dev/null
+++ b/glib/demo/taggedstruct.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <string.h>
+
+#include "text.h"
+#include "utils.h"
+
+typedef struct {
+ PopplerStructure *structure;
+ GtkWidget *view;
+ GtkTreeStore *store;
+
+ GtkWidget *type_value;
+ GtkWidget *lang_value;
+ GtkTextBuffer *text_buffer;
+} PgdTaggedStructDemo;
+
+
+static void
+pgd_taggedstruct_free (PgdTaggedStructDemo *demo)
+{
+ if (!demo)
+ return;
+
+ if (demo->store) {
+ g_object_unref (demo->store);
+ demo->store = NULL;
+ }
+
+ if (demo->structure)
+ g_object_unref (demo->structure);
+
+ g_free (demo);
+}
+
+
+static void
+populate_store_aux (GtkTreeStore *store, GtkTreeIter *parent, PopplerStructureElement *element)
+{
+ GEnumClass *enum_class = G_ENUM_CLASS (g_type_class_ref (POPPLER_TYPE_STRUCTURE_ELEMENT_KIND));
+ GEnumValue *enum_value = g_enum_get_value (enum_class, poppler_structure_element_get_kind (element));
+ GtkTreeIter pos;
+ guint i;
+
+ gtk_tree_store_append (store, &pos, parent);
+ gtk_tree_store_set (store, &pos, 0, enum_value->value_nick, 1, element, -1);
+
+ for (i = 0; i < poppler_structure_element_get_n_children (element); i++)
+ populate_store_aux (store, &pos, poppler_structure_element_get_child (element, i));
+}
+
+
+static GtkTreeStore *
+populate_store (PopplerStructure *structure)
+{
+ guint i;
+ GtkTreeStore *store = gtk_tree_store_new (2, G_TYPE_STRING, G_TYPE_POINTER);
+
+ if (structure)
+ {
+ for (i = 0; i < poppler_structure_get_n_children (structure); i++)
+ {
+ PopplerStructureElement *element = poppler_structure_get_child (structure, i);
+ populate_store_aux (store, NULL, element);
+ }
+ }
+ else
+ {
+ GtkTreeIter pos;
+ gtk_tree_store_append (store, &pos, NULL);
+ gtk_tree_store_set (store, &pos, 0, "<b>Not a Tagged-PDF</b>", 1, NULL, -1);
+ }
+
+ return store;
+}
+
+
+static void
+pgd_row_activated (GtkTreeView *tree_view, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
+{
+ PgdTaggedStructDemo *demo = (PgdTaggedStructDemo*) user_data;
+ GtkTreeModel *model = gtk_tree_view_get_model (tree_view);
+ PopplerStructureElement *element;
+ GtkTreeIter iter;
+ gpointer elementptr;
+
+ if (!gtk_tree_model_get_iter (model, &iter, path))
+ return;
+
+ gtk_tree_model_get (model, &iter, 1, &elementptr, -1);
+ element = POPPLER_STRUCTURE_ELEMENT (elementptr);
+
+ gtk_label_set_text (GTK_LABEL (demo->lang_value),
+ poppler_structure_element_get_language (element, TRUE));
+
+ if (poppler_structure_element_is_content (element))
+ {
+ gtk_text_buffer_set_text (demo->text_buffer,
+ poppler_structure_element_get_text (element, FALSE),
+ -1);
+ gtk_label_set_text (GTK_LABEL (demo->type_value), "Content");
+ }
+ else
+ {
+ gtk_text_buffer_set_text (demo->text_buffer, "", -1);
+ if (poppler_structure_element_is_inline (element))
+ gtk_label_set_text (GTK_LABEL (demo->type_value), "Inline");
+ else if (poppler_structure_element_is_block (element))
+ gtk_label_set_text (GTK_LABEL (demo->type_value), "Block");
+ else
+ gtk_label_set_text (GTK_LABEL (demo->type_value), "Structure");
+ }
+}
+
+
+static void
+pgd_cursor_changed (GtkTreeView *tree_view, gpointer user_data)
+{
+ GtkTreePath *path;
+ gtk_tree_view_get_cursor (tree_view, &path, NULL);
+ if (path)
+ {
+ pgd_row_activated (tree_view, path, NULL, user_data);
+ gtk_tree_path_free (path);
+ }
+}
+
+
+GtkWidget *
+pgd_taggedstruct_create_widget (PopplerDocument *document)
+{
+ PgdTaggedStructDemo *demo;
+ GtkCellRenderer *renderer;
+ GtkWidget *hbox;
+ GtkWidget *vbox;
+ GtkWidget *grid;
+ GtkWidget *scroll;
+ GtkWidget *w;
+ gint row;
+
+ demo = g_new0 (PgdTaggedStructDemo, 1);
+ demo->structure = poppler_document_get_structure (document);
+ if (demo->structure)
+ g_object_ref (demo->structure);
+
+ demo->store = populate_store (demo->structure);
+ demo->view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (demo->store));
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (demo->view),
+ 0, "Type",
+ renderer,
+ "markup", 0,
+ NULL);
+ g_object_set (G_OBJECT (gtk_tree_view_get_column (GTK_TREE_VIEW (demo->view), 0)),
+ "expand", TRUE, NULL);
+
+ gtk_tree_view_expand_all (GTK_TREE_VIEW (demo->view));
+ gtk_tree_view_set_show_expanders (GTK_TREE_VIEW (demo->view), TRUE);
+ gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (demo->view), TRUE);
+ gtk_tree_view_set_headers_clickable (GTK_TREE_VIEW (demo->view), FALSE);
+ gtk_tree_view_set_activate_on_single_click (GTK_TREE_VIEW (demo->view), TRUE);
+
+ hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_add (GTK_CONTAINER (scroll), demo->view);
+ gtk_widget_show (demo->view);
+ gtk_box_pack_start (GTK_BOX (hbox), scroll, TRUE, TRUE, 0);
+ gtk_widget_show (scroll);
+
+ row = 0;
+ grid = gtk_grid_new ();
+ gtk_container_set_border_width (GTK_CONTAINER (grid), 12);
+ gtk_grid_set_row_homogeneous (GTK_GRID (grid), FALSE);
+ gtk_grid_set_column_spacing (GTK_GRID (grid), 6);
+ gtk_grid_set_row_spacing (GTK_GRID (grid), 6);
+ pgd_table_add_property_with_value_widget (GTK_GRID (grid), "<b>Type:</b>", &demo->type_value, NULL, &row);
+ pgd_table_add_property_with_value_widget (GTK_GRID (grid), "<b>Language:</b>", &demo->lang_value, NULL, &row);
+
+ vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
+ gtk_box_pack_start (GTK_BOX (vbox), grid, FALSE, FALSE, 0);
+ gtk_widget_show (grid);
+
+ scroll = gtk_scrolled_window_new (NULL, NULL);
+ gtk_container_set_border_width (GTK_CONTAINER (scroll), 12);
+ gtk_box_pack_end (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
+ gtk_widget_show (scroll);
+
+ gtk_container_add (GTK_CONTAINER (scroll), (w = gtk_text_view_new ()));
+ gtk_widget_show (w);
+
+ demo->text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (w));
+ gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW (w), GTK_WRAP_WORD_CHAR);
+ gtk_text_view_set_editable (GTK_TEXT_VIEW (w), FALSE);
+ gtk_text_buffer_set_text (demo->text_buffer, "", -1);
+ gtk_widget_show (w);
+
+ g_signal_connect (demo->view, "row-activated",
+ G_CALLBACK (pgd_row_activated),
+ demo);
+ g_signal_connect (demo->view, "cursor-changed",
+ G_CALLBACK (pgd_cursor_changed),
+ demo);
+
+ gtk_box_pack_end (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
+ gtk_widget_show (vbox);
+
+ g_object_weak_ref (G_OBJECT (hbox),
+ (GWeakNotify) pgd_taggedstruct_free,
+ demo);
+
+ gtk_widget_show (hbox);
+ return hbox;
+}
diff --git a/glib/demo/taggedstruct.h b/glib/demo/taggedstruct.h
new file mode 100644
index 0000000..3a38727
--- /dev/null
+++ b/glib/demo/taggedstruct.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2013 Igalia S.L.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include <gtk/gtk.h>
+#include <poppler.h>
+
+#ifndef _TAGGEDSTRUCT_H_
+#define _TAGGEDSTRUCT_H_
+
+G_BEGIN_DECLS
+
+GtkWidget *pgd_taggedstruct_create_widget (PopplerDocument *document);
+
+G_END_DECLS
+
+#endif /* _TAGGEDSTRUCT_H_ */
--
1.8.3
More information about the poppler
mailing list