]> www.fi.muni.cz Git - evince.git/blobdiff - libview/ev-jobs.c
[dualscreen] fix crash on ctrl+w and fix control window closing
[evince.git] / libview / ev-jobs.c
index df15f6db865ce0fa489905019abf982b38190b43..816a56bbb3c7987351291af6d82f778eb0c41243 100644 (file)
  *
  * 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.
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  */
 
 #include <config.h>
 
 #include "ev-jobs.h"
-#include "ev-document-thumbnails.h"
 #include "ev-document-links.h"
 #include "ev-document-images.h"
 #include "ev-document-forms.h"
@@ -36,6 +35,7 @@
 #include "ev-document-print.h"
 #include "ev-document-annotations.h"
 #include "ev-document-attachments.h"
+#include "ev-document-text.h"
 #include "ev-debug.h"
 
 #include <errno.h>
@@ -49,6 +49,8 @@ static void ev_job_links_init             (EvJobLinks            *job);
 static void ev_job_links_class_init       (EvJobLinksClass       *class);
 static void ev_job_attachments_init       (EvJobAttachments      *job);
 static void ev_job_attachments_class_init (EvJobAttachmentsClass *class);
+static void ev_job_annots_init            (EvJobAnnots           *job);
+static void ev_job_annots_class_init      (EvJobAnnotsClass      *class);
 static void ev_job_render_init            (EvJobRender           *job);
 static void ev_job_render_class_init      (EvJobRenderClass      *class);
 static void ev_job_page_data_init         (EvJobPageData         *job);
@@ -91,6 +93,7 @@ static guint job_find_signals[FIND_LAST_SIGNAL] = { 0 };
 G_DEFINE_ABSTRACT_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
 G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobAttachments, ev_job_attachments, EV_TYPE_JOB)
+G_DEFINE_TYPE (EvJobAnnots, ev_job_annots, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobPageData, ev_job_page_data, EV_TYPE_JOB)
 G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
@@ -213,7 +216,7 @@ ev_job_run (EvJob *job)
 void
 ev_job_cancel (EvJob *job)
 {
-       if (job->cancelled || (job->finished && job->idle_finished_id == 0))
+       if (job->cancelled)
                return;
 
        ev_debug_message (DEBUG_JOBS, "job %s (%p) cancelled", EV_GET_TYPE_NAME (job), job);
@@ -222,6 +225,10 @@ ev_job_cancel (EvJob *job)
        /* This should never be called from a thread */
        job->cancelled = TRUE;
        g_cancellable_cancel (job->cancellable);
+
+        if (job->finished && job->idle_finished_id == 0)
+                return;
+
        g_signal_emit (job, job_signals[CANCELLED], 0);
 }
 
@@ -328,6 +335,38 @@ ev_job_links_dispose (GObject *object)
        (* G_OBJECT_CLASS (ev_job_links_parent_class)->dispose) (object);
 }
 
+static gboolean
+fill_page_labels (GtkTreeModel   *tree_model,
+                 GtkTreePath    *path,
+                 GtkTreeIter    *iter,
+                 EvJob          *job)
+{
+       EvDocumentLinks *document_links;
+       EvLink          *link;
+       gchar           *page_label;
+
+       gtk_tree_model_get (tree_model, iter,
+                           EV_DOCUMENT_LINKS_COLUMN_LINK, &link,
+                           -1);
+
+       if (!link)
+               return FALSE;
+
+       document_links = EV_DOCUMENT_LINKS (job->document);
+       page_label = ev_document_links_get_link_page_label (document_links, link);
+       if (!page_label)
+               return FALSE;
+
+       gtk_tree_store_set (GTK_TREE_STORE (tree_model), iter,
+                           EV_DOCUMENT_LINKS_COLUMN_PAGE_LABEL, page_label,
+                           -1);
+
+       g_free (page_label);
+       g_object_unref (link);
+
+       return FALSE;
+}
+
 static gboolean
 ev_job_links_run (EvJob *job)
 {
@@ -339,7 +378,9 @@ ev_job_links_run (EvJob *job)
        ev_document_doc_mutex_lock ();
        job_links->model = ev_document_links_get_links_model (EV_DOCUMENT_LINKS (job->document));
        ev_document_doc_mutex_unlock ();
-       
+
+       gtk_tree_model_foreach (job_links->model, (GtkTreeModelForeachFunc)fill_page_labels, job);
+
        ev_job_succeeded (job);
        
        return FALSE;
@@ -434,6 +475,85 @@ ev_job_attachments_new (EvDocument *document)
        return job;
 }
 
+/* EvJobAnnots */
+static void
+ev_job_annots_init (EvJobAnnots *job)
+{
+       EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
+}
+
+static void
+ev_job_annots_dispose (GObject *object)
+{
+       EvJobAnnots *job;
+
+       ev_debug_message (DEBUG_JOBS, NULL);
+
+       job = EV_JOB_ANNOTS (object);
+
+       if (job->annots) {
+               g_list_foreach (job->annots, (GFunc)ev_mapping_list_unref, NULL);
+               g_list_free (job->annots);
+               job->annots = NULL;
+       }
+
+       G_OBJECT_CLASS (ev_job_annots_parent_class)->dispose (object);
+}
+
+static gboolean
+ev_job_annots_run (EvJob *job)
+{
+       EvJobAnnots *job_annots = EV_JOB_ANNOTS (job);
+       gint         i;
+
+       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 ();
+       for (i = 0; i < ev_document_get_n_pages (job->document); i++) {
+               EvMappingList *mapping_list;
+               EvPage        *page;
+
+               page = ev_document_get_page (job->document, i);
+               mapping_list = ev_document_annotations_get_annotations (EV_DOCUMENT_ANNOTATIONS (job->document),
+                                                                       page);
+               g_object_unref (page);
+
+               if (mapping_list)
+                       job_annots->annots = g_list_prepend (job_annots->annots, mapping_list);
+       }
+       ev_document_doc_mutex_unlock ();
+
+       job_annots->annots = g_list_reverse (job_annots->annots);
+
+       ev_job_succeeded (job);
+
+       return FALSE;
+}
+
+static void
+ev_job_annots_class_init (EvJobAnnotsClass *class)
+{
+       GObjectClass *oclass = G_OBJECT_CLASS (class);
+       EvJobClass   *job_class = EV_JOB_CLASS (class);
+
+       oclass->dispose = ev_job_annots_dispose;
+       job_class->run = ev_job_annots_run;
+}
+
+EvJob *
+ev_job_annots_new (EvDocument *document)
+{
+       EvJob *job;
+
+       ev_debug_message (DEBUG_JOBS, NULL);
+
+       job = g_object_new (EV_TYPE_JOB_ANNOTS, NULL);
+       job->document = g_object_ref (document);
+
+       return job;
+}
+
 /* EvJobRender */
 static void
 ev_job_render_init (EvJobRender *job)
@@ -461,7 +581,7 @@ ev_job_render_dispose (GObject *object)
        }
 
        if (job->selection_region) {
-               gdk_region_destroy (job->selection_region);
+               cairo_region_destroy (job->selection_region);
                job->selection_region = NULL;
        }
 
@@ -593,12 +713,20 @@ ev_job_page_data_run (EvJob *job)
        ev_document_doc_mutex_lock ();
        ev_page = ev_document_get_page (job->document, job_pd->page);
 
-       if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_TEXT) && EV_IS_SELECTION (job->document))
+       if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_TEXT_MAPPING) && EV_IS_DOCUMENT_TEXT (job->document))
                job_pd->text_mapping =
-                       ev_selection_get_selection_map (EV_SELECTION (job->document), ev_page);
+                       ev_document_text_get_text_mapping (EV_DOCUMENT_TEXT (job->document), ev_page);
+       if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_TEXT) && EV_IS_DOCUMENT_TEXT (job->document))
+               job_pd->text =
+                       ev_document_text_get_text (EV_DOCUMENT_TEXT (job->document), ev_page);
+       if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_TEXT_LAYOUT) && EV_IS_DOCUMENT_TEXT (job->document))
+               ev_document_text_get_text_layout (EV_DOCUMENT_TEXT (job->document),
+                                                 ev_page,
+                                                 &(job_pd->text_layout),
+                                                 &(job_pd->text_layout_length));
        if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (job->document))
                job_pd->link_mapping =
-                       ev_document_links_get_links (EV_DOCUMENT_LINKS (job->document), job_pd->page);
+                       ev_document_links_get_links (EV_DOCUMENT_LINKS (job->document), ev_page);
        if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (job->document))
                job_pd->form_field_mapping =
                        ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (job->document),
@@ -606,7 +734,7 @@ ev_job_page_data_run (EvJob *job)
        if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (job->document))
                job_pd->image_mapping =
                        ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (job->document),
-                                                             job_pd->page);
+                                                             ev_page);
        if ((job_pd->flags & EV_PAGE_DATA_INCLUDE_ANNOTS) && EV_IS_DOCUMENT_ANNOTATIONS (job->document))
                job_pd->annot_mapping =
                        ev_document_annotations_get_annotations (EV_DOCUMENT_ANNOTATIONS (job->document),
@@ -674,6 +802,7 @@ ev_job_thumbnail_run (EvJob *job)
 {
        EvJobThumbnail  *job_thumb = EV_JOB_THUMBNAIL (job);
        EvRenderContext *rc;
+       GdkPixbuf       *pixbuf;
        EvPage          *page;
 
        ev_debug_message (DEBUG_JOBS, "%d (%p)", job_thumb->page, job);
@@ -685,11 +814,14 @@ ev_job_thumbnail_run (EvJob *job)
        rc = ev_render_context_new (page, job_thumb->rotation, job_thumb->scale);
        g_object_unref (page);
 
-       job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (job->document),
-                                                                    rc, TRUE);
+       pixbuf = ev_document_get_thumbnail (job->document, rc);
        g_object_unref (rc);
        ev_document_doc_mutex_unlock ();
 
+       if (pixbuf)
+               job_thumb->thumbnail = ev_document_misc_get_thumbnail_frame (-1, -1, pixbuf);
+       g_object_unref (pixbuf);
+
        ev_job_succeeded (job);
        
        return FALSE;
@@ -840,6 +972,8 @@ ev_job_load_run (EvJob *job)
           because, e.g., a password is required - if so, just reload rather than
           creating a new instance */
        if (job->document) {
+               const gchar *uncompressed_uri;
+
                if (job_load->password) {
                        ev_document_security_set_password (EV_DOCUMENT_SECURITY (job->document),
                                                           job_load->password);
@@ -848,9 +982,11 @@ ev_job_load_run (EvJob *job)
                job->failed = FALSE;
                job->finished = FALSE;
                g_clear_error (&job->error);
-               
+
+               uncompressed_uri = g_object_get_data (G_OBJECT (job->document),
+                                                     "uri-uncompressed");
                ev_document_load (job->document,
-                                 job_load->uri,
+                                 uncompressed_uri ? uncompressed_uri : job_load->uri,
                                  &error);
        } else {
                job->document = ev_document_factory_get_document (job_load->uri,
@@ -1083,7 +1219,7 @@ ev_job_find_dispose (GObject *object)
                gint i;
 
                for (i = 0; i < job->n_pages; i++) {
-                       g_list_foreach (job->pages[i], (GFunc)g_free, NULL);
+                       g_list_foreach (job->pages[i], (GFunc)ev_rectangle_free, NULL);
                        g_list_free (job->pages[i]);
                }
 
@@ -1424,6 +1560,9 @@ ev_job_print_run (EvJob *job)
 
        ev_document_doc_mutex_unlock ();
 
+        if (g_cancellable_is_cancelled (job->cancellable))
+                return FALSE;
+
        cr_status = cairo_status (job_print->cr);
        if (cr_status == CAIRO_STATUS_SUCCESS) {
                ev_job_succeeded (job);