~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/poppler/glib/demo/layers.c

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2008 Carlos Garcia Campos  <carlosgc@gnome.org>
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License as published by
 
6
 * the Free Software Foundation; either version 2, or (at your option)
 
7
 * any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License
 
15
 * along with this program; if not, write to the Free Software
 
16
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 
17
 */
 
18
 
 
19
#include "config.h"
 
20
 
 
21
#include <gtk/gtk.h>
 
22
 
 
23
#include "layers.h"
 
24
 
 
25
enum {
 
26
        LAYERS_TITLE_COLUMN,
 
27
        LAYERS_VISIBILITY_COLUMN,
 
28
        LAYERS_ENABLE_COLUMN,
 
29
        LAYERS_SHOWTOGGLE_COLUMN,
 
30
        LAYERS_RB_GROUP_COLUMN,
 
31
        LAYERS_LAYER_COLUMN,
 
32
        N_COLUMNS
 
33
};
 
34
 
 
35
typedef struct {
 
36
        PopplerDocument *doc;
 
37
        guint            page;
 
38
        GtkWidget       *treeview;
 
39
        GtkWidget       *darea;
 
40
 
 
41
        cairo_surface_t *surface;
 
42
} PgdLayersDemo;
 
43
 
 
44
static void
 
45
pgd_layers_free (PgdLayersDemo *demo)
 
46
{
 
47
        if (!demo)
 
48
                return;
 
49
 
 
50
        if (demo->doc) {
 
51
                g_object_unref (demo->doc);
 
52
                demo->doc = NULL;
 
53
        }
 
54
 
 
55
        if (demo->surface) {
 
56
                cairo_surface_destroy (demo->surface);
 
57
                demo->surface = NULL;
 
58
        }
 
59
 
 
60
        g_free (demo);
 
61
}
 
62
 
 
63
static void
 
64
build_tree (PopplerDocument   *document,
 
65
            GtkTreeModel      *model,
 
66
            GtkTreeIter       *parent,
 
67
            PopplerLayersIter *iter)
 
68
{
 
69
 
 
70
        do {
 
71
                GtkTreeIter        tree_iter;
 
72
                PopplerLayersIter *child;
 
73
                PopplerLayer      *layer;
 
74
                gboolean           visible;
 
75
                gchar             *markup;
 
76
                gint               rb_group = 0;
 
77
 
 
78
                layer = poppler_layers_iter_get_layer (iter);
 
79
                if (layer) {
 
80
                        markup = g_markup_escape_text (poppler_layer_get_title (layer), -1);
 
81
                        visible = poppler_layer_is_visible (layer);
 
82
                        rb_group = poppler_layer_get_radio_button_group_id (layer);
 
83
                } else {
 
84
                        gchar *title;
 
85
 
 
86
                        title = poppler_layers_iter_get_title (iter);
 
87
                        markup = g_markup_escape_text (title, -1);
 
88
                        g_free (title);
 
89
 
 
90
                        visible = FALSE;
 
91
                        layer = NULL;
 
92
                }
 
93
 
 
94
                gtk_tree_store_append (GTK_TREE_STORE (model), &tree_iter, parent);
 
95
                gtk_tree_store_set (GTK_TREE_STORE (model), &tree_iter,
 
96
                                    LAYERS_TITLE_COLUMN, markup,
 
97
                                    LAYERS_VISIBILITY_COLUMN, visible,
 
98
                                    LAYERS_ENABLE_COLUMN, TRUE, /* FIXME */
 
99
                                    LAYERS_SHOWTOGGLE_COLUMN, (layer != NULL),
 
100
                                    LAYERS_RB_GROUP_COLUMN, rb_group,
 
101
                                    LAYERS_LAYER_COLUMN, layer,
 
102
                                    -1);
 
103
                if (layer)
 
104
                        g_object_unref (layer);
 
105
                g_free (markup);
 
106
 
 
107
                child = poppler_layers_iter_get_child (iter);
 
108
                if (child)
 
109
                        build_tree (document, model, &tree_iter, child);
 
110
                poppler_layers_iter_free (child);
 
111
        } while (poppler_layers_iter_next (iter));
 
112
}
 
113
 
 
114
GtkTreeModel *
 
115
pgd_layers_create_model (PopplerDocument *document)
 
116
{
 
117
        GtkTreeModel     *model;
 
118
        PopplerLayersIter *iter;
 
119
 
 
120
        iter = poppler_layers_iter_new (document);
 
121
        if (iter) {
 
122
                model = GTK_TREE_MODEL (
 
123
                        gtk_tree_store_new (N_COLUMNS,
 
124
                                            G_TYPE_STRING, 
 
125
                                            G_TYPE_BOOLEAN,
 
126
                                            G_TYPE_BOOLEAN,
 
127
                                            G_TYPE_BOOLEAN,
 
128
                                            G_TYPE_INT,
 
129
                                            G_TYPE_OBJECT));
 
130
                build_tree (document, model, NULL, iter);
 
131
                poppler_layers_iter_free (iter);
 
132
        } else {
 
133
                GtkTreeIter tree_iter;
 
134
                gchar      *markup;
 
135
                
 
136
                model = GTK_TREE_MODEL (gtk_list_store_new (1, G_TYPE_STRING));
 
137
                gtk_list_store_append (GTK_LIST_STORE (model), &tree_iter);
 
138
                markup = g_strdup_printf ("<span size=\"larger\" style=\"italic\">%s</span>",
 
139
                                          "The document doesn't contain layers");
 
140
                gtk_list_store_set (GTK_LIST_STORE (model), &tree_iter,
 
141
                                    0, markup, -1);
 
142
                g_free (markup);
 
143
        }
 
144
 
 
145
        return model;
 
146
}
 
147
 
 
148
static cairo_surface_t *
 
149
pgd_layers_render_page (PgdLayersDemo *demo)
 
150
{
 
151
        cairo_t *cr;
 
152
        PopplerPage *page;
 
153
        gdouble width, height;
 
154
        cairo_surface_t *surface = NULL;
 
155
 
 
156
        page = poppler_document_get_page (demo->doc, demo->page);
 
157
        if (!page)
 
158
                return NULL;
 
159
 
 
160
        poppler_page_get_size (page, &width, &height);
 
161
        gtk_widget_set_size_request (demo->darea, width, height);
 
162
        
 
163
        surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24,
 
164
                                              width, height);
 
165
        cr = cairo_create (surface);
 
166
 
 
167
        cairo_save (cr);
 
168
        cairo_set_source_rgb (cr, 1, 1, 1);
 
169
        cairo_rectangle (cr, 0, 0, width, height);
 
170
        cairo_fill (cr);
 
171
        cairo_restore (cr);
 
172
 
 
173
        cairo_save (cr);
 
174
        poppler_page_render (page, cr);
 
175
        cairo_restore (cr);
 
176
        
 
177
        cairo_destroy (cr);
 
178
        g_object_unref (page);
 
179
 
 
180
        return surface;
 
181
}
 
182
 
 
183
static gboolean
 
184
pgd_layers_viewer_drawing_area_expose (GtkWidget      *area,
 
185
                                       GdkEventExpose *event,
 
186
                                       PgdLayersDemo  *demo)
 
187
{
 
188
        cairo_t *cr;
 
189
        
 
190
        if (!demo->surface) {
 
191
                demo->surface = pgd_layers_render_page (demo);
 
192
                if (!demo->surface)
 
193
                        return FALSE;
 
194
        }
 
195
 
 
196
        gdk_window_clear (gtk_widget_get_window (area));
 
197
 
 
198
        cr = gdk_cairo_create (gtk_widget_get_window (area));
 
199
        cairo_set_source_surface (cr, demo->surface, 0, 0);
 
200
        cairo_paint (cr);
 
201
        cairo_destroy (cr);
 
202
 
 
203
        return TRUE;
 
204
}
 
205
 
 
206
static gboolean
 
207
pgd_layers_viewer_redraw (PgdLayersDemo *demo)
 
208
{
 
209
        cairo_surface_destroy (demo->surface);
 
210
        demo->surface = NULL;
 
211
 
 
212
        gtk_widget_queue_draw (demo->darea);
 
213
 
 
214
        return FALSE;
 
215
}
 
216
 
 
217
static void
 
218
pgd_layers_viewer_queue_redraw (PgdLayersDemo *demo)
 
219
{
 
220
        g_idle_add ((GSourceFunc)pgd_layers_viewer_redraw, demo);
 
221
}
 
222
 
 
223
static void
 
224
pgd_layers_page_selector_value_changed (GtkSpinButton *spinbutton,
 
225
                                        PgdLayersDemo *demo)
 
226
{
 
227
        demo->page = (gint)gtk_spin_button_get_value (spinbutton) - 1;
 
228
        pgd_layers_viewer_queue_redraw (demo);
 
229
}
 
230
 
 
231
static GtkWidget *
 
232
pgd_layers_create_viewer (PgdLayersDemo *demo)
 
233
{
 
234
        GtkWidget *vbox, *hbox;
 
235
        GtkWidget *label;
 
236
        GtkWidget *swindow;
 
237
        GtkWidget *page_selector;
 
238
        guint      n_pages;
 
239
        gchar     *str;
 
240
 
 
241
        vbox = gtk_vbox_new (FALSE, 6);
 
242
 
 
243
        hbox = gtk_hbox_new (FALSE, 6);
 
244
 
 
245
        label = gtk_label_new ("Page:");
 
246
        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
 
247
        gtk_widget_show (label);
 
248
 
 
249
        n_pages = poppler_document_get_n_pages (demo->doc);
 
250
        page_selector = gtk_spin_button_new_with_range (1, n_pages, 1);
 
251
        g_signal_connect (G_OBJECT (page_selector), "value-changed",
 
252
                          G_CALLBACK (pgd_layers_page_selector_value_changed),
 
253
                          (gpointer)demo);
 
254
        gtk_box_pack_start (GTK_BOX (hbox), page_selector, FALSE, TRUE, 0);
 
255
        gtk_widget_show (page_selector);
 
256
 
 
257
        str = g_strdup_printf ("of %d", n_pages);
 
258
        label = gtk_label_new (str);
 
259
        gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, TRUE, 0);
 
260
        gtk_widget_show (label);
 
261
        g_free (str);
 
262
 
 
263
        gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
 
264
        gtk_widget_show (hbox);
 
265
 
 
266
        demo->darea = gtk_drawing_area_new ();
 
267
        g_signal_connect (G_OBJECT (demo->darea), "expose_event",
 
268
                          G_CALLBACK (pgd_layers_viewer_drawing_area_expose),
 
269
                          (gpointer)demo);
 
270
 
 
271
        swindow = gtk_scrolled_window_new (NULL, NULL);
 
272
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
 
273
                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
 
274
        gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (swindow), demo->darea);
 
275
        gtk_widget_show (demo->darea);
 
276
 
 
277
        gtk_box_pack_start (GTK_BOX (vbox), swindow, TRUE, TRUE, 0);
 
278
        gtk_widget_show (swindow);
 
279
 
 
280
        return vbox;
 
281
}
 
282
 
 
283
static gboolean
 
284
update_kids (GtkTreeModel *model,
 
285
             GtkTreePath  *path,
 
286
             GtkTreeIter  *iter,
 
287
             GtkTreeIter  *parent)
 
288
{
 
289
        if (gtk_tree_store_is_ancestor (GTK_TREE_STORE (model), parent, iter)) {
 
290
                gboolean visible;
 
291
 
 
292
                gtk_tree_model_get (model, parent,
 
293
                                    LAYERS_VISIBILITY_COLUMN, &visible,
 
294
                                    -1);
 
295
                gtk_tree_store_set (GTK_TREE_STORE (model), iter,
 
296
                                    LAYERS_ENABLE_COLUMN, visible,
 
297
                                    -1);
 
298
        }
 
299
 
 
300
        return FALSE;
 
301
}
 
302
 
 
303
static gboolean
 
304
clear_rb_group (GtkTreeModel *model,
 
305
                GtkTreePath  *path,
 
306
                GtkTreeIter  *iter,
 
307
                gint         *rb_group)
 
308
{
 
309
        gint group;
 
310
        
 
311
        gtk_tree_model_get (model, iter,
 
312
                            LAYERS_RB_GROUP_COLUMN, &group,
 
313
                            -1);
 
314
        
 
315
        if (group == *rb_group) {
 
316
                gtk_tree_store_set (GTK_TREE_STORE (model), iter,
 
317
                                    LAYERS_VISIBILITY_COLUMN, FALSE,
 
318
                                    -1);
 
319
        }
 
320
        
 
321
        return FALSE;
 
322
}
 
323
 
 
324
static void
 
325
pgd_layers_visibility_changed (GtkCellRendererToggle *cell,
 
326
                               gchar                 *path_str,
 
327
                               PgdLayersDemo         *demo)
 
328
{
 
329
        GtkTreeModel *model;
 
330
        GtkTreePath *path;
 
331
        GtkTreeIter iter;
 
332
        gboolean visible;
 
333
        PopplerLayer *layer;
 
334
 
 
335
        model = gtk_tree_view_get_model (GTK_TREE_VIEW (demo->treeview));
 
336
 
 
337
        path = gtk_tree_path_new_from_string (path_str);
 
338
        gtk_tree_model_get_iter (model, &iter, path);
 
339
        gtk_tree_model_get (model, &iter,
 
340
                            LAYERS_VISIBILITY_COLUMN, &visible,
 
341
                            LAYERS_LAYER_COLUMN, &layer,
 
342
                            -1);
 
343
 
 
344
        visible = !visible;
 
345
        visible ? poppler_layer_show (layer) : poppler_layer_hide (layer);
 
346
 
 
347
        if (visible) {
 
348
                gint rb_group;
 
349
                
 
350
                rb_group = poppler_layer_get_radio_button_group_id (layer);
 
351
                if (rb_group) {
 
352
                        gtk_tree_model_foreach (model,
 
353
                                                (GtkTreeModelForeachFunc)clear_rb_group,
 
354
                                                &rb_group);
 
355
                }
 
356
        }
 
357
        
 
358
        gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
 
359
                            LAYERS_VISIBILITY_COLUMN, visible,
 
360
                            -1);
 
361
        
 
362
        if (poppler_layer_is_parent (layer)) {
 
363
                gtk_tree_model_foreach (model,
 
364
                                        (GtkTreeModelForeachFunc)update_kids,
 
365
                                        &iter);
 
366
        }
 
367
 
 
368
        pgd_layers_viewer_queue_redraw (demo);
 
369
 
 
370
        gtk_tree_path_free (path);
 
371
        g_object_unref (layer);
 
372
}
 
373
 
 
374
GtkWidget *
 
375
pgd_layers_create_widget (PopplerDocument *document)
 
376
{
 
377
        PgdLayersDemo    *demo;
 
378
        GtkWidget        *swindow;
 
379
        GtkWidget        *treeview;
 
380
        GtkTreeModel     *model;
 
381
        GtkCellRenderer  *renderer;
 
382
        GtkTreeSelection *selection;
 
383
        GtkWidget        *hpaned, *viewer;
 
384
 
 
385
        demo = g_new0 (PgdLayersDemo, 1);
 
386
        demo->doc = g_object_ref (document);
 
387
        
 
388
        hpaned = gtk_hpaned_new ();
 
389
 
 
390
        viewer = pgd_layers_create_viewer (demo);
 
391
        
 
392
        swindow = gtk_scrolled_window_new (NULL, NULL);
 
393
        gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
 
394
                                        GTK_POLICY_AUTOMATIC,
 
395
                                        GTK_POLICY_AUTOMATIC);
 
396
 
 
397
        model = pgd_layers_create_model (document);
 
398
        treeview = gtk_tree_view_new_with_model (model);
 
399
        demo->treeview = treeview;
 
400
        g_object_unref (model);
 
401
 
 
402
        renderer = gtk_cell_renderer_text_new ();
 
403
        gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
 
404
                                                     0, "Layer",
 
405
                                                     renderer,
 
406
                                                     "markup", LAYERS_TITLE_COLUMN,
 
407
                                                     NULL);
 
408
        g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
 
409
        g_object_set (G_OBJECT (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 0)),
 
410
                      "expand", TRUE, NULL);
 
411
 
 
412
        if (GTK_IS_TREE_STORE (model)) {
 
413
                renderer = gtk_cell_renderer_toggle_new ();
 
414
                gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview),
 
415
                                                             1, "Show/Hide",
 
416
                                                             renderer,
 
417
                                                             "active", LAYERS_VISIBILITY_COLUMN,
 
418
                                                             "activatable", LAYERS_ENABLE_COLUMN,
 
419
                                                             "visible", LAYERS_SHOWTOGGLE_COLUMN,
 
420
                                                             NULL);
 
421
 
 
422
                g_signal_connect (renderer, "toggled",
 
423
                                  G_CALLBACK (pgd_layers_visibility_changed),
 
424
                                  (gpointer)demo);
 
425
                gtk_tree_view_column_set_clickable (gtk_tree_view_get_column (GTK_TREE_VIEW (treeview), 1),
 
426
                                                    TRUE);
 
427
        }
 
428
 
 
429
        gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)),
 
430
                                     GTK_SELECTION_NONE);
 
431
 
 
432
        gtk_container_add (GTK_CONTAINER (swindow), treeview);
 
433
        gtk_widget_show (treeview);
 
434
 
 
435
        gtk_paned_add1 (GTK_PANED (hpaned), swindow);
 
436
        gtk_widget_show (swindow);
 
437
 
 
438
        gtk_paned_add2 (GTK_PANED (hpaned), viewer);
 
439
        gtk_widget_show (viewer);
 
440
 
 
441
        gtk_paned_set_position (GTK_PANED (hpaned), 150);
 
442
 
 
443
        g_object_weak_ref (G_OBJECT (hpaned),
 
444
                           (GWeakNotify)pgd_layers_free,
 
445
                           (gpointer)demo);
 
446
 
 
447
        return hpaned;
 
448
}