Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/shell
diff options
context:
space:
mode:
authorCarlos Garcia Campos <carlosgc@gnome.org>2008-11-15 10:08:38 (GMT)
committer Carlos Garcia Campos <carlosgc@src.gnome.org>2008-11-15 10:08:38 (GMT)
commit7f94a4075450791807ee2699cb0e7a0293ccc2f3 (patch)
tree053081ede8f0448ba59d6729dc66dcc434817202 /shell
parentb39fbcf7b7c248bf2ab04d5ff86d17780194ae5d (diff)
Add layers support.
2008-11-15 Carlos Garcia Campos <carlosgc@gnome.org> * shell/Makefile.am: * shell/ev-jobs.[ch]: (ev_job_layers_init), (ev_job_layers_dispose), (ev_job_layers_run), (ev_job_layers_class_init), (ev_job_layers_new): * shell/ev-sidebar-layers.[ch]: * shell/ev-view.[ch]: (ev_view_form_field_button_create_widget), (ev_view_form_field_text_save), (ev_view_form_field_choice_save), (ev_view_reload_page), (ev_view_reload): * shell/ev-window.c: (setup_sidebar_from_metadata), (ev_window_sidebar_current_page_changed_cb), (sidebar_layers_visibility_changed), (ev_window_init): Add layers support. svn path=/trunk/; revision=3268
Diffstat (limited to 'shell')
-rw-r--r--shell/Makefile.am52
-rw-r--r--shell/ev-jobs.c67
-rw-r--r--shell/ev-jobs.h32
-rw-r--r--shell/ev-sidebar-layers.c405
-rw-r--r--shell/ev-sidebar-layers.h58
-rw-r--r--shell/ev-view.c42
-rw-r--r--shell/ev-view.h2
-rw-r--r--shell/ev-window.c45
8 files changed, 653 insertions, 50 deletions
diff --git a/shell/Makefile.am b/shell/Makefile.am
index 3dc7e15..b1dafd7 100644
--- a/shell/Makefile.am
+++ b/shell/Makefile.am
@@ -1,18 +1,19 @@
-INCLUDES= \
- -DDATADIR=\"$(pkgdatadir)\" \
- -DGNOMEDATADIR=\"$(datadir)\" \
- -I$(top_srcdir)/cut-n-paste/zoom-control/ \
- -I$(top_srcdir)/cut-n-paste/toolbar-editor/ \
- -I$(top_srcdir)/cut-n-paste/totem-screensaver/ \
- -I$(top_srcdir)/cut-n-paste/gedit-message-area/ \
- -I$(top_srcdir)/cut-n-paste/evmountoperation/ \
- -I$(top_srcdir)/cut-n-paste/smclient/ \
- -I$(top_srcdir)/libdocument \
- -I$(top_srcdir)/properties \
- -DGNOMELOCALEDIR=\"$(datadir)/locale\" \
- -DGNOMEICONDIR=\""$(datadir)/pixmaps"\" \
- $(SHELL_CFLAGS) \
- $(WARN_CFLAGS) \
+INCLUDES= \
+ -DDATADIR=\"$(pkgdatadir)\" \
+ -DGNOMEDATADIR=\"$(datadir)\" \
+ -I$(top_srcdir)/cut-n-paste/zoom-control/ \
+ -I$(top_srcdir)/cut-n-paste/toolbar-editor/ \
+ -I$(top_srcdir)/cut-n-paste/totem-screensaver/ \
+ -I$(top_srcdir)/cut-n-paste/gedit-message-area/ \
+ -I$(top_srcdir)/cut-n-paste/gimpcellrenderertoggle/ \
+ -I$(top_srcdir)/cut-n-paste/evmountoperation/ \
+ -I$(top_srcdir)/cut-n-paste/smclient/ \
+ -I$(top_srcdir)/libdocument \
+ -I$(top_srcdir)/properties \
+ -DGNOMELOCALEDIR=\"$(datadir)/locale\" \
+ -DGNOMEICONDIR=\""$(datadir)/pixmaps"\" \
+ $(SHELL_CFLAGS) \
+ $(WARN_CFLAGS) \
$(DISABLE_DEPRECATED)
bin_PROGRAMS=evince
@@ -81,6 +82,8 @@ evince_SOURCES= \
ev-sidebar.h \
ev-sidebar-attachments.c \
ev-sidebar-attachments.h \
+ ev-sidebar-layers.c \
+ ev-sidebar-layers.h \
ev-sidebar-links.c \
ev-sidebar-links.h \
ev-sidebar-page.c \
@@ -95,15 +98,16 @@ evince_SOURCES= \
ev-transition-animation.h \
main.c
-evince_LDADD= \
- $(top_builddir)/cut-n-paste/zoom-control/libephyzoom.la \
- $(top_builddir)/cut-n-paste/toolbar-editor/libtoolbareditor.la \
- $(top_builddir)/cut-n-paste/totem-screensaver/libtotemscrsaver.la \
- $(top_builddir)/cut-n-paste/gedit-message-area/libgeditmsgarea.la \
- $(top_builddir)/cut-n-paste/evmountoperation/libevmountoperation.la \
- $(top_builddir)/cut-n-paste/smclient/libsmclient.la \
- $(top_builddir)/properties/libevproperties.la \
- $(top_builddir)/libdocument/libevbackend.la \
+evince_LDADD= \
+ $(top_builddir)/cut-n-paste/zoom-control/libephyzoom.la \
+ $(top_builddir)/cut-n-paste/toolbar-editor/libtoolbareditor.la \
+ $(top_builddir)/cut-n-paste/totem-screensaver/libtotemscrsaver.la \
+ $(top_builddir)/cut-n-paste/gedit-message-area/libgeditmsgarea.la \
+ $(top_builddir)/cut-n-paste/gimpcellrenderertoggle/libgimpcellrenderertoggle.la \
+ $(top_builddir)/cut-n-paste/evmountoperation/libevmountoperation.la \
+ $(top_builddir)/cut-n-paste/smclient/libsmclient.la \
+ $(top_builddir)/properties/libevproperties.la \
+ $(top_builddir)/libdocument/libevbackend.la \
$(SHELL_LIBS)
BUILT_SOURCES = ev-marshal.h ev-marshal.c
diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c
index dee23b8..1a5dd47 100644
--- a/shell/ev-jobs.c
+++ b/shell/ev-jobs.c
@@ -32,6 +32,7 @@
#include "ev-document-fonts.h"
#include "ev-document-security.h"
#include "ev-document-find.h"
+#include "ev-document-layers.h"
#include "ev-debug.h"
#include <errno.h>
@@ -57,6 +58,8 @@ static void ev_job_print_init (EvJobPrint *job);
static void ev_job_print_class_init (EvJobPrintClass *class);
static void ev_job_find_init (EvJobFind *job);
static void ev_job_find_class_init (EvJobFindClass *class);
+static void ev_job_layers_init (EvJobLayers *job);
+static void ev_job_layers_class_init (EvJobLayersClass *class);
enum {
CANCELLED,
@@ -94,6 +97,7 @@ G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobPrint, ev_job_print, EV_TYPE_JOB)
G_DEFINE_TYPE (EvJobFind, ev_job_find, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobLayers, ev_job_layers, EV_TYPE_JOB)
/* EvJob */
static void
@@ -1536,3 +1540,66 @@ ev_job_find_get_results (EvJobFind *job)
return job->pages;
}
+/* EvJobLayers */
+static void
+ev_job_layers_init (EvJobLayers *job)
+{
+ EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
+
+static void
+ev_job_layers_dispose (GObject *object)
+{
+ EvJobLayers *job;
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+
+ job = EV_JOB_LAYERS (object);
+
+ if (job->model) {
+ g_object_unref (job->model);
+ job->model = NULL;
+ }
+
+ (* G_OBJECT_CLASS (ev_job_layers_parent_class)->dispose) (object);
+}
+
+static gboolean
+ev_job_layers_run (EvJob *job)
+{
+ EvJobLayers *job_layers = EV_JOB_LAYERS (job);
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+ ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+ ev_document_doc_mutex_lock ();
+ job_layers->model = ev_document_layers_get_layers (EV_DOCUMENT_LAYERS (job->document));
+ ev_document_doc_mutex_unlock ();
+
+ ev_job_succeeded (job);
+
+ return FALSE;
+}
+
+static void
+ev_job_layers_class_init (EvJobLayersClass *class)
+{
+ GObjectClass *oclass = G_OBJECT_CLASS (class);
+ EvJobClass *job_class = EV_JOB_CLASS (class);
+
+ oclass->dispose = ev_job_layers_dispose;
+ job_class->run = ev_job_layers_run;
+}
+
+EvJob *
+ev_job_layers_new (EvDocument *document)
+{
+ EvJob *job;
+
+ ev_debug_message (DEBUG_JOBS, NULL);
+
+ job = g_object_new (EV_TYPE_JOB_LAYERS, NULL);
+ job->document = g_object_ref (document);
+
+ return job;
+}
diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h
index 188759e..6d6581a 100644
--- a/shell/ev-jobs.h
+++ b/shell/ev-jobs.h
@@ -60,6 +60,9 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
typedef struct _EvJobFind EvJobFind;
typedef struct _EvJobFindClass EvJobFindClass;
+typedef struct _EvJobLayers EvJobLayers;
+typedef struct _EvJobLayersClass EvJobLayersClass;
+
#define EV_TYPE_JOB (ev_job_get_type())
#define EV_JOB(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB, EvJob))
#define EV_JOB_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB, EvJobClass))
@@ -106,10 +109,15 @@ typedef struct _EvJobFindClass EvJobFindClass;
#define EV_JOB_PRINT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_PRINT, EvJobPrintClass))
#define EV_IS_JOB_PRINT(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_PRINT))
-#define EV_TYPE_JOB_FIND (ev_job_find_get_type())
-#define EV_JOB_FIND(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_FIND, EvJobFind))
-#define EV_JOB_FIND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_FIND, EvJobFindClass))
-#define EV_IS_JOB_FIND(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_FIND))
+#define EV_TYPE_JOB_FIND (ev_job_find_get_type())
+#define EV_JOB_FIND(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_FIND, EvJobFind))
+#define EV_JOB_FIND_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_FIND, EvJobFindClass))
+#define EV_IS_JOB_FIND(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_FIND))
+
+#define EV_TYPE_JOB_LAYERS (ev_job_layers_get_type())
+#define EV_JOB_LAYERS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_LAYERS, EvJobLayers))
+#define EV_JOB_LAYERS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_LAYERS, EvJobLayersClass))
+#define EV_IS_JOB_LAYERS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_LAYERS))
typedef enum {
EV_JOB_RUN_THREAD,
@@ -320,6 +328,18 @@ struct _EvJobFindClass
gint page);
};
+struct _EvJobLayers
+{
+ EvJob parent;
+
+ GtkTreeModel *model;
+};
+
+struct _EvJobLayersClass
+{
+ EvJobClass parent_class;
+};
+
/* Base job class */
GType ev_job_get_type (void) G_GNUC_CONST;
gboolean ev_job_run (EvJob *job);
@@ -414,6 +434,10 @@ gdouble ev_job_find_get_progress (EvJobFind *job);
gboolean ev_job_find_has_results (EvJobFind *job);
GList **ev_job_find_get_results (EvJobFind *job);
+/* EvJobLayers */
+GType ev_job_layers_get_type (void) G_GNUC_CONST;
+EvJob *ev_job_layers_new (EvDocument *document);
+
G_END_DECLS
#endif /* __EV_JOBS_H__ */
diff --git a/shell/ev-sidebar-layers.c b/shell/ev-sidebar-layers.c
new file mode 100644
index 0000000..cebd96d
--- /dev/null
+++ b/shell/ev-sidebar-layers.c
@@ -0,0 +1,405 @@
+/* ev-sidebar-layers.c
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince 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 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib/gi18n.h>
+#include "gimpcellrenderertoggle.h"
+
+#include "ev-document-layers.h"
+#include "ev-sidebar-page.h"
+#include "ev-jobs.h"
+#include "ev-job-scheduler.h"
+#include "ev-stock-icons.h"
+#include "ev-sidebar-layers.h"
+
+struct _EvSidebarLayersPrivate {
+ GtkTreeView *tree_view;
+
+ EvDocument *document;
+ EvJob *job;
+};
+
+enum {
+ PROP_0,
+ PROP_WIDGET
+};
+
+enum {
+ LAYERS_VISIBILITY_CHANGED,
+ N_SIGNALS
+};
+
+static void ev_sidebar_layers_page_iface_init (EvSidebarPageIface *iface);
+static void job_finished_callback (EvJobLayers *job,
+ EvSidebarLayers *sidebar_layers);
+
+static guint signals[N_SIGNALS];
+
+G_DEFINE_TYPE_EXTENDED (EvSidebarLayers,
+ ev_sidebar_layers,
+ GTK_TYPE_VBOX,
+ 0,
+ G_IMPLEMENT_INTERFACE (EV_TYPE_SIDEBAR_PAGE,
+ ev_sidebar_layers_page_iface_init))
+
+#define EV_SIDEBAR_LAYERS_GET_PRIVATE(object) \
+ (G_TYPE_INSTANCE_GET_PRIVATE ((object), EV_TYPE_SIDEBAR_LAYERS, EvSidebarLayersPrivate))
+
+static void
+ev_sidebar_layers_dispose (GObject *object)
+{
+ EvSidebarLayers *sidebar = EV_SIDEBAR_LAYERS (object);
+
+ if (sidebar->priv->job) {
+ g_signal_handlers_disconnect_by_func (sidebar->priv->job,
+ job_finished_callback,
+ sidebar);
+ ev_job_cancel (sidebar->priv->job);
+ g_object_unref (sidebar->priv->job);
+ sidebar->priv->job = NULL;
+ }
+
+ if (sidebar->priv->document) {
+ g_object_unref (sidebar->priv->document);
+ sidebar->priv->document = NULL;
+ }
+
+ G_OBJECT_CLASS (ev_sidebar_layers_parent_class)->dispose (object);
+}
+
+static void
+ev_sidebar_layers_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EvSidebarLayers *ev_sidebar_layers;
+
+ ev_sidebar_layers = EV_SIDEBAR_LAYERS (object);
+
+ switch (prop_id) {
+ case PROP_WIDGET:
+ g_value_set_object (value, ev_sidebar_layers->priv->tree_view);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static GtkTreeModel *
+ev_sidebar_layers_create_loading_model (void)
+{
+ GtkTreeModel *retval;
+ GtkTreeIter iter;
+ gchar *markup;
+
+ /* Creates a fake model to indicate that we're loading */
+ retval = (GtkTreeModel *)gtk_list_store_new (EV_DOCUMENT_LAYERS_N_COLUMNS,
+ G_TYPE_STRING,
+ G_TYPE_OBJECT,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN,
+ G_TYPE_BOOLEAN,
+ G_TYPE_INT);
+
+ gtk_list_store_append (GTK_LIST_STORE (retval), &iter);
+ markup = g_strdup_printf ("<span size=\"larger\" style=\"italic\">%s</span>", _("Loading..."));
+ gtk_list_store_set (GTK_LIST_STORE (retval), &iter,
+ EV_DOCUMENT_LAYERS_COLUMN_TITLE, markup,
+ EV_DOCUMENT_LAYERS_COLUMN_VISIBLE, FALSE,
+ EV_DOCUMENT_LAYERS_COLUMN_ENABLED, TRUE,
+ EV_DOCUMENT_LAYERS_COLUMN_SHOWTOGGLE, FALSE,
+ EV_DOCUMENT_LAYERS_COLUMN_RBGROUP, -1,
+ EV_DOCUMENT_LAYERS_COLUMN_LAYER, NULL,
+ -1);
+ g_free (markup);
+
+ return retval;
+}
+
+static gboolean
+update_kids (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ GtkTreeIter *parent)
+{
+ if (gtk_tree_store_is_ancestor (GTK_TREE_STORE (model), parent, iter)) {
+ gboolean visible;
+
+ gtk_tree_model_get (model, parent,
+ EV_DOCUMENT_LAYERS_COLUMN_VISIBLE, &visible,
+ -1);
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ EV_DOCUMENT_LAYERS_COLUMN_ENABLED, visible,
+ -1);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+clear_rb_group (GtkTreeModel *model,
+ GtkTreePath *path,
+ GtkTreeIter *iter,
+ gint *rb_group)
+{
+ gint group;
+
+ gtk_tree_model_get (model, iter,
+ EV_DOCUMENT_LAYERS_COLUMN_RBGROUP, &group,
+ -1);
+
+ if (group == *rb_group) {
+ gtk_tree_store_set (GTK_TREE_STORE (model), iter,
+ EV_DOCUMENT_LAYERS_COLUMN_VISIBLE, FALSE,
+ -1);
+ }
+
+ return FALSE;
+}
+
+static void
+ev_sidebar_layers_visibility_changed (GtkCellRendererToggle *cell,
+ gchar *path_str,
+ EvSidebarLayers *ev_layers)
+{
+ GtkTreeModel *model;
+ GtkTreePath *path;
+ GtkTreeIter iter;
+ gboolean visible;
+ EvLayer *layer;
+
+ model = gtk_tree_view_get_model (ev_layers->priv->tree_view);
+
+ path = gtk_tree_path_new_from_string (path_str);
+ gtk_tree_model_get_iter (model, &iter, path);
+ gtk_tree_model_get (model, &iter,
+ EV_DOCUMENT_LAYERS_COLUMN_VISIBLE, &visible,
+ EV_DOCUMENT_LAYERS_COLUMN_LAYER, &layer,
+ -1);
+
+ visible = !visible;
+ if (visible) {
+ gint rb_group;
+
+ ev_document_layers_show_layer (EV_DOCUMENT_LAYERS (ev_layers->priv->document),
+ layer);
+
+ rb_group = ev_layer_get_rb_group (layer);
+ if (rb_group) {
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc)clear_rb_group,
+ &rb_group);
+ }
+ } else {
+ ev_document_layers_hide_layer (EV_DOCUMENT_LAYERS (ev_layers->priv->document),
+ layer);
+ }
+
+ gtk_tree_store_set (GTK_TREE_STORE (model), &iter,
+ EV_DOCUMENT_LAYERS_COLUMN_VISIBLE, visible,
+ -1);
+
+ if (ev_layer_is_parent (layer)) {
+ gtk_tree_model_foreach (model,
+ (GtkTreeModelForeachFunc)update_kids,
+ &iter);
+ }
+
+ gtk_tree_path_free (path);
+
+ g_signal_emit (ev_layers, signals[LAYERS_VISIBILITY_CHANGED], 0);
+}
+
+static GtkTreeView *
+ev_sidebar_layers_create_tree_view (EvSidebarLayers *ev_layers)
+{
+ GtkTreeView *tree_view;
+ GtkTreeViewColumn *column;
+ GtkCellRenderer *renderer;
+
+ tree_view = GTK_TREE_VIEW (gtk_tree_view_new ());
+ gtk_tree_view_set_headers_visible (tree_view, FALSE);
+ gtk_tree_selection_set_mode (gtk_tree_view_get_selection (tree_view),
+ GTK_SELECTION_NONE);
+
+
+ column = gtk_tree_view_column_new ();
+
+ renderer = gimp_cell_renderer_toggle_new (EV_STOCK_VISIBLE);
+ gtk_tree_view_column_pack_start (column, renderer, FALSE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "active", EV_DOCUMENT_LAYERS_COLUMN_VISIBLE,
+ "activatable", EV_DOCUMENT_LAYERS_COLUMN_ENABLED,
+ "visible", EV_DOCUMENT_LAYERS_COLUMN_SHOWTOGGLE,
+ "sensitive", EV_DOCUMENT_LAYERS_COLUMN_ENABLED,
+ NULL);
+ g_object_set (G_OBJECT (renderer),
+ "xpad", 0,
+ "ypad", 0,
+ NULL);
+ g_signal_connect (renderer, "toggled",
+ G_CALLBACK (ev_sidebar_layers_visibility_changed),
+ (gpointer)ev_layers);
+
+ renderer = gtk_cell_renderer_text_new ();
+ gtk_tree_view_column_pack_start (column, renderer, TRUE);
+ gtk_tree_view_column_set_attributes (column, renderer,
+ "markup", EV_DOCUMENT_LAYERS_COLUMN_TITLE,
+ "sensitive", EV_DOCUMENT_LAYERS_COLUMN_ENABLED,
+ NULL);
+ g_object_set (G_OBJECT (renderer), "ellipsize", PANGO_ELLIPSIZE_END, NULL);
+
+ gtk_tree_view_append_column (tree_view, column);
+
+ return tree_view;
+}
+
+static void
+ev_sidebar_layers_init (EvSidebarLayers *ev_layers)
+{
+ GtkWidget *swindow;
+ GtkTreeModel *model;
+
+ ev_layers->priv = EV_SIDEBAR_LAYERS_GET_PRIVATE (ev_layers);
+
+ swindow = gtk_scrolled_window_new (NULL, NULL);
+ gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
+ GTK_POLICY_NEVER,
+ GTK_POLICY_AUTOMATIC);
+ gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (swindow),
+ GTK_SHADOW_IN);
+ /* Data Model */
+ model = ev_sidebar_layers_create_loading_model ();
+
+ /* Layers list */
+ ev_layers->priv->tree_view = ev_sidebar_layers_create_tree_view (ev_layers);
+ gtk_tree_view_set_model (ev_layers->priv->tree_view, model);
+ g_object_unref (model);
+
+ gtk_container_add (GTK_CONTAINER (swindow),
+ GTK_WIDGET (ev_layers->priv->tree_view));
+
+ gtk_container_add (GTK_CONTAINER (ev_layers), swindow);
+ gtk_widget_show_all (GTK_WIDGET (ev_layers));
+}
+
+static void
+ev_sidebar_layers_class_init (EvSidebarLayersClass *ev_layers_class)
+{
+ GObjectClass *g_object_class = G_OBJECT_CLASS (ev_layers_class);
+
+ g_object_class->get_property = ev_sidebar_layers_get_property;
+ g_object_class->dispose = ev_sidebar_layers_dispose;
+
+ g_type_class_add_private (g_object_class, sizeof (EvSidebarLayersPrivate));
+
+ g_object_class_override_property (g_object_class, PROP_WIDGET, "main-widget");
+
+ signals[LAYERS_VISIBILITY_CHANGED] =
+ g_signal_new ("layers_visibility_changed",
+ G_TYPE_FROM_CLASS (g_object_class),
+ G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
+ G_STRUCT_OFFSET (EvSidebarLayersClass, layers_visibility_changed),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0, G_TYPE_NONE);
+}
+
+GtkWidget *
+ev_sidebar_layers_new (void)
+{
+ return GTK_WIDGET (g_object_new (EV_TYPE_SIDEBAR_LAYERS, NULL));
+}
+
+static void
+job_finished_callback (EvJobLayers *job,
+ EvSidebarLayers *sidebar_layers)
+{
+ EvSidebarLayersPrivate *priv;
+
+ priv = sidebar_layers->priv;
+
+ gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), job->model);
+
+ g_object_unref (job);
+ priv->job = NULL;
+}
+
+static void
+ev_sidebar_layers_set_document (EvSidebarPage *sidebar_page,
+ EvDocument *document)
+{
+ EvSidebarLayers *sidebar_layers;
+ EvSidebarLayersPrivate *priv;
+
+ g_return_if_fail (EV_IS_SIDEBAR_PAGE (sidebar_page));
+ g_return_if_fail (EV_IS_DOCUMENT (document));
+
+ sidebar_layers = EV_SIDEBAR_LAYERS (sidebar_page);
+
+ priv = sidebar_layers->priv;
+
+ if (priv->document) {
+ gtk_tree_view_set_model (GTK_TREE_VIEW (priv->tree_view), NULL);
+ g_object_unref (priv->document);
+ }
+
+ priv->document = g_object_ref (document);
+
+ if (priv->job) {
+ g_signal_handlers_disconnect_by_func (priv->job,
+ job_finished_callback,
+ sidebar_layers);
+ g_object_unref (priv->job);
+ }
+
+ priv->job = ev_job_layers_new (document);
+ g_signal_connect (priv->job, "finished",
+ G_CALLBACK (job_finished_callback),
+ sidebar_layers);
+ /* The priority doesn't matter for this job */
+ ev_job_scheduler_push_job (priv->job, EV_JOB_PRIORITY_NONE);
+}
+
+static gboolean
+ev_sidebar_layers_support_document (EvSidebarPage *sidebar_page,
+ EvDocument *document)
+{
+ return (EV_IS_DOCUMENT_LAYERS (document) &&
+ ev_document_layers_has_layers (EV_DOCUMENT_LAYERS (document)));
+}
+
+static const gchar*
+ev_sidebar_layers_get_label (EvSidebarPage *sidebar_page)
+{
+ return _("Layers");
+}
+
+static void
+ev_sidebar_layers_page_iface_init (EvSidebarPageIface *iface)
+{
+ iface->support_document = ev_sidebar_layers_support_document;
+ iface->set_document = ev_sidebar_layers_set_document;
+ iface->get_label = ev_sidebar_layers_get_label;
+}
+
diff --git a/shell/ev-sidebar-layers.h b/shell/ev-sidebar-layers.h
new file mode 100644
index 0000000..f974d79
--- /dev/null
+++ b/shell/ev-sidebar-layers.h
@@ -0,0 +1,58 @@
+/* ev-sidebar-layers.h
+ * this file is part of evince, a gnome document viewer
+ *
+ * Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
+ *
+ * Evince 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 of the License, or
+ * (at your option) any later version.
+ *
+ * Evince 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __EV_SIDEBAR_LAYERS_H__
+#define __EV_SIDEBAR_LAYERS_H__
+
+#include <gtk/gtk.h>
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _EvSidebarLayers EvSidebarLayers;
+typedef struct _EvSidebarLayersClass EvSidebarLayersClass;
+typedef struct _EvSidebarLayersPrivate EvSidebarLayersPrivate;
+
+#define EV_TYPE_SIDEBAR_LAYERS (ev_sidebar_layers_get_type())
+#define EV_SIDEBAR_LAYERS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_SIDEBAR_LAYERS, EvSidebarLayers))
+#define EV_SIDEBAR_LAYERS_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_SIDEBAR_LAYERS, EvSidebarLayersClass))
+#define EV_IS_SIDEBAR_LAYERS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_SIDEBAR_LAYERS))
+#define EV_IS_SIDEBAR_LAYERS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), EV_TYPE_SIDEBAR_LAYERS))
+#define EV_SIDEBAR_LAYERS_GET_CLASS(object) (G_TYPE_INSTANCE_GET_CLASS((object), EV_TYPE_SIDEBAR_LAYERS, EvSidebarLayersClass))
+
+struct _EvSidebarLayers {
+ GtkVBox base_instance;
+
+ EvSidebarLayersPrivate *priv;
+};
+
+struct _EvSidebarLayersClass {
+ GtkVBoxClass base_class;
+
+ /* Signals */
+ void (* layers_visibility_changed) (EvSidebarLayers *ev_layers);
+};
+
+GType ev_sidebar_layers_get_type (void) G_GNUC_CONST;
+GtkWidget *ev_sidebar_layers_new (void);
+
+G_END_DECLS
+
+#endif /* __EV_SIDEBAR_LAYERS_H__ */
diff --git a/shell/ev-view.c b/shell/ev-view.c
index 41efa33..9c575d2 100644
--- a/shell/ev-view.c
+++ b/shell/ev-view.c
@@ -220,6 +220,9 @@ static void draw_one_page (EvView
static void draw_loading_text (EvView *view,
GdkRectangle *page_area,
GdkRectangle *expose_area);
+static void ev_view_reload_page (EvView *view,
+ gint page,
+ GdkRegion *region);
/*** Callbacks ***/
static void job_finished_cb (EvPixbufCache *pixbuf_cache,
@@ -1703,11 +1706,7 @@ ev_view_form_field_button_create_widget (EvView *view,
break;
}
- ev_pixbuf_cache_reload_page (view->pixbuf_cache,
- field_region,
- field->page->index,
- view->rotation,
- view->scale);
+ ev_view_reload_page (view, field->page->index, field_region);
gdk_region_destroy (field_region);
return NULL;
@@ -1733,11 +1732,7 @@ ev_view_form_field_text_save (EvView *view,
ev_document_forms_form_field_text_set_text (EV_DOCUMENT_FORMS (view->document),
field, field_text->text);
field->changed = FALSE;
- ev_pixbuf_cache_reload_page (view->pixbuf_cache,
- field_region,
- field->page->index,
- view->rotation,
- view->scale);
+ ev_view_reload_page (view, field->page->index, field_region);
gdk_region_destroy (field_region);
}
}
@@ -1854,11 +1849,7 @@ ev_view_form_field_choice_save (EvView *view,
}
}
field->changed = FALSE;
- ev_pixbuf_cache_reload_page (view->pixbuf_cache,
- field_region,
- field->page->index,
- view->rotation,
- view->scale);
+ ev_view_reload_page (view, field->page->index, field_region);
gdk_region_destroy (field_region);
}
}
@@ -4471,6 +4462,25 @@ ev_view_set_document (EvView *view,
}
}
+static void
+ev_view_reload_page (EvView *view,
+ gint page,
+ GdkRegion *region)
+{
+ ev_pixbuf_cache_reload_page (view->pixbuf_cache,
+ region,
+ page,
+ view->rotation,
+ view->scale);
+}
+
+void
+ev_view_reload (EvView *view)
+{
+ ev_pixbuf_cache_clear (view->pixbuf_cache);
+ view_update_range_and_current_page (view);
+}
+
/*** Zoom and sizing mode ***/
#define EPSILON 0.0000001
@@ -5871,7 +5881,7 @@ ev_view_previous_page (EvView *view)
return FALSE;
}
}
-
+
/*** Enum description for usage in signal ***/
GType
diff --git a/shell/ev-view.h b/shell/ev-view.h
index 424cecc..d41edd1 100644
--- a/shell/ev-view.h
+++ b/shell/ev-view.h
@@ -58,6 +58,8 @@ void ev_view_set_document (EvView *view,
EvDocument *document);
void ev_view_set_loading (EvView *view,
gboolean loading);
+void ev_view_reload (EvView *view);
+
/* Clipboard */
void ev_view_copy (EvView *view);
void ev_view_copy_link_address (EvView *view,
diff --git a/shell/ev-window.c b/shell/ev-window.c
index 2e2e1bc..ef96dce 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -81,6 +81,7 @@
#include "ev-sidebar-links.h"
#include "ev-sidebar-page.h"
#include "ev-sidebar-thumbnails.h"
+#include "ev-sidebar-layers.h"
#include "ev-stock-icons.h"
#include "ev-utils.h"
#include "ev-view.h"
@@ -129,6 +130,7 @@ struct _EvWindowPrivate {
GtkWidget *sidebar_thumbs;
GtkWidget *sidebar_links;
GtkWidget *sidebar_attachments;
+ GtkWidget *sidebar_layers;
/* Dialogs */
GtkWidget *properties;
@@ -211,6 +213,7 @@ struct _EvWindowPrivate {
#define LINKS_SIDEBAR_ID "links"
#define THUMBNAILS_SIDEBAR_ID "thumbnails"
#define ATTACHMENTS_SIDEBAR_ID "attachments"
+#define LAYERS_SIDEBAR_ID "layers"
static const gchar *document_print_settings[] = {
GTK_PRINT_SETTINGS_N_COPIES,
@@ -906,6 +909,7 @@ setup_sidebar_from_metadata (EvWindow *window, EvDocument *document)
GtkWidget *links = window->priv->sidebar_links;
GtkWidget *thumbs = window->priv->sidebar_thumbs;
GtkWidget *attachments = window->priv->sidebar_attachments;
+ GtkWidget *layers = window->priv->sidebar_layers;
GValue sidebar_size = { 0, };
GValue sidebar_page = { 0, };
GValue sidebar_visibility = { 0, };
@@ -916,19 +920,29 @@ setup_sidebar_from_metadata (EvWindow *window, EvDocument *document)
g_value_unset(&sidebar_size);
}
- if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, FALSE)) {
+ if (document && ev_metadata_manager_get (uri, "sidebar_page", &sidebar_page, TRUE)) {
const char *page_id = g_value_get_string (&sidebar_page);
-
+
if (strcmp (page_id, LINKS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
ev_sidebar_set_page (EV_SIDEBAR (sidebar), links);
- } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) {
+ } else if (strcmp (page_id, THUMBNAILS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) {
ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs);
- } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
+ } else if (strcmp (page_id, ATTACHMENTS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments);
+ } else if (strcmp (page_id, LAYERS_SIDEBAR_ID) == 0 && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) {
+ ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers);
}
g_value_unset (&sidebar_page);
- } else if (document && ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
- ev_sidebar_set_page (EV_SIDEBAR (sidebar), links);
+ } else if (document) {
+ if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (links), document)) {
+ ev_sidebar_set_page (EV_SIDEBAR (sidebar), links);
+ } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (thumbs), document)) {
+ ev_sidebar_set_page (EV_SIDEBAR (sidebar), thumbs);
+ } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (attachments), document)) {
+ ev_sidebar_set_page (EV_SIDEBAR (sidebar), attachments);
+ } else if (ev_sidebar_page_support_document (EV_SIDEBAR_PAGE (layers), document)) {
+ ev_sidebar_set_page (EV_SIDEBAR (sidebar), layers);
+ }
}
if (ev_metadata_manager_get (uri, "sidebar_visibility", &sidebar_visibility, FALSE)) {
@@ -3819,6 +3833,8 @@ ev_window_sidebar_current_page_changed_cb (EvSidebar *ev_sidebar,
id = THUMBNAILS_SIDEBAR_ID;
} else if (current_page == ev_window->priv->sidebar_attachments) {
id = ATTACHMENTS_SIDEBAR_ID;
+ } else if (current_page == ev_window->priv->sidebar_layers) {
+ id = LAYERS_SIDEBAR_ID;
} else {
g_assert_not_reached();
}
@@ -4593,6 +4609,13 @@ navigation_action_activate_link_cb (EvNavigationAction *action, EvLink *link, Ev
}
static void
+sidebar_layers_visibility_changed (EvSidebarLayers *layers,
+ EvWindow *window)
+{
+ ev_view_reload (EV_VIEW (window->priv->view));
+}
+
+static void
register_custom_actions (EvWindow *window, GtkActionGroup *group)
{
GtkAction *action;
@@ -5493,6 +5516,16 @@ ev_window_init (EvWindow *ev_window)
ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
sidebar_widget);
+ sidebar_widget = ev_sidebar_layers_new ();
+ ev_window->priv->sidebar_layers = sidebar_widget;
+ g_signal_connect (sidebar_widget,
+ "layers_visibility_changed",
+ G_CALLBACK (sidebar_layers_visibility_changed),
+ ev_window);
+ gtk_widget_show (sidebar_widget);
+ ev_sidebar_add_page (EV_SIDEBAR (ev_window->priv->sidebar),
+ sidebar_widget);
+
ev_window->priv->view_box = gtk_vbox_new (FALSE, 0);
ev_window->priv->scrolled_window =
GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW,