[evince/wip/bug654832: 16/16] libview: Add API to load from streams and gfile



commit ae06cf30c03ca7e088159fa6abd68aa146888b1e
Author: Christian Persch <chpe gnome org>
Date:   Sun May 13 20:49:51 2012 +0200

    libview: Add API to load from streams and gfile
    
    Add EvJobLoadStream and EvJobLoadGFile to load documents from
    GInputStream and GFile.
    
    Bug #654832.

 help/reference/libview/libevview-sections.txt |   22 ++
 libview/ev-jobs.c                             |  316 +++++++++++++++++++++++++
 libview/ev-jobs.h                             |   64 +++++
 3 files changed, 402 insertions(+), 0 deletions(-)
---
diff --git a/help/reference/libview/libevview-sections.txt b/help/reference/libview/libevview-sections.txt
index fe50b2e..4e6794b 100644
--- a/help/reference/libview/libevview-sections.txt
+++ b/help/reference/libview/libevview-sections.txt
@@ -141,6 +141,10 @@ EvJobFonts
 EvJobFontsClass
 EvJobLoad
 EvJobLoadClass
+EvJobLoadStream
+EvJobLoadStreamClass
+EvJobLoadGFile
+EvJobLoadGFileClass
 EvJobSave
 EvJobSaveClass
 EvJobFind
@@ -174,6 +178,14 @@ ev_job_fonts_new
 ev_job_load_new
 ev_job_load_set_uri
 ev_job_load_set_password
+ev_job_load_stream_new
+ev_job_load_stream_set_stream
+ev_job_load_stream_set_load_flags
+ev_job_load_stream_set_password
+ev_job_load_gfile_new
+ev_job_load_gfile_set_gfile
+ev_job_load_gfile_set_load_flags
+ev_job_load_gfile_set_password
 ev_job_save_new
 ev_job_find_new
 ev_job_find_get_n_results
@@ -232,6 +244,16 @@ ev_job_load_get_type
 EV_JOB_LOAD
 EV_JOB_LOAD_CLASS
 EV_IS_JOB_LOAD
+EV_TYPE_JOB_LOAD_STREAM
+ev_job_load_stream_get_type
+EV_JOB_LOAD_STREAM
+EV_JOB_LOAD_STREAM_CLASS
+EV_IS_JOB_LOAD_STREAM
+EV_TYPE_JOB_LOAD_GFILE
+ev_job_load_gfile_get_type
+EV_JOB_LOAD_GFILE
+EV_JOB_LOAD_GFILE_CLASS
+EV_IS_JOB_LOAD_GFILE
 EV_TYPE_JOB_SAVE
 ev_job_save_get_type
 EV_JOB_SAVE
diff --git a/libview/ev-jobs.c b/libview/ev-jobs.c
index 23ee586..5064a98 100644
--- a/libview/ev-jobs.c
+++ b/libview/ev-jobs.c
@@ -99,6 +99,8 @@ G_DEFINE_TYPE (EvJobPageData, ev_job_page_data, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobLoadStream, ev_job_load_stream, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobLoadGFile, ev_job_load_gfile, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobFind, ev_job_find, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobLayers, ev_job_layers, EV_TYPE_JOB)
@@ -1048,6 +1050,320 @@ ev_job_load_set_password (EvJobLoad *job, const gchar *password)
 	job->password = password ? g_strdup (password) : NULL;
 }
 
+/* EvJobLoadStream */
+
+/**
+ * EvJobLoadStream:
+ *
+ * A job class to load a #EvDocument from a #GInputStream.
+ *
+ * Since: 3.6
+ */
+
+struct _EvJobLoadStreamPrivate {
+        char *password;
+        GInputStream *stream;
+        EvDocumentLoadFlags flags;
+};
+
+static void
+ev_job_load_stream_init (EvJobLoadStream *job)
+{
+        EvJobLoadStreamPrivate *priv;
+
+        priv = job->priv = G_TYPE_INSTANCE_GET_PRIVATE (job, EV_TYPE_JOB_LOAD_STREAM, EvJobLoadStreamPrivate);
+
+        priv->flags = EV_DOCUMENT_LOAD_FLAG_NONE;
+
+        EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
+
+static void
+ev_job_load_stream_dispose (GObject *object)
+{
+        EvJobLoadStream *job = EV_JOB_LOAD_STREAM (object);
+        EvJobLoadStreamPrivate *priv = job->priv;
+
+        if (priv->stream) {
+                g_object_unref (priv->stream);
+                priv->stream = NULL;
+        }
+
+        g_free (priv->password);
+        priv->password = NULL;
+
+        G_OBJECT_CLASS (ev_job_load_stream_parent_class)->dispose (object);
+}
+
+static gboolean
+ev_job_load_stream_run (EvJob *job)
+{
+        EvJobLoadStream *job_load_stream = EV_JOB_LOAD_STREAM (job);
+        EvJobLoadStreamPrivate *priv = job_load_stream->priv;
+        GError    *error = NULL;
+
+        ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+        ev_document_fc_mutex_lock ();
+
+        /* This job may already have a document even if the job didn't complete
+           because, e.g., a password is required - if so, just reload_stream rather than
+           creating a new instance */
+        /* FIXME: do we need to rewind the stream here?? */
+        if (job->document) {
+
+                if (priv->password) {
+                        ev_document_security_set_password (EV_DOCUMENT_SECURITY (job->document),
+                                                           priv->password);
+                }
+
+                job->failed = FALSE;
+                job->finished = FALSE;
+                g_clear_error (&job->error);
+
+                ev_document_load_stream_sync (job->document,
+                                              priv->stream,
+                                              priv->flags,
+                                              job->cancellable,
+                                              &error);
+        } else {
+                job->document = ev_document_factory_get_document_for_stream (priv->stream,
+                                                                             NULL /* mime-type FIXME? */,
+                                                                             priv->flags,
+                                                                             job->cancellable,
+                                                                             &error);
+        }
+
+        ev_document_fc_mutex_unlock ();
+
+        if (error) {
+                ev_job_failed_from_error (job, error);
+                g_error_free (error);
+        } else {
+                ev_job_succeeded (job);
+        }
+
+        return FALSE;
+}
+
+static void
+ev_job_load_stream_class_init (EvJobLoadStreamClass *class)
+{
+        GObjectClass *oclass = G_OBJECT_CLASS (class);
+        EvJobClass   *job_class = EV_JOB_CLASS (class);
+
+        oclass->dispose = ev_job_load_stream_dispose;
+        job_class->run = ev_job_load_stream_run;
+
+        g_type_class_add_private (class, sizeof (EvJobLoadStreamPrivate));
+}
+
+EvJob *
+ev_job_load_stream_new (GInputStream       *stream,
+                        EvDocumentLoadFlags flags)
+{
+        EvJobLoadStream *job;
+
+        job = g_object_new (EV_TYPE_JOB_LOAD_STREAM, NULL);
+        ev_job_load_stream_set_stream (job, stream);
+        ev_job_load_stream_set_load_flags (job, flags);
+
+        return EV_JOB (job);
+}
+
+void
+ev_job_load_stream_set_stream (EvJobLoadStream *job,
+                               GInputStream    *stream)
+{
+        g_return_if_fail (EV_IS_JOB_LOAD_STREAM (job));
+        g_return_if_fail (G_IS_INPUT_STREAM (stream));
+
+        g_object_ref (stream);
+        if (job->priv->stream)
+              g_object_unref (job->priv->stream);
+        job->priv->stream = stream;
+}
+
+void
+ev_job_load_stream_set_load_flags (EvJobLoadStream    *job,
+                                   EvDocumentLoadFlags flags)
+{
+        g_return_if_fail (EV_IS_JOB_LOAD_STREAM (job));
+
+        job->priv->flags = flags;
+}
+
+void
+ev_job_load_stream_set_password (EvJobLoadStream *job, 
+                                 const char *password)
+{
+        char *old_password;
+
+        ev_debug_message (DEBUG_JOBS, NULL);
+
+        g_return_if_fail (EV_IS_JOB_LOAD_STREAM (job));
+
+        old_password = job->priv->password;
+        job->priv->password = g_strdup (password);
+        g_free (old_password);
+}
+
+/* EvJobLoadGFile */
+
+/**
+ * EvJobLoadGFile:
+ *
+ * A job class to load a #EvDocument from a #GFile.
+ *
+ * Since: 3.6
+ */
+
+struct _EvJobLoadGFilePrivate {
+        char *password;
+        GFile *gfile;
+        EvDocumentLoadFlags flags;
+};
+
+static void
+ev_job_load_gfile_init (EvJobLoadGFile *job)
+{
+        EvJobLoadGFilePrivate *priv;
+
+        priv = job->priv = G_TYPE_INSTANCE_GET_PRIVATE (job, EV_TYPE_JOB_LOAD_GFILE, EvJobLoadGFilePrivate);
+
+        priv->flags = EV_DOCUMENT_LOAD_FLAG_NONE;
+
+        EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
+
+static void
+ev_job_load_gfile_dispose (GObject *object)
+{
+        EvJobLoadGFile *job = EV_JOB_LOAD_GFILE (object);
+        EvJobLoadGFilePrivate *priv = job->priv;
+
+        if (priv->gfile) {
+                g_object_unref (priv->gfile);
+                priv->gfile = NULL;
+        }
+
+        g_free (priv->password);
+        priv->password = NULL;
+
+        G_OBJECT_CLASS (ev_job_load_gfile_parent_class)->dispose (object);
+}
+
+static gboolean
+ev_job_load_gfile_run (EvJob *job)
+{
+        EvJobLoadGFile *job_load_gfile = EV_JOB_LOAD_GFILE (job);
+        EvJobLoadGFilePrivate *priv = job_load_gfile->priv;
+        GError    *error = NULL;
+
+        ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
+
+        ev_document_fc_mutex_lock ();
+
+        /* This job may already have a document even if the job didn't complete
+           because, e.g., a password is required - if so, just reload_gfile rather than
+           creating a new instance */
+        if (job->document) {
+
+                if (priv->password) {
+                        ev_document_security_set_password (EV_DOCUMENT_SECURITY (job->document),
+                                                           priv->password);
+                }
+
+                job->failed = FALSE;
+                job->finished = FALSE;
+                g_clear_error (&job->error);
+
+                ev_document_load_gfile_sync (job->document,
+                                             priv->gfile,
+                                             priv->flags,
+                                             job->cancellable,
+                                             &error);
+        } else {
+                job->document = ev_document_factory_get_document_for_gfile (priv->gfile,
+                                                                            priv->flags,
+                                                                            job->cancellable,
+                                                                            &error);
+        }
+
+        ev_document_fc_mutex_unlock ();
+
+        if (error) {
+                ev_job_failed_from_error (job, error);
+                g_error_free (error);
+        } else {
+                ev_job_succeeded (job);
+        }
+
+        return FALSE;
+}
+
+static void
+ev_job_load_gfile_class_init (EvJobLoadGFileClass *class)
+{
+        GObjectClass *oclass = G_OBJECT_CLASS (class);
+        EvJobClass   *job_class = EV_JOB_CLASS (class);
+
+        oclass->dispose = ev_job_load_gfile_dispose;
+        job_class->run = ev_job_load_gfile_run;
+
+        g_type_class_add_private (class, sizeof (EvJobLoadGFilePrivate));
+}
+
+EvJob *
+ev_job_load_gfile_new (GFile              *gfile,
+                       EvDocumentLoadFlags flags)
+{
+        EvJobLoadGFile *job;
+
+        job = g_object_new (EV_TYPE_JOB_LOAD_GFILE, NULL);
+        ev_job_load_gfile_set_gfile (job, gfile);
+        ev_job_load_gfile_set_load_flags (job, flags);
+
+        return EV_JOB (job);
+}
+
+void
+ev_job_load_gfile_set_gfile (EvJobLoadGFile *job,
+                             GFile          *gfile)
+{
+        g_return_if_fail (EV_IS_JOB_LOAD_GFILE (job));
+        g_return_if_fail (G_IS_FILE (gfile));
+
+        g_object_ref (gfile);
+        if (job->priv->gfile)
+              g_object_unref (job->priv->gfile);
+        job->priv->gfile = gfile;
+}
+
+void
+ev_job_load_gfile_set_load_flags (EvJobLoadGFile     *job,
+                                  EvDocumentLoadFlags flags)
+{
+        g_return_if_fail (EV_IS_JOB_LOAD_GFILE (job));
+
+        job->priv->flags = flags;
+}
+
+void
+ev_job_load_gfile_set_password (EvJobLoadGFile *job,
+                                const char *password)
+{
+        char *old_password;
+
+        ev_debug_message (DEBUG_JOBS, NULL);
+
+        g_return_if_fail (EV_IS_JOB_LOAD_GFILE (job));
+
+        old_password = job->priv->password;
+        job->priv->password = g_strdup (password);
+        g_free (old_password);
+}
+
 /* EvJobSave */
 static void
 ev_job_save_init (EvJobSave *job)
diff --git a/libview/ev-jobs.h b/libview/ev-jobs.h
index 7596d76..9f2f8ff 100644
--- a/libview/ev-jobs.h
+++ b/libview/ev-jobs.h
@@ -60,6 +60,14 @@ typedef struct _EvJobFontsClass EvJobFontsClass;
 typedef struct _EvJobLoad EvJobLoad;
 typedef struct _EvJobLoadClass EvJobLoadClass;
 
+typedef struct _EvJobLoadStream EvJobLoadStream;
+typedef struct _EvJobLoadStreamPrivate EvJobLoadStreamPrivate;
+typedef struct _EvJobLoadStreamClass EvJobLoadStreamClass;
+
+typedef struct _EvJobLoadGFile EvJobLoadGFile;
+typedef struct _EvJobLoadGFilePrivate EvJobLoadGFilePrivate;
+typedef struct _EvJobLoadGFileClass EvJobLoadGFileClass;
+
 typedef struct _EvJobSave EvJobSave;
 typedef struct _EvJobSaveClass EvJobSaveClass;
 
@@ -121,6 +129,16 @@ typedef struct _EvJobPrintClass EvJobPrintClass;
 #define EV_JOB_LOAD_CLASS(klass)	     (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_LOAD, EvJobLoadClass))
 #define EV_IS_JOB_LOAD(object)		     (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_LOAD))
 
+#define EV_TYPE_JOB_LOAD_STREAM                     (ev_job_load_stream_get_type())
+#define EV_JOB_LOAD_STREAM(object)                  (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_LOAD_STREAM, EvJobLoadStream))
+#define EV_JOB_LOAD_STREAM_CLASS(klass)             (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_LOAD_STREAM, EvJobLoadStreamClass))
+#define EV_IS_JOB_LOAD_STREAM(object)               (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_LOAD_STREAM))
+
+#define EV_TYPE_JOB_LOAD_GFILE                     (ev_job_load_gfile_get_type())
+#define EV_JOB_LOAD_GFILE(object)                  (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_LOAD_GFILE, EvJobLoadGFile))
+#define EV_JOB_LOAD_GFILE_CLASS(klass)             (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_LOAD_GFILE, EvJobLoadGFileClass))
+#define EV_IS_JOB_LOAD_GFILE(object)               (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_LOAD_GFILE))
+
 #define EV_TYPE_JOB_SAVE		     (ev_job_save_get_type())
 #define EV_JOB_SAVE(object)	     	     (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_SAVE, EvJobSave))
 #define EV_JOB_SAVE_CLASS(klass)	     (G_TYPE_CHECK_CLASS_CAST((klass), EV_TYPE_JOB_SAVE, EvJobSaveClass))
@@ -322,6 +340,30 @@ struct _EvJobLoadClass
 	EvJobClass parent_class;
 };
 
+struct _EvJobLoadStream
+{
+        EvJob parent;
+
+        EvJobLoadStreamPrivate *priv;
+};
+
+struct _EvJobLoadStreamClass
+{
+        EvJobClass parent_class;
+};
+
+struct _EvJobLoadGFile
+{
+        EvJob parent;
+
+        EvJobLoadGFilePrivate *priv;
+};
+
+struct _EvJobLoadGFileClass
+{
+        EvJobClass parent_class;
+};
+
 struct _EvJobSave
 {
 	EvJob parent;
@@ -462,6 +504,28 @@ void            ev_job_load_set_uri       (EvJobLoad       *load,
 void            ev_job_load_set_password  (EvJobLoad       *job,
 					   const gchar     *password);
 
+/* EvJobLoadStream */
+GType           ev_job_load_stream_get_type       (void) G_GNUC_CONST;
+EvJob          *ev_job_load_stream_new            (GInputStream       *stream,
+                                                   EvDocumentLoadFlags flags);
+void            ev_job_load_stream_set_stream     (EvJobLoadStream    *job,
+                                                   GInputStream       *stream);
+void            ev_job_load_stream_set_load_flags (EvJobLoadStream    *job,
+                                                   EvDocumentLoadFlags flags);
+void            ev_job_load_stream_set_password   (EvJobLoadStream    *job,
+                                                   const gchar        *password);
+
+/* EvJobLoadGFile */
+GType           ev_job_load_gfile_get_type        (void) G_GNUC_CONST;
+EvJob          *ev_job_load_gfile_new             (GFile              *gfile,
+                                                   EvDocumentLoadFlags flags);
+void            ev_job_load_gfile_set_gfile       (EvJobLoadGFile     *job,
+                                                   GFile              *gfile);
+void            ev_job_load_gfile_set_load_flags  (EvJobLoadGFile     *job,
+                                                   EvDocumentLoadFlags flags);
+void            ev_job_load_gfile_set_password    (EvJobLoadGFile     *job,
+                                                   const gchar        *password);
+
 /* EvJobSave */
 GType           ev_job_save_get_type      (void) G_GNUC_CONST;
 EvJob          *ev_job_save_new           (EvDocument      *document,



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]