/*
 * Copyright (C) 2008 Inigo Martinez <inigomartinez@gmail.com>
 *
 * 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 <string.h>

#include "annots.h"
#include "utils.h"

enum {
    ANNOTS_TYPE_COLUMN,
    ANNOTS_COLOR_COLUMN,
    ANNOTS_FLAG_INVISIBLE_COLUMN,
    ANNOTS_FLAG_HIDDEN_COLUMN,
    ANNOTS_FLAG_PRINT_COLUMN,
    ANNOTS_COLUMN,
    N_COLUMNS
};

enum {
    SELECTED_TYPE_COLUMN,
    SELECTED_LABEL_COLUMN,
    SELECTED_N_COLUMNS
};

typedef struct
{
  const guint  type;
  const gchar *label;
} Annotations;

static Annotations supported_annots[] = {
    { POPPLER_ANNOT_TEXT,       "Text" },
    { POPPLER_ANNOT_LINE,       "Line" },
    { POPPLER_ANNOT_SQUARE,     "Square" },
    { POPPLER_ANNOT_CIRCLE,     "Circle" },
    { POPPLER_ANNOT_HIGHLIGHT,  "Highlight" },
    { POPPLER_ANNOT_UNDERLINE,  "Underline" },
    { POPPLER_ANNOT_SQUIGGLY,   "Squiggly" },
    { POPPLER_ANNOT_STRIKE_OUT, "Strike Out" },
};

typedef enum {
    MODE_NORMAL,  /* Regular use as pointer in the page */
    MODE_ADD,     /* To add simple annotations */
    MODE_EDIT,    /* To move/edit an annotation */
    MODE_DRAWING  /* To add annotations that require mouse interactions */
} ModeType;

typedef struct {
    PopplerDocument *doc;
    PopplerPage     *page;
    PopplerAnnot    *active_annot;

    GtkWidget       *tree_view;
    GtkListStore    *model;
    GtkWidget       *darea;
    GtkWidget       *annot_view;
    GtkWidget       *timer_label;
    GtkWidget       *remove_button;
    GtkWidget       *type_selector;
    GtkWidget       *main_box;

    gint             num_page;
    gint             annot_type;
    ModeType         mode;

    cairo_surface_t *surface;
    GdkRGBA          annot_color;

    GdkPoint         start;
    GdkPoint         stop;
    GdkCursorType    cursor;
    guint            annotations_idle;
} PgdAnnotsDemo;

static void pgd_annots_viewer_queue_redraw (PgdAnnotsDemo *demo);

static void
pgd_annots_free (PgdAnnotsDemo *demo)
{
    if (!demo)
        return;

    if (demo->annotations_idle > 0) {
        g_source_remove (demo->annotations_idle);
        demo->annotations_idle = 0;
    }

    if (demo->doc) {
        g_object_unref (demo->doc);
        demo->doc = NULL;
    }

    if (demo->page) {
        g_object_unref (demo->page);
        demo->page = NULL;
    }

    if (demo->model) {
        g_object_unref (demo->model);
        demo->model = NULL;
    }

    g_free (demo);
}

static GtkWidget *
pgd_annot_view_new (void)
{
    GtkWidget  *frame, *label;

    frame = gtk_frame_new (NULL);
    gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
    label = gtk_label_new (NULL);
    gtk_label_set_markup (GTK_LABEL (label), "<b>Annotation Properties</b>");
    gtk_frame_set_label_widget (GTK_FRAME (frame), label);
    gtk_widget_show (label);

    return frame;
}

const gchar *
get_annot_type (PopplerAnnot *poppler_annot)
{
    switch (poppler_annot_get_annot_type (poppler_annot))
    {
      case POPPLER_ANNOT_TEXT:
        return "Text";
      case POPPLER_ANNOT_LINK:
        return "Link";
      case POPPLER_ANNOT_FREE_TEXT:
        return "Free Text";
      case POPPLER_ANNOT_LINE:
        return "Line";
      case POPPLER_ANNOT_SQUARE:
        return "Square";
      case POPPLER_ANNOT_CIRCLE:
        return "Circle";
      case POPPLER_ANNOT_POLYGON:
        return "Polygon";
      case POPPLER_ANNOT_POLY_LINE:
        return "Poly Line";
      case POPPLER_ANNOT_HIGHLIGHT:
        return "Highlight";
      case POPPLER_ANNOT_UNDERLINE:
        return "Underline";
      case POPPLER_ANNOT_SQUIGGLY:
        return "Squiggly";
      case POPPLER_ANNOT_STRIKE_OUT:
        return "Strike Out";
      case POPPLER_ANNOT_STAMP:
        return "Stamp";
      case POPPLER_ANNOT_CARET:
        return "Caret";
      case POPPLER_ANNOT_INK:
        return "Ink";
      case POPPLER_ANNOT_POPUP:
        return "Popup";
      case POPPLER_ANNOT_FILE_ATTACHMENT:
        return "File Attachment";
      case POPPLER_ANNOT_SOUND:
        return "Sound";
      case POPPLER_ANNOT_MOVIE:
        return "Movie";
      case POPPLER_ANNOT_WIDGET:
        return "Widget";
      case POPPLER_ANNOT_SCREEN:
        return "Screen";
      case POPPLER_ANNOT_PRINTER_MARK:
        return "Printer Mark";
      case POPPLER_ANNOT_TRAP_NET:
        return "Trap Net";
      case POPPLER_ANNOT_WATERMARK:
        return "Watermark";
      case POPPLER_ANNOT_3D:
        return "3D";
      default:
        break;
  }

  return "Unknown";
}

GdkPixbuf *
get_annot_color (PopplerAnnot *poppler_annot)
{
    PopplerColor *poppler_color;

    if ((poppler_color = poppler_annot_get_color (poppler_annot))) {
        GdkPixbuf *pixbuf_tmp, *pixbuf;

        pixbuf_tmp = pgd_pixbuf_new_for_color (poppler_color);
        pixbuf = gdk_pixbuf_scale_simple(pixbuf_tmp, 16, 16, GDK_INTERP_BILINEAR);
        g_object_unref (pixbuf_tmp);

        g_free (poppler_color);

        return pixbuf;
    }

    return NULL;
}

gchar *
get_markup_date (PopplerAnnotMarkup *poppler_annot)
{
    GDate *date;
    struct tm t;
    time_t timet;

    date = poppler_annot_markup_get_date (poppler_annot);
    if (!date)
	    return NULL;

    g_date_to_struct_tm (date, &t);
    g_date_free (date);

    timet = mktime (&t);
    return timet == (time_t) - 1 ? NULL : pgd_format_date (timet);
}

const gchar *
get_markup_reply_to (PopplerAnnotMarkup *poppler_annot)
{
    switch (poppler_annot_markup_get_reply_to (poppler_annot))
    {
      case POPPLER_ANNOT_MARKUP_REPLY_TYPE_R:
        return "Type R";
      case POPPLER_ANNOT_MARKUP_REPLY_TYPE_GROUP:
        return "Type Group";
      default:
        break;
    }

  return "Unknown";
}

const gchar *
get_markup_external_data (PopplerAnnotMarkup *poppler_annot)
{
    switch (poppler_annot_markup_get_external_data (poppler_annot))
    {
      case POPPLER_ANNOT_EXTERNAL_DATA_MARKUP_3D:
        return "Markup 3D";
      default:
        break;
    }

  return "Unknown";
}

const gchar *
get_text_state (PopplerAnnotText *poppler_annot)
{
    switch (poppler_annot_text_get_state (poppler_annot))
    {
      case POPPLER_ANNOT_TEXT_STATE_MARKED:
        return "Marked";
      case POPPLER_ANNOT_TEXT_STATE_UNMARKED:
        return "Unmarked";
      case POPPLER_ANNOT_TEXT_STATE_ACCEPTED:
        return "Accepted";
      case POPPLER_ANNOT_TEXT_STATE_REJECTED:
        return "Rejected";
      case POPPLER_ANNOT_TEXT_STATE_CANCELLED:
        return "Cancelled";
      case POPPLER_ANNOT_TEXT_STATE_COMPLETED:
        return "Completed";
      case POPPLER_ANNOT_TEXT_STATE_NONE:
        return "None";
      case POPPLER_ANNOT_TEXT_STATE_UNKNOWN:
        return "Unknown";
      default:
        break;
    }

  return "Unknown";
}

const gchar *
get_free_text_quadding (PopplerAnnotFreeText *poppler_annot)
{
    switch (poppler_annot_free_text_get_quadding (poppler_annot))
    {
      case POPPLER_ANNOT_FREE_TEXT_QUADDING_LEFT_JUSTIFIED:
        return "Left Justified";
      case POPPLER_ANNOT_FREE_TEXT_QUADDING_CENTERED:
        return "Centered";
      case POPPLER_ANNOT_FREE_TEXT_QUADDING_RIGHT_JUSTIFIED:
        return "Right Justified";
      default:
        break;
    }

  return "Unknown";
}

gchar *
get_free_text_callout_line (PopplerAnnotFreeText *poppler_annot)
{
    PopplerAnnotCalloutLine *callout;
    gchar *text;
    
    if ((callout = poppler_annot_free_text_get_callout_line (poppler_annot))) {
        text = g_strdup_printf ("%f,%f,%f,%f", callout->x1,
                                               callout->y1,
                                               callout->x2,
                                               callout->y2);
        if (callout->multiline)
            text = g_strdup_printf ("%s,%f,%f", text,
                                                callout->x3,
                                                callout->y3);

        return text;
    }
    
    return NULL;
}

static void
pgd_annots_update_cursor (PgdAnnotsDemo *demo,
                          GdkCursorType  cursor_type)
{
    GdkCursor *cursor = NULL;

    if (cursor_type == demo->cursor)
        return;

    if (cursor_type != GDK_LAST_CURSOR) {
        cursor = gdk_cursor_new_for_display (gtk_widget_get_display (demo->main_box),
                                             cursor_type);
     }

     demo->cursor = cursor_type;

     gdk_window_set_cursor (gtk_widget_get_window (demo->main_box), cursor);
     gdk_display_flush (gtk_widget_get_display (demo->main_box));
     if (cursor)
         g_object_unref (cursor);
}

static void
pgd_annots_start_add_annot (GtkWidget     *button,
                            PgdAnnotsDemo *demo)
{
    GtkTreeModel *model;
    GtkTreeIter   iter;

    gtk_combo_box_get_active_iter (GTK_COMBO_BOX (demo->type_selector), &iter);
    model = gtk_combo_box_get_model (GTK_COMBO_BOX (demo->type_selector));
    gtk_tree_model_get (model, &iter,
                        SELECTED_TYPE_COLUMN, &(demo->annot_type),
                        -1);

    demo->mode = MODE_ADD;
    pgd_annots_update_cursor (demo, GDK_TCROSS);
}

static void
pgd_annots_remove_annot (GtkWidget     *button,
                         PgdAnnotsDemo *demo)
{
    GtkTreeSelection *selection;
    GtkTreeModel *model;
    GtkTreeIter   iter;

    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (demo->tree_view));

    if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
        PopplerAnnot *annot;

        gtk_tree_model_get (model, &iter,
                            ANNOTS_COLUMN, &annot,
                           -1);
        poppler_page_remove_annot (demo->page, annot);
        g_object_unref (annot);
        gtk_list_store_remove (GTK_LIST_STORE (model), &iter);

        pgd_annots_viewer_queue_redraw (demo);
    }
}

static void
pgd_annot_view_set_annot_markup (GtkWidget          *table,
                                 PopplerAnnotMarkup *markup,
                                 gint               *row)
{
    gchar *text;
    PopplerRectangle rect;

    text = poppler_annot_markup_get_label (markup);
    pgd_table_add_property (GTK_GRID (table), "<b>Label:</b>", text, row);
    g_free (text);

    if (poppler_annot_markup_has_popup (markup)) {
	    pgd_table_add_property (GTK_GRID (table), "<b>Popup is open:</b>",
				    poppler_annot_markup_get_popup_is_open (markup) ? "Yes" : "No", row);

	    poppler_annot_markup_get_popup_rectangle (markup, &rect);
	    text = g_strdup_printf ("X1: %.2f, Y1: %.2f, X2: %.2f, Y2: %.2f",
				    rect.x1, rect.y1, rect.x2, rect.y2);
	    pgd_table_add_property (GTK_GRID (table), "<b>Popup Rectangle:</b>", text, row);
	    g_free (text);
    }

    text = g_strdup_printf ("%f", poppler_annot_markup_get_opacity (markup));
    pgd_table_add_property (GTK_GRID (table), "<b>Opacity:</b>", text, row);
    g_free (text);

    text = get_markup_date (markup);
    pgd_table_add_property (GTK_GRID (table), "<b>Date:</b>", text, row);
    g_free (text);

    text = poppler_annot_markup_get_subject (markup);
    pgd_table_add_property (GTK_GRID (table), "<b>Subject:</b>", text, row);
    g_free (text);

    pgd_table_add_property (GTK_GRID (table), "<b>Reply To:</b>", get_markup_reply_to (markup), row);

    pgd_table_add_property (GTK_GRID (table), "<b>External Data:</b>", get_markup_external_data (markup), row);
}

static void
pgd_annot_view_set_annot_text (GtkWidget        *table,
                               PopplerAnnotText *annot,
                               gint             *row)
{
    gchar *text;

    pgd_table_add_property (GTK_GRID (table), "<b>Is open:</b>",
                            poppler_annot_text_get_is_open (annot) ? "Yes" : "No", row);

    text = poppler_annot_text_get_icon (annot);
    pgd_table_add_property (GTK_GRID (table), "<b>Icon:</b>", text, row);
    g_free (text);

    pgd_table_add_property (GTK_GRID (table), "<b>State:</b>", get_text_state (annot), row);
}

static void
pgd_annot_color_changed (GtkButton     *button,
                         GParamSpec    *pspec,
                         PgdAnnotsDemo *demo)
{
    gtk_color_chooser_get_rgba (GTK_COLOR_CHOOSER (button), &demo->annot_color);
}

static void
pgd_annot_view_set_annot_text_markup (GtkWidget              *table,
                                      PopplerAnnotTextMarkup *annot,
                                      gint                   *row)
{
    gint                  i;
    gchar                *text = NULL;
    gchar                *prev_text = NULL;
    GArray               *quads_array = NULL;
    PopplerQuadrilateral  quadrilateral;

    quads_array = poppler_annot_text_markup_get_quadrilaterals (annot);

    prev_text = g_strdup ("");
    for (i = 0; i < quads_array->len; i++) {
        quadrilateral = g_array_index (quads_array, PopplerQuadrilateral, i);

        text = g_strdup_printf ("%s%2d:(%.2f,%.2f) (%.2f,%.2f)\n"
                                "    (%.2f,%.2f) (%.2f,%.2f)\n",
                                prev_text, i+1,
                                quadrilateral.p1.x, quadrilateral.p1.y,
                                quadrilateral.p2.x, quadrilateral.p2.y,
                                quadrilateral.p3.x, quadrilateral.p3.y,
                                quadrilateral.p4.x, quadrilateral.p4.y);
        g_free (prev_text);
        prev_text = text;
    }

    text = g_strchomp (text);
    pgd_table_add_property (GTK_GRID (table), "<b>Quadrilaterals:</b>", text, row);

    g_array_free (quads_array, TRUE);
    g_free (text);
}


static void
pgd_annot_view_set_annot_free_text (GtkWidget            *table,
                                    PopplerAnnotFreeText *annot,
                                    gint                 *row)
{
    gchar *text;

    pgd_table_add_property (GTK_GRID (table), "<b>Quadding:</b>", get_free_text_quadding (annot), row);

    text = get_free_text_callout_line (annot);
    pgd_table_add_property (GTK_GRID (table), "<b>Callout:</b>", text, row);
    g_free (text);
}

static void
pgd_annots_file_attachment_save_dialog_response (GtkFileChooser    *file_chooser,
						 gint               response,
						 PopplerAttachment *attachment)
{
    gchar  *filename;
    GError *error = NULL;

    if (response != GTK_RESPONSE_ACCEPT) {
        g_object_unref (attachment);
	gtk_widget_destroy (GTK_WIDGET (file_chooser));
	return;
    }

    filename = gtk_file_chooser_get_filename (file_chooser);
    if (!poppler_attachment_save (attachment, filename, &error)) {
        g_warning ("%s", error->message);
	g_error_free (error);
    }
    g_free (filename);
    g_object_unref (attachment);
    gtk_widget_destroy (GTK_WIDGET (file_chooser));
}

static void
pgd_annot_save_file_attachment_button_clicked (GtkButton                  *button,
					       PopplerAnnotFileAttachment *annot)
{
    GtkWidget         *file_chooser;
    PopplerAttachment *attachment;

    attachment = poppler_annot_file_attachment_get_attachment (annot);
    if (!attachment)
        return;

    file_chooser = gtk_file_chooser_dialog_new ("Save attachment",
						GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (button))),
						GTK_FILE_CHOOSER_ACTION_SAVE,
						"_Cancel", GTK_RESPONSE_CANCEL,
						"_Save", GTK_RESPONSE_ACCEPT,
						NULL);
    gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (file_chooser), attachment->name);
    g_signal_connect (G_OBJECT (file_chooser), "response",
		      G_CALLBACK (pgd_annots_file_attachment_save_dialog_response),
		      (gpointer) attachment);
    gtk_widget_show (file_chooser);
}

static void
pgd_annot_view_set_annot_file_attachment (GtkWidget                  *table,
					  PopplerAnnotFileAttachment *annot,
					  gint                       *row)
{
    GtkWidget *button;
    gchar *text;

    text = poppler_annot_file_attachment_get_name (annot);
    pgd_table_add_property (GTK_GRID (table), "<b>Attachment Name:</b>", text, row);
    g_free (text);

    button = gtk_button_new_with_label ("Save Attachment");
    g_signal_connect (G_OBJECT (button), "clicked",
		      G_CALLBACK (pgd_annot_save_file_attachment_button_clicked),
		      (gpointer)annot);
    pgd_table_add_property_with_custom_widget (GTK_GRID (table), "<b>File Attachment:</b>", button, row);
    gtk_widget_show (button);

}

static void
pgd_annot_view_set_annot_movie (GtkWidget         *table,
				PopplerAnnotMovie *annot,
				gint              *row)
{
    GtkWidget *movie_view;
    gchar *text;

    text = poppler_annot_movie_get_title (annot);
    pgd_table_add_property (GTK_GRID (table), "<b>Movie Title:</b>", text, row);
    g_free (text);

    movie_view = pgd_movie_view_new ();
    pgd_movie_view_set_movie (movie_view, poppler_annot_movie_get_movie (annot));
    pgd_table_add_property_with_custom_widget (GTK_GRID (table), "<b>Movie:</b>", movie_view, row);
    gtk_widget_show (movie_view);
}

static void
pgd_annot_view_set_annot_screen (GtkWidget          *table,
				 PopplerAnnotScreen *annot,
				 gint               *row)
{
    GtkWidget *action_view;

    action_view = pgd_action_view_new (NULL);
    pgd_action_view_set_action (action_view, poppler_annot_screen_get_action (annot));
    pgd_table_add_property_with_custom_widget (GTK_GRID (table), "<b>Action:</b>", action_view, row);
    gtk_widget_show (action_view);
}

static void
pgd_annot_view_set_annot (PgdAnnotsDemo *demo,
                          PopplerAnnot  *annot)
{
    GtkWidget  *table;
    gint        row = 0;
    gchar      *text;
    time_t      timet;
    PopplerRectangle rect;

    table = gtk_bin_get_child (GTK_BIN (demo->annot_view));
    if (table) {
        gtk_container_remove (GTK_CONTAINER (demo->annot_view), table);
    }

    if (!annot)
        return;

    table = gtk_grid_new ();
    gtk_widget_set_margin_top (table, 5);
    gtk_widget_set_margin_bottom (table, 5);
#if GTK_CHECK_VERSION(3, 12, 0)
    gtk_widget_set_margin_start (table, 8);
    gtk_widget_set_margin_end (table, 5);
#else
    gtk_widget_set_margin_left (table, 8);
    gtk_widget_set_margin_right (table, 5);
#endif
    gtk_grid_set_column_spacing (GTK_GRID (table), 6);
    gtk_grid_set_row_spacing (GTK_GRID (table), 6);

    text = poppler_annot_get_contents (annot);
    pgd_table_add_property (GTK_GRID (table), "<b>Contents:</b>", text, &row);
    g_free (text);

    text = poppler_annot_get_name (annot);
    pgd_table_add_property (GTK_GRID (table), "<b>Name:</b>", text, &row);
    g_free (text);

    text = poppler_annot_get_modified (annot);
    if (poppler_date_parse (text, &timet)) {
	    g_free (text);
	    text = pgd_format_date (timet);
    }
    pgd_table_add_property (GTK_GRID (table), "<b>Modified:</b>", text, &row);
    g_free (text);

    poppler_annot_get_rectangle (annot, &rect);
    text = g_strdup_printf ("(%.2f;%.2f) (%.2f;%.2f)", rect.x1, rect.y1, rect.x2, rect.y2);
    pgd_table_add_property (GTK_GRID (table), "<b>Coords:</b>", text, &row);
    g_free (text);

    if (POPPLER_IS_ANNOT_MARKUP (annot))
        pgd_annot_view_set_annot_markup (table, POPPLER_ANNOT_MARKUP (annot), &row);

    switch (poppler_annot_get_annot_type (annot))
    {
        case POPPLER_ANNOT_TEXT:
          pgd_annot_view_set_annot_text (table, POPPLER_ANNOT_TEXT (annot), &row);
          break;
        case POPPLER_ANNOT_HIGHLIGHT:
        case POPPLER_ANNOT_UNDERLINE:
        case POPPLER_ANNOT_SQUIGGLY:
        case POPPLER_ANNOT_STRIKE_OUT:
          pgd_annot_view_set_annot_text_markup (table, POPPLER_ANNOT_TEXT_MARKUP (annot), &row);
          break;
        case POPPLER_ANNOT_FREE_TEXT:
          pgd_annot_view_set_annot_free_text (table, POPPLER_ANNOT_FREE_TEXT (annot), &row);
          break;
        case POPPLER_ANNOT_FILE_ATTACHMENT:
	  pgd_annot_view_set_annot_file_attachment (table, POPPLER_ANNOT_FILE_ATTACHMENT (annot), &row);
	  break;
        case POPPLER_ANNOT_MOVIE:
	  pgd_annot_view_set_annot_movie (table, POPPLER_ANNOT_MOVIE (annot), &row);
	  break;
        case POPPLER_ANNOT_SCREEN:
	  pgd_annot_view_set_annot_screen (table, POPPLER_ANNOT_SCREEN (annot), &row);
	  break;
        default:
          break;
    }

    gtk_container_add (GTK_CONTAINER (demo->annot_view), table);
    gtk_widget_show (table);
}

static void
pgd_annots_add_annot_to_model (PgdAnnotsDemo *demo,
                               PopplerAnnot *annot,
                               PopplerRectangle area,
                               gboolean selected)
{
    GtkTreeIter      iter;
    GdkPixbuf        *pixbuf;
    PopplerAnnotFlag  flags;

    pixbuf = get_annot_color (annot);
    flags = poppler_annot_get_flags (annot);

    gtk_list_store_append (demo->model, &iter);
    gtk_list_store_set (demo->model, &iter,
                        ANNOTS_TYPE_COLUMN, get_annot_type (annot),
                        ANNOTS_COLOR_COLUMN, pixbuf,
                        ANNOTS_FLAG_INVISIBLE_COLUMN, (flags & POPPLER_ANNOT_FLAG_INVISIBLE),
                        ANNOTS_FLAG_HIDDEN_COLUMN, (flags & POPPLER_ANNOT_FLAG_HIDDEN),
                        ANNOTS_FLAG_PRINT_COLUMN, (flags & POPPLER_ANNOT_FLAG_PRINT),
                        ANNOTS_COLUMN, annot,
                        -1);

    if (selected) {
        GtkTreePath *path;

        path = gtk_tree_model_get_path (GTK_TREE_MODEL (demo->model), &iter);
        gtk_tree_view_set_cursor (GTK_TREE_VIEW (demo->tree_view), path, NULL, FALSE);
        gtk_tree_path_free (path);
    }

    if (pixbuf)
        g_object_unref (pixbuf);
}

static void
pgd_annots_get_annots (PgdAnnotsDemo *demo)
{
    GList       *mapping, *l;
    gint         n_fields;
    GTimer      *timer;

    gtk_list_store_clear (demo->model);
    pgd_annot_view_set_annot (demo, NULL);

    if (demo->page) {
        g_object_unref (demo->page);
        demo->page = NULL;
    }

    demo->page = poppler_document_get_page (demo->doc, demo->num_page);
    if (!demo->page)
        return;

    timer = g_timer_new ();
    mapping = poppler_page_get_annot_mapping (demo->page);
    g_timer_stop (timer);

    n_fields = g_list_length (mapping);
    if (n_fields > 0) {
        gchar *str;

        str = g_strdup_printf ("<i>%d annotations found in %.4f seconds</i>",
                               n_fields, g_timer_elapsed (timer, NULL));
        gtk_label_set_markup (GTK_LABEL (demo->timer_label), str);
        g_free (str);
    } else {
        gtk_label_set_markup (GTK_LABEL (demo->timer_label), "<i>No annotations found</i>");
    }

    g_timer_destroy (timer);

    for (l = mapping; l; l = g_list_next (l)) {
        PopplerAnnotMapping *amapping;

        amapping = (PopplerAnnotMapping *) l->data;
        pgd_annots_add_annot_to_model (demo, amapping->annot,
                                       amapping->area, FALSE);
    }

    poppler_page_free_annot_mapping (mapping);
}

static void
pgd_annots_page_selector_value_changed (GtkSpinButton *spinbutton,
                                        PgdAnnotsDemo *demo)
{
    demo->num_page = (gint) gtk_spin_button_get_value (spinbutton) - 1;
    pgd_annots_viewer_queue_redraw (demo);
    pgd_annots_get_annots (demo);
}

static void
pgd_annots_selection_changed (GtkTreeSelection *treeselection,
                              PgdAnnotsDemo    *demo)
{
    GtkTreeModel *model;
    GtkTreeIter   iter;

    if (gtk_tree_selection_get_selected (treeselection, &model, &iter)) {
        PopplerAnnot *annot;

        gtk_tree_model_get (model, &iter,
                            ANNOTS_COLUMN, &annot,
                           -1);
        pgd_annot_view_set_annot (demo, annot);
        g_object_unref (annot);

        gtk_widget_set_sensitive (demo->remove_button, TRUE);
    } else {
        pgd_annot_view_set_annot (demo, NULL);
        gtk_widget_set_sensitive (demo->remove_button, FALSE);
    }
}

static void
pgd_annots_flags_toggled (GtkCellRendererToggle *renderer,
			  gchar *path_str,
			  PgdAnnotsDemo *demo,
			  gint column,
			  PopplerAnnotFlag flag_bit)
{
    GtkTreeIter  iter;
    gboolean fixed;
    PopplerAnnot *annot;
    PopplerAnnotFlag flags;
    GtkTreePath *path = gtk_tree_path_new_from_string (path_str);
    GtkTreeModel *model =  GTK_TREE_MODEL (demo->model);

    gtk_tree_model_get_iter (model, &iter, path);
    gtk_tree_model_get (model, &iter, column, &fixed, ANNOTS_COLUMN, &annot,-1);

    fixed ^= 1;
    flags = poppler_annot_get_flags (annot);

    if (fixed)
        flags |= flag_bit;
    else
        flags &= ~flag_bit;

    poppler_annot_set_flags (annot, flags);
    gtk_list_store_set (GTK_LIST_STORE (model), &iter, column, fixed, -1);

    pgd_annot_view_set_annot (demo, annot);
    gtk_tree_path_free (path);

    pgd_annots_viewer_queue_redraw (demo);
}

static void
pgd_annots_hidden_flag_toggled (GtkCellRendererToggle *renderer,
				gchar *path_str,
				PgdAnnotsDemo *demo)
{
    pgd_annots_flags_toggled (renderer, path_str, demo, ANNOTS_FLAG_HIDDEN_COLUMN, POPPLER_ANNOT_FLAG_HIDDEN);
}

static void
pgd_annots_print_flag_toggled (GtkCellRendererToggle *renderer,
                               gchar *path_str,
                               PgdAnnotsDemo *demo)
{
    pgd_annots_flags_toggled (renderer, path_str, demo, ANNOTS_FLAG_PRINT_COLUMN, POPPLER_ANNOT_FLAG_PRINT);
}

static void
pgd_annots_invisible_flag_toggled (GtkCellRendererToggle *renderer,
                                   gchar *path_str,
                                   PgdAnnotsDemo *demo)
{
    pgd_annots_flags_toggled (renderer, path_str, demo, ANNOTS_FLAG_INVISIBLE_COLUMN, POPPLER_ANNOT_FLAG_INVISIBLE);
}

static inline void
pgd_annots_set_poppler_quad_from_rectangle (PopplerQuadrilateral *quad,
                                            PopplerRectangle     *rect)
{
    quad->p1.x = rect->x1;
    quad->p1.y = rect->y1;
    quad->p2.x = rect->x2;
    quad->p2.y = rect->y1;
    quad->p3.x = rect->x1;
    quad->p3.y = rect->y2;
    quad->p4.x = rect->x2;
    quad->p4.y = rect->y2;
}

static GArray *
pgd_annots_create_quads_array_for_rectangle (PopplerRectangle *rect)
{
    GArray               *quads_array;
    PopplerQuadrilateral *quad;

    quads_array = g_array_sized_new (FALSE, FALSE,
                                     sizeof (PopplerQuadrilateral),
                                     1);
    g_array_set_size (quads_array, 1);

    quad = &g_array_index (quads_array, PopplerQuadrilateral, 0);
    pgd_annots_set_poppler_quad_from_rectangle (quad, rect);

    return quads_array;
}

static void
pgd_annots_add_annot (PgdAnnotsDemo *demo)
{
    PopplerRectangle rect;
    PopplerColor     color;
    PopplerAnnot    *annot;
    gdouble          height;

    g_assert (demo->mode == MODE_ADD);

    poppler_page_get_size (demo->page, NULL, &height);

    rect.x1 = demo->start.x;
    rect.y1 = height - demo->start.y;
    rect.x2 = demo->stop.x;
    rect.y2 = height - demo->stop.y;

    color.red = CLAMP ((guint) (demo->annot_color.red * 65535), 0, 65535);
    color.green = CLAMP ((guint) (demo->annot_color.green * 65535), 0, 65535);
    color.blue = CLAMP ((guint) (demo->annot_color.blue * 65535), 0, 65535);

    switch (demo->annot_type) {
        case POPPLER_ANNOT_TEXT:
            annot = poppler_annot_text_new (demo->doc, &rect);

            break;
        case POPPLER_ANNOT_LINE: {
            PopplerPoint start, end;

            start.x = rect.x1;
            start.y = rect.y1;
            end.x = rect.x2;
            end.y = rect.y2;

            annot = poppler_annot_line_new (demo->doc, &rect, &start, &end);
        }
            break;
        case POPPLER_ANNOT_SQUARE:
            annot = poppler_annot_square_new (demo->doc, &rect);
            break;
        case POPPLER_ANNOT_CIRCLE:
            annot = poppler_annot_circle_new (demo->doc, &rect);
            break;
        case POPPLER_ANNOT_HIGHLIGHT: {
            GArray *quads_array;

            quads_array = pgd_annots_create_quads_array_for_rectangle (&rect);
            annot = poppler_annot_text_markup_new_highlight (demo->doc, &rect, quads_array);
            g_array_free (quads_array, TRUE);
        }
            break;
        case POPPLER_ANNOT_UNDERLINE: {
            GArray *quads_array;

            quads_array = pgd_annots_create_quads_array_for_rectangle (&rect);
            annot = poppler_annot_text_markup_new_underline (demo->doc, &rect, quads_array);
            g_array_free (quads_array, TRUE);
        }
            break;
        case POPPLER_ANNOT_SQUIGGLY: {
            GArray *quads_array;

            quads_array = pgd_annots_create_quads_array_for_rectangle (&rect);
            annot = poppler_annot_text_markup_new_squiggly (demo->doc, &rect, quads_array);
            g_array_free (quads_array, TRUE);
        }
            break;
        case POPPLER_ANNOT_STRIKE_OUT: {
            GArray *quads_array;

            quads_array = pgd_annots_create_quads_array_for_rectangle (&rect);
            annot = poppler_annot_text_markup_new_strikeout (demo->doc, &rect, quads_array);
            g_array_free (quads_array, TRUE);
        }
            break;
        default:
            g_assert_not_reached ();
    }

    demo->active_annot = annot;

    poppler_annot_set_color (annot, &color);
    poppler_page_add_annot (demo->page, annot);
    pgd_annots_add_annot_to_model (demo, annot, rect, TRUE);
    g_object_unref (annot);
}

static void
pgd_annots_finish_add_annot (PgdAnnotsDemo *demo)
{
    g_assert (demo->mode == MODE_ADD || demo->mode == MODE_DRAWING);

    demo->mode = MODE_NORMAL;
    demo->start.x = -1;
    pgd_annots_update_cursor (demo, GDK_LAST_CURSOR);
    pgd_annots_viewer_queue_redraw (demo);

    gtk_label_set_text (GTK_LABEL (demo->timer_label), NULL);
}

static void
pgd_annots_update_selected_text (PgdAnnotsDemo *demo)
{
    PopplerRectangle      doc_area, *rects = NULL, *r = NULL;
    gdouble               width, height;
    GArray               *quads_array = NULL;
    guint                 n_rects;
    gint                  i, lines = 0;
    GList                 *l_rects = NULL, *list;

    poppler_page_get_size (demo->page, &width, &height);

    doc_area.x1 = demo->start.x;
    doc_area.y1 = demo->start.y;
    doc_area.x2 = demo->stop.x;
    doc_area.y2 = demo->stop.y;

    if (! poppler_page_get_text_layout_for_area (demo->page, &doc_area,
                                                 &rects, &n_rects))
        return;

    r = g_slice_new (PopplerRectangle);
    r->x1 = G_MAXDOUBLE; r->y1 = G_MAXDOUBLE;
    r->x2 = G_MINDOUBLE; r->y2 = G_MINDOUBLE;

    for (i = 0; i < n_rects; i++) {
        /* Check if the rectangle belongs to the same line.
           On a new line, start a new target rectangle.
           On the same line, make an union of rectangles at
           the same line */
        if (ABS(r->y2 - rects[i].y2) > 0.0001) {
            if (i > 0)
                l_rects = g_list_append (l_rects, r);
            r = g_slice_new (PopplerRectangle);
            r->x1 = rects[i].x1;
            r->y1 = rects[i].y1;
            r->x2 = rects[i].x2;
            r->y2 = rects[i].y2;
            lines++;
        } else {
            r->x1 = MIN(r->x1, rects[i].x1);
            r->y1 = MIN(r->y1, rects[i].y1);
            r->x2 = MAX(r->x2, rects[i].x2);
            r->y2 = MAX(r->y2, rects[i].y2);
        }
    }

    l_rects = g_list_append (l_rects, r);
    l_rects = g_list_reverse (l_rects);

    quads_array = g_array_sized_new (TRUE, TRUE,
                                     sizeof (PopplerQuadrilateral),
                                     lines);
    g_array_set_size (quads_array, lines);

    for (list = l_rects, i = 0; list; list = list->next, i++) {
        PopplerQuadrilateral *quad;

        quad = &g_array_index (quads_array, PopplerQuadrilateral, i);
        r = (PopplerRectangle *)list->data;
        quad->p1.x = r->x1;
        quad->p1.y = height - r->y1;
        quad->p2.x = r->x2;
        quad->p2.y = height - r->y1;
        quad->p3.x = r->x1;
        quad->p3.y = height - r->y2;
        quad->p4.x = r->x2;
        quad->p4.y = height - r->y2;
        g_slice_free (PopplerRectangle, r);
    }

    poppler_annot_text_markup_set_quadrilaterals (POPPLER_ANNOT_TEXT_MARKUP (demo->active_annot), quads_array);
    g_array_free (quads_array, TRUE);
    g_free (rects);
    g_list_free (l_rects);
}

/* Render area */
static cairo_surface_t *
pgd_annots_render_page (PgdAnnotsDemo *demo)
{
    cairo_t *cr;
    PopplerPage *page;
    gdouble width, height;
    cairo_surface_t *surface = NULL;

    page = poppler_document_get_page (demo->doc, demo->num_page);
    if (!page)
        return NULL;

    poppler_page_get_size (page, &width, &height);
    gtk_widget_set_size_request (demo->darea, width, height);

    surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
                                          width, height);
    cr = cairo_create (surface);

    cairo_save (cr);
    cairo_set_source_rgb (cr, 1, 1, 1);
    cairo_rectangle (cr, 0, 0, width, height);
    cairo_fill (cr);
    cairo_restore (cr);

    cairo_save (cr);
    poppler_page_render (page, cr);
    cairo_restore (cr);

    cairo_destroy (cr);
    g_object_unref (page);

    return surface;
}

static gboolean
pgd_annots_view_drawing_area_draw (GtkWidget   *area,
                                   cairo_t     *cr,
                                   PgdAnnotsDemo *demo)
{
    if (demo->num_page == -1)
        return FALSE;

    if (!demo->surface) {
        demo->surface = pgd_annots_render_page (demo);
        if (!demo->surface)
            return FALSE;
    }

    cairo_set_source_surface (cr, demo->surface, 0, 0);
    cairo_paint (cr);

    return TRUE;
}

static gboolean
pgd_annots_viewer_redraw (PgdAnnotsDemo *demo)
{
    cairo_surface_destroy (demo->surface);
    demo->surface = NULL;

    gtk_widget_queue_draw (demo->darea);

    demo->annotations_idle = 0;

    return FALSE;
}

static void
pgd_annots_viewer_queue_redraw (PgdAnnotsDemo *demo)
{
    if (demo->annotations_idle == 0)
        demo->annotations_idle = g_idle_add ((GSourceFunc)pgd_annots_viewer_redraw,
                                             demo);
}

static void
pgd_annots_drawing_area_realize (GtkWidget     *area,
                                 PgdAnnotsDemo *demo)
{
    gtk_widget_add_events (area,
                           GDK_POINTER_MOTION_HINT_MASK |
                           GDK_BUTTON1_MOTION_MASK |
                           GDK_BUTTON_PRESS_MASK |
                           GDK_BUTTON_RELEASE_MASK);
}

static gboolean
pgd_annots_drawing_area_button_press (GtkWidget      *area,
                                      GdkEventButton *event,
                                      PgdAnnotsDemo  *demo)
{
    if (!demo->page || demo->mode != MODE_ADD || event->button != 1)
        return FALSE;

    demo->start.x = event->x;
    demo->start.y = event->y;
    demo->stop = demo->start;

    pgd_annots_add_annot (demo);
    pgd_annots_viewer_queue_redraw (demo);
    demo->mode = MODE_DRAWING;

    return TRUE;
}

static gboolean
pgd_annots_drawing_area_motion_notify (GtkWidget      *area,
                                       GdkEventMotion *event,
                                       PgdAnnotsDemo  *demo)
{
    PopplerRectangle rect;
    PopplerPoint start, end;
    gdouble width, height;

    if (!demo->page || demo->mode != MODE_DRAWING || demo->start.x == -1)
        return FALSE;

    demo->stop.x = event->x;
    demo->stop.y = event->y;

    poppler_page_get_size (demo->page, &width, &height);

    /* Keep the drawing within the page */
    demo->stop.x = CLAMP (demo->stop.x, 0, width);
    demo->stop.y = CLAMP (demo->stop.y, 0, height);

    rect.x1 = start.x = demo->start.x;
    rect.y1 = start.y = height - demo->start.y;
    rect.x2 = end.x = demo->stop.x;
    rect.y2 = end.y = height - demo->stop.y;

    poppler_annot_set_rectangle (demo->active_annot, &rect);

    if (demo->annot_type == POPPLER_ANNOT_LINE)
        poppler_annot_line_set_vertices (POPPLER_ANNOT_LINE (demo->active_annot),
                                         &start, &end);

    if (POPPLER_IS_ANNOT_TEXT_MARKUP (demo->active_annot))
        pgd_annots_update_selected_text (demo);

    pgd_annot_view_set_annot (demo, demo->active_annot);
    pgd_annots_viewer_queue_redraw (demo);

    return TRUE;
}

static gboolean
pgd_annots_drawing_area_button_release (GtkWidget      *area,
                                        GdkEventButton *event,
                                        PgdAnnotsDemo  *demo)
{
    if (!demo->page || demo->mode != MODE_DRAWING || event->button != 1)
        return FALSE;

    pgd_annots_finish_add_annot (demo);

    return TRUE;
}

/* Main UI */
GtkWidget *
pgd_annots_create_widget (PopplerDocument *document)
{
    PgdAnnotsDemo    *demo;
    GtkWidget        *label;
    GtkWidget        *vbox, *vbox2;
    GtkWidget        *button;
    GtkWidget        *hbox, *page_selector;
    GtkWidget        *hpaned;
    GtkWidget        *swindow, *treeview;
    GtkTreeSelection *selection;
    GtkCellRenderer  *renderer;
    GtkTreeViewColumn *column;
    GtkListStore     *model;
    GtkTreeIter       iter;
    gchar            *str;
    gint              n_pages;
    gint              i;

    demo = g_new0 (PgdAnnotsDemo, 1);

    demo->doc = g_object_ref (document);
    demo->cursor = GDK_LAST_CURSOR;
    demo->mode = MODE_NORMAL;

    n_pages = poppler_document_get_n_pages (document);

    vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 12);
    vbox2 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);

    hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);

    label = gtk_label_new ("Page:");
    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
    gtk_widget_show (label);

    page_selector = gtk_spin_button_new_with_range (1, n_pages, 1);
    g_signal_connect (G_OBJECT (page_selector), "value-changed",
                      G_CALLBACK (pgd_annots_page_selector_value_changed),
                      (gpointer) demo);
    gtk_box_pack_start (GTK_BOX (hbox), page_selector, FALSE, TRUE, 0);
    gtk_widget_show (page_selector);

    str = g_strdup_printf ("of %d", n_pages);
    label = gtk_label_new (str);
    gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
    gtk_widget_show (label);
    g_free (str);

    demo->remove_button = gtk_button_new_with_mnemonic ("_Remove");
    gtk_widget_set_sensitive (demo->remove_button, FALSE);
    g_signal_connect (G_OBJECT (demo->remove_button), "clicked",
                      G_CALLBACK (pgd_annots_remove_annot),
                      (gpointer) demo);
    gtk_box_pack_end (GTK_BOX (hbox), demo->remove_button, FALSE, FALSE, 6);
    gtk_widget_show (demo->remove_button);

    gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);

    button = gtk_button_new_with_mnemonic ("_Add");
    g_signal_connect (G_OBJECT (button), "clicked",
                      G_CALLBACK (pgd_annots_start_add_annot),
                      (gpointer) demo);
    gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
    gtk_widget_show (button);

    model = gtk_list_store_new(SELECTED_N_COLUMNS,
                               G_TYPE_INT, G_TYPE_STRING);

    for (i = 0; i < G_N_ELEMENTS (supported_annots); i++) {
        gtk_list_store_append (model, &iter);
        gtk_list_store_set (model, &iter,
                            SELECTED_TYPE_COLUMN, supported_annots[i].type,
                            SELECTED_LABEL_COLUMN, supported_annots[i].label,
                            -1);
    }

    demo->type_selector = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
    g_object_unref (model);

    renderer = gtk_cell_renderer_text_new ();
    gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (demo->type_selector), renderer, TRUE);
    gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (demo->type_selector), renderer,
                                    "text", SELECTED_LABEL_COLUMN,
                                    NULL);
    gtk_combo_box_set_active (GTK_COMBO_BOX (demo->type_selector), 0);
    gtk_box_pack_end (GTK_BOX (hbox), demo->type_selector, FALSE, FALSE, 0);
    gtk_widget_show (demo->type_selector);

    button = gtk_color_button_new ();
    demo->annot_color.red = 65535;
    demo->annot_color.alpha = 1.0;
    gtk_color_chooser_set_rgba (GTK_COLOR_CHOOSER (button), &demo->annot_color);
    g_signal_connect (button, "notify::color",
                      G_CALLBACK (pgd_annot_color_changed),
                      (gpointer)demo);
    gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, TRUE, 0);
    gtk_widget_show (button);

    gtk_widget_show (hbox);

    demo->timer_label = gtk_label_new (NULL);
    gtk_label_set_markup (GTK_LABEL (demo->timer_label), "<i>No annotations found</i>");
    g_object_set (G_OBJECT (demo->timer_label), "xalign", 1.0, NULL);
    gtk_box_pack_start (GTK_BOX (vbox), demo->timer_label, FALSE, TRUE, 0);
    gtk_widget_show (demo->timer_label);

    hpaned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);

    demo->annot_view = pgd_annot_view_new ();

    swindow = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
                                    GTK_POLICY_AUTOMATIC,
                                    GTK_POLICY_AUTOMATIC);

    demo->model = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING,
                                      GDK_TYPE_PIXBUF, G_TYPE_BOOLEAN,
				      G_TYPE_BOOLEAN, G_TYPE_BOOLEAN,
				      G_TYPE_OBJECT);
    treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (demo->model));
    demo->tree_view = treeview;

    column = gtk_tree_view_column_new ();
    gtk_tree_view_column_set_title (column, "Type");
    gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);

    renderer = gtk_cell_renderer_pixbuf_new ();
    gtk_tree_view_column_pack_start (column, renderer, TRUE);
    gtk_tree_view_column_add_attribute (column, renderer, "pixbuf", ANNOTS_COLOR_COLUMN);

    renderer = gtk_cell_renderer_text_new ();
    gtk_tree_view_column_pack_start (column, renderer, TRUE);
    gtk_tree_view_column_add_attribute (column, renderer, "text", ANNOTS_TYPE_COLUMN);

    renderer = gtk_cell_renderer_toggle_new ();
    g_signal_connect (renderer, "toggled",
		      G_CALLBACK (pgd_annots_invisible_flag_toggled),
		      (gpointer) demo);
    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                                 ANNOTS_FLAG_INVISIBLE_COLUMN, "Invisible",
                                                 renderer,
                                                 "active", ANNOTS_FLAG_INVISIBLE_COLUMN,
                                                 NULL);

    renderer = gtk_cell_renderer_toggle_new ();
    g_signal_connect (renderer, "toggled",
                      G_CALLBACK (pgd_annots_hidden_flag_toggled),
                      (gpointer) demo);
    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                                 ANNOTS_FLAG_HIDDEN_COLUMN, "Hidden",
                                                 renderer,
                                                 "active", ANNOTS_FLAG_HIDDEN_COLUMN,
                                                 NULL);

    renderer = gtk_cell_renderer_toggle_new ();
    g_signal_connect (renderer, "toggled",
                      G_CALLBACK (pgd_annots_print_flag_toggled),
                      (gpointer) demo);
    gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
                                                 ANNOTS_FLAG_PRINT_COLUMN, "Print",
                                                 renderer,
                                                 "active", ANNOTS_FLAG_PRINT_COLUMN,
                                                 NULL);

    selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
    g_signal_connect (G_OBJECT (selection), "changed",
                      G_CALLBACK (pgd_annots_selection_changed),
                      (gpointer) demo);

    /* Annotation's list */
    gtk_container_add (GTK_CONTAINER (swindow), treeview);
    gtk_widget_show (treeview);

    gtk_box_pack_start (GTK_BOX (vbox2), swindow, TRUE, TRUE, 0);
    gtk_widget_show (swindow);

    /* Annotation Properties */
    swindow = gtk_scrolled_window_new (NULL, NULL);
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
                                    GTK_POLICY_AUTOMATIC,
                                    GTK_POLICY_AUTOMATIC);
    gtk_container_add (GTK_CONTAINER (swindow), demo->annot_view);
    gtk_widget_show (demo->annot_view);
    gtk_widget_show (swindow);

    gtk_box_pack_start (GTK_BOX (vbox2), swindow, TRUE, TRUE, 6);
    gtk_widget_show (swindow);

    gtk_paned_add1 (GTK_PANED (hpaned), vbox2);
    gtk_widget_show (vbox2);

    /* Demo Area (Render) */
    demo->darea = gtk_drawing_area_new ();
    g_signal_connect (demo->darea, "draw",
                      G_CALLBACK (pgd_annots_view_drawing_area_draw),
                      demo);
    g_signal_connect (demo->darea, "realize",
                      G_CALLBACK (pgd_annots_drawing_area_realize),
                      (gpointer)demo);
    g_signal_connect (demo->darea, "button_press_event",
                      G_CALLBACK (pgd_annots_drawing_area_button_press),
                      (gpointer)demo);
    g_signal_connect (demo->darea, "motion_notify_event",
                      G_CALLBACK (pgd_annots_drawing_area_motion_notify),
                      (gpointer)demo);
    g_signal_connect (demo->darea, "button_release_event",
                      G_CALLBACK (pgd_annots_drawing_area_button_release),
                      (gpointer)demo);

    swindow = gtk_scrolled_window_new (NULL, NULL);
#if GTK_CHECK_VERSION(3, 7, 8)
    gtk_container_add(GTK_CONTAINER(swindow), demo->darea);
#else
    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), demo->darea);
#endif
    gtk_widget_show (demo->darea);

    gtk_paned_add2 (GTK_PANED (hpaned), swindow);
    gtk_widget_show (swindow);

    gtk_paned_set_position (GTK_PANED (hpaned), 300);

    gtk_box_pack_start (GTK_BOX (vbox), hpaned, TRUE, TRUE, 0);
    gtk_widget_show (hpaned);

    g_object_weak_ref (G_OBJECT (vbox),
                       (GWeakNotify)pgd_annots_free,
                       demo);

    pgd_annots_viewer_queue_redraw (demo);
    pgd_annots_get_annots (demo);

    demo->main_box = vbox;

    return vbox;
}
