1
/* this file is part of evince, a gnome document viewer
3
* Copyright (C) 2008 Carlos Garcia Campos <carlosgc@gnome.org>
4
* Copyright (C) 2005 Red Hat, Inc
6
* Evince is free software; you can redistribute it and/or modify it
7
* under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 2 of the License, or
9
* (at your option) any later version.
11
* Evince is distributed in the hope that it will be useful, but
12
* WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
24
#include "ev-document-thumbnails.h"
25
#include "ev-document-links.h"
26
#include "ev-document-images.h"
27
#include "ev-document-forms.h"
28
#include "ev-file-exporter.h"
29
#include "ev-document-factory.h"
30
#include "ev-document-misc.h"
31
#include "ev-file-helpers.h"
32
#include "ev-document-fonts.h"
33
#include "ev-document-security.h"
34
#include "ev-document-find.h"
35
#include "ev-document-layers.h"
39
#include <glib/gstdio.h>
40
#include <glib/gi18n.h>
43
static void ev_job_init (EvJob *job);
44
static void ev_job_class_init (EvJobClass *class);
45
static void ev_job_links_init (EvJobLinks *job);
46
static void ev_job_links_class_init (EvJobLinksClass *class);
47
static void ev_job_attachments_init (EvJobAttachments *job);
48
static void ev_job_attachments_class_init (EvJobAttachmentsClass *class);
49
static void ev_job_render_init (EvJobRender *job);
50
static void ev_job_render_class_init (EvJobRenderClass *class);
51
static void ev_job_thumbnail_init (EvJobThumbnail *job);
52
static void ev_job_thumbnail_class_init (EvJobThumbnailClass *class);
53
static void ev_job_load_init (EvJobLoad *job);
54
static void ev_job_load_class_init (EvJobLoadClass *class);
55
static void ev_job_save_init (EvJobSave *job);
56
static void ev_job_save_class_init (EvJobSaveClass *class);
57
static void ev_job_find_init (EvJobFind *job);
58
static void ev_job_find_class_init (EvJobFindClass *class);
59
static void ev_job_layers_init (EvJobLayers *job);
60
static void ev_job_layers_class_init (EvJobLayersClass *class);
61
static void ev_job_export_init (EvJobExport *job);
62
static void ev_job_export_class_init (EvJobExportClass *class);
85
static guint job_signals[LAST_SIGNAL] = { 0 };
86
static guint job_render_signals[RENDER_LAST_SIGNAL] = { 0 };
87
static guint job_fonts_signals[FONTS_LAST_SIGNAL] = { 0 };
88
static guint job_find_signals[FIND_LAST_SIGNAL] = { 0 };
90
G_DEFINE_ABSTRACT_TYPE (EvJob, ev_job, G_TYPE_OBJECT)
91
G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB)
92
G_DEFINE_TYPE (EvJobAttachments, ev_job_attachments, EV_TYPE_JOB)
93
G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB)
94
G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB)
95
G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB)
96
G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB)
97
G_DEFINE_TYPE (EvJobSave, ev_job_save, EV_TYPE_JOB)
98
G_DEFINE_TYPE (EvJobFind, ev_job_find, EV_TYPE_JOB)
99
G_DEFINE_TYPE (EvJobLayers, ev_job_layers, EV_TYPE_JOB)
100
G_DEFINE_TYPE (EvJobExport, ev_job_export, EV_TYPE_JOB)
104
ev_job_init (EvJob *job)
106
job->cancellable = g_cancellable_new ();
110
ev_job_dispose (GObject *object)
114
job = EV_JOB (object);
117
g_object_unref (job->document);
118
job->document = NULL;
121
if (job->cancellable) {
122
g_object_unref (job->cancellable);
123
job->cancellable = NULL;
127
g_error_free (job->error);
131
(* G_OBJECT_CLASS (ev_job_parent_class)->dispose) (object);
135
ev_job_class_init (EvJobClass *class)
137
GObjectClass *oclass;
139
oclass = G_OBJECT_CLASS (class);
141
oclass->dispose = ev_job_dispose;
143
job_signals[CANCELLED] =
144
g_signal_new ("cancelled",
147
G_STRUCT_OFFSET (EvJobClass, cancelled),
149
g_cclosure_marshal_VOID__VOID,
151
job_signals [FINISHED] =
152
g_signal_new ("finished",
155
G_STRUCT_OFFSET (EvJobClass, finished),
157
g_cclosure_marshal_VOID__VOID,
162
emit_finished (EvJob *job)
164
ev_debug_message (DEBUG_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
166
job->idle_finished_id = 0;
168
if (job->cancelled) {
169
ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, do not emit finished", EV_GET_TYPE_NAME (job), job);
171
ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
172
g_signal_emit (job, job_signals[FINISHED], 0);
179
ev_job_emit_finished (EvJob *job)
181
ev_debug_message (DEBUG_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
183
if (g_cancellable_is_cancelled (job->cancellable)) {
184
ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, returning", EV_GET_TYPE_NAME (job), job);
188
job->finished = TRUE;
190
if (job->run_mode == EV_JOB_RUN_THREAD) {
191
job->idle_finished_id =
192
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
193
(GSourceFunc)emit_finished,
195
(GDestroyNotify)g_object_unref);
197
ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
198
g_signal_emit (job, job_signals[FINISHED], 0);
203
ev_job_run (EvJob *job)
205
EvJobClass *class = EV_JOB_GET_CLASS (job);
207
return class->run (job);
211
ev_job_cancel (EvJob *job)
213
if (job->cancelled || (job->finished && job->idle_finished_id == 0))
216
ev_debug_message (DEBUG_JOBS, "job %s (%p) cancelled", EV_GET_TYPE_NAME (job), job);
217
ev_profiler_stop (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
219
/* This should never be called from a thread */
220
job->cancelled = TRUE;
221
g_cancellable_cancel (job->cancellable);
222
g_signal_emit (job, job_signals[CANCELLED], 0);
226
ev_job_failed (EvJob *job,
235
if (job->failed || job->finished)
238
ev_debug_message (DEBUG_JOBS, "job %s (%p) failed", EV_GET_TYPE_NAME (job), job);
242
va_start (args, format);
243
message = g_strdup_vprintf (format, args);
246
job->error = g_error_new_literal (domain, code, message);
249
ev_job_emit_finished (job);
253
ev_job_failed_from_error (EvJob *job,
256
if (job->failed || job->finished)
259
ev_debug_message (DEBUG_JOBS, "job %s (%p) failed", EV_GET_TYPE_NAME (job), job);
262
job->error = g_error_copy (error);
264
ev_job_emit_finished (job);
268
ev_job_succeeded (EvJob *job)
273
ev_debug_message (DEBUG_JOBS, "job %s (%p) succeeded", EV_GET_TYPE_NAME (job), job);
276
ev_job_emit_finished (job);
280
ev_job_is_finished (EvJob *job)
282
return job->finished;
286
ev_job_is_failed (EvJob *job)
292
ev_job_get_run_mode (EvJob *job)
294
return job->run_mode;
298
ev_job_set_run_mode (EvJob *job,
299
EvJobRunMode run_mode)
301
job->run_mode = run_mode;
306
ev_job_links_init (EvJobLinks *job)
308
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
312
ev_job_links_dispose (GObject *object)
316
ev_debug_message (DEBUG_JOBS, NULL);
318
job = EV_JOB_LINKS (object);
321
g_object_unref (job->model);
325
(* G_OBJECT_CLASS (ev_job_links_parent_class)->dispose) (object);
329
ev_job_links_run (EvJob *job)
331
EvJobLinks *job_links = EV_JOB_LINKS (job);
333
ev_debug_message (DEBUG_JOBS, NULL);
334
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
336
ev_document_doc_mutex_lock ();
337
job_links->model = ev_document_links_get_links_model (EV_DOCUMENT_LINKS (job->document));
338
ev_document_doc_mutex_unlock ();
340
ev_job_succeeded (job);
346
ev_job_links_class_init (EvJobLinksClass *class)
348
GObjectClass *oclass = G_OBJECT_CLASS (class);
349
EvJobClass *job_class = EV_JOB_CLASS (class);
351
oclass->dispose = ev_job_links_dispose;
352
job_class->run = ev_job_links_run;
356
ev_job_links_new (EvDocument *document)
360
ev_debug_message (DEBUG_JOBS, NULL);
362
job = g_object_new (EV_TYPE_JOB_LINKS, NULL);
363
job->document = g_object_ref (document);
368
/* EvJobAttachments */
370
ev_job_attachments_init (EvJobAttachments *job)
372
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
376
ev_job_attachments_dispose (GObject *object)
378
EvJobAttachments *job;
380
ev_debug_message (DEBUG_JOBS, NULL);
382
job = EV_JOB_ATTACHMENTS (object);
384
if (job->attachments) {
385
g_list_foreach (job->attachments, (GFunc)g_object_unref, NULL);
386
g_list_free (job->attachments);
387
job->attachments = NULL;
390
(* G_OBJECT_CLASS (ev_job_attachments_parent_class)->dispose) (object);
394
ev_job_attachments_run (EvJob *job)
396
EvJobAttachments *job_attachments = EV_JOB_ATTACHMENTS (job);
398
ev_debug_message (DEBUG_JOBS, NULL);
399
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
401
ev_document_doc_mutex_lock ();
402
job_attachments->attachments = ev_document_get_attachments (job->document);
403
ev_document_doc_mutex_unlock ();
405
ev_job_succeeded (job);
411
ev_job_attachments_class_init (EvJobAttachmentsClass *class)
413
GObjectClass *oclass = G_OBJECT_CLASS (class);
414
EvJobClass *job_class = EV_JOB_CLASS (class);
416
oclass->dispose = ev_job_attachments_dispose;
417
job_class->run = ev_job_attachments_run;
421
ev_job_attachments_new (EvDocument *document)
425
ev_debug_message (DEBUG_JOBS, NULL);
427
job = g_object_new (EV_TYPE_JOB_ATTACHMENTS, NULL);
428
job->document = g_object_ref (document);
435
ev_job_render_init (EvJobRender *job)
437
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
441
ev_job_render_dispose (GObject *object)
445
job = EV_JOB_RENDER (object);
448
ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job->ev_page->index, job);
449
g_object_unref (job->ev_page);
454
cairo_surface_destroy (job->surface);
458
if (job->selection) {
459
cairo_surface_destroy (job->selection);
460
job->selection = NULL;
463
if (job->selection_region) {
464
gdk_region_destroy (job->selection_region);
465
job->selection_region = NULL;
468
(* G_OBJECT_CLASS (ev_job_render_parent_class)->dispose) (object);
472
notify_page_ready (EvJobRender *job)
474
ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job);
475
ev_profiler_stop (EV_PROFILE_JOBS, "Rendering page %d", job->ev_page->index);
477
if (EV_JOB (job)->cancelled) {
478
ev_debug_message (DEBUG_JOBS, "%s (%p) job was cancelled, do not emit page_ready", EV_GET_TYPE_NAME (job), job);
480
g_signal_emit (job, job_render_signals[PAGE_READY], 0);
487
ev_job_render_page_ready (EvJobRender *job)
489
ev_debug_message (DEBUG_JOBS, "%d (%p)", job->ev_page->index, job);
491
job->page_ready = TRUE;
492
g_idle_add_full (G_PRIORITY_HIGH_IDLE,
493
(GSourceFunc)notify_page_ready,
495
(GDestroyNotify)g_object_unref);
499
ev_job_render_run (EvJob *job)
501
EvJobRender *job_render = EV_JOB_RENDER (job);
504
ev_debug_message (DEBUG_JOBS, "page: %d (%p)", job_render->page, job);
505
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
507
ev_document_doc_mutex_lock ();
509
ev_profiler_start (EV_PROFILE_JOBS, "Rendering page %d", job_render->page);
511
ev_document_fc_mutex_lock ();
513
job_render->ev_page = ev_document_get_page (job->document, job_render->page);
514
rc = ev_render_context_new (job_render->ev_page, job_render->rotation, job_render->scale);
516
job_render->surface = ev_document_render (job->document, rc);
517
/* If job was cancelled during the page rendering,
518
* we return now, so that the thread is finished ASAP
520
if (g_cancellable_is_cancelled (job->cancellable)) {
521
ev_document_fc_mutex_unlock ();
522
ev_document_doc_mutex_unlock ();
528
if ((job_render->flags & EV_RENDER_INCLUDE_SELECTION) && EV_IS_SELECTION (job->document)) {
529
ev_selection_render_selection (EV_SELECTION (job->document),
531
&(job_render->selection),
532
&(job_render->selection_points),
534
job_render->selection_style,
535
&(job_render->text), &(job_render->base));
536
job_render->selection_region =
537
ev_selection_get_selection_region (EV_SELECTION (job->document),
539
job_render->selection_style,
540
&(job_render->selection_points));
543
ev_job_render_page_ready (job_render);
545
ev_document_fc_mutex_unlock ();
547
if ((job_render->flags & EV_RENDER_INCLUDE_TEXT) && EV_IS_SELECTION (job->document))
548
job_render->text_mapping =
549
ev_selection_get_selection_map (EV_SELECTION (job->document), rc);
550
if ((job_render->flags & EV_RENDER_INCLUDE_LINKS) && EV_IS_DOCUMENT_LINKS (job->document))
551
job_render->link_mapping =
552
ev_document_links_get_links (EV_DOCUMENT_LINKS (job->document), job_render->page);
553
if ((job_render->flags & EV_RENDER_INCLUDE_FORMS) && EV_IS_DOCUMENT_FORMS (job->document))
554
job_render->form_field_mapping =
555
ev_document_forms_get_form_fields (EV_DOCUMENT_FORMS (job->document),
556
job_render->ev_page);
557
if ((job_render->flags & EV_RENDER_INCLUDE_IMAGES) && EV_IS_DOCUMENT_IMAGES (job->document))
558
job_render->image_mapping =
559
ev_document_images_get_image_mapping (EV_DOCUMENT_IMAGES (job->document),
562
ev_document_doc_mutex_unlock ();
564
ev_job_succeeded (job);
570
ev_job_render_class_init (EvJobRenderClass *class)
572
GObjectClass *oclass = G_OBJECT_CLASS (class);
573
EvJobClass *job_class = EV_JOB_CLASS (class);
575
job_render_signals [PAGE_READY] =
576
g_signal_new ("page-ready",
579
G_STRUCT_OFFSET (EvJobRenderClass, page_ready),
581
g_cclosure_marshal_VOID__VOID,
584
oclass->dispose = ev_job_render_dispose;
585
job_class->run = ev_job_render_run;
589
ev_job_render_new (EvDocument *document,
599
ev_debug_message (DEBUG_JOBS, "page: %d", page);
601
job = g_object_new (EV_TYPE_JOB_RENDER, NULL);
603
EV_JOB (job)->document = g_object_ref (document);
605
job->rotation = rotation;
607
job->target_width = width;
608
job->target_height = height;
615
ev_job_render_set_selection_info (EvJobRender *job,
616
EvRectangle *selection_points,
617
EvSelectionStyle selection_style,
621
job->flags |= EV_RENDER_INCLUDE_SELECTION;
623
job->selection_points = *selection_points;
624
job->selection_style = selection_style;
631
ev_job_thumbnail_init (EvJobThumbnail *job)
633
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
637
ev_job_thumbnail_dispose (GObject *object)
641
job = EV_JOB_THUMBNAIL (object);
643
ev_debug_message (DEBUG_JOBS, "%d (%p)", job->page, job);
645
if (job->thumbnail) {
646
g_object_unref (job->thumbnail);
647
job->thumbnail = NULL;
650
(* G_OBJECT_CLASS (ev_job_thumbnail_parent_class)->dispose) (object);
654
ev_job_thumbnail_run (EvJob *job)
656
EvJobThumbnail *job_thumb = EV_JOB_THUMBNAIL (job);
660
ev_debug_message (DEBUG_JOBS, "%d (%p)", job_thumb->page, job);
661
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
663
ev_document_doc_mutex_lock ();
665
page = ev_document_get_page (job->document, job_thumb->page);
666
rc = ev_render_context_new (page, job_thumb->rotation, job_thumb->scale);
667
g_object_unref (page);
669
job_thumb->thumbnail = ev_document_thumbnails_get_thumbnail (EV_DOCUMENT_THUMBNAILS (job->document),
672
ev_document_doc_mutex_unlock ();
674
ev_job_succeeded (job);
680
ev_job_thumbnail_class_init (EvJobThumbnailClass *class)
682
GObjectClass *oclass = G_OBJECT_CLASS (class);
683
EvJobClass *job_class = EV_JOB_CLASS (class);
685
oclass->dispose = ev_job_thumbnail_dispose;
686
job_class->run = ev_job_thumbnail_run;
690
ev_job_thumbnail_new (EvDocument *document,
697
ev_debug_message (DEBUG_JOBS, "%d", page);
699
job = g_object_new (EV_TYPE_JOB_THUMBNAIL, NULL);
701
EV_JOB (job)->document = g_object_ref (document);
703
job->rotation = rotation;
711
ev_job_fonts_init (EvJobFonts *job)
713
EV_JOB (job)->run_mode = EV_JOB_RUN_MAIN_LOOP;
717
ev_job_fonts_run (EvJob *job)
719
EvJobFonts *job_fonts = EV_JOB_FONTS (job);
720
EvDocumentFonts *fonts = EV_DOCUMENT_FONTS (job->document);
722
ev_debug_message (DEBUG_JOBS, NULL);
724
/* Do not block the main loop */
725
if (!ev_document_doc_mutex_trylock ())
728
if (!ev_document_fc_mutex_trylock ())
731
#ifdef EV_ENABLE_DEBUG
732
/* We use the #ifdef in this case because of the if */
733
if (ev_document_fonts_get_progress (fonts) == 0)
734
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
737
job_fonts->scan_completed = !ev_document_fonts_scan (fonts, 20);
738
g_signal_emit (job_fonts, job_fonts_signals[FONTS_UPDATED], 0,
739
ev_document_fonts_get_progress (fonts));
741
ev_document_fc_mutex_unlock ();
742
ev_document_doc_mutex_unlock ();
744
if (job_fonts->scan_completed)
745
ev_job_succeeded (job);
747
return !job_fonts->scan_completed;
751
ev_job_fonts_class_init (EvJobFontsClass *class)
753
EvJobClass *job_class = EV_JOB_CLASS (class);
755
job_class->run = ev_job_fonts_run;
757
job_fonts_signals[FONTS_UPDATED] =
758
g_signal_new ("updated",
761
G_STRUCT_OFFSET (EvJobFontsClass, updated),
763
g_cclosure_marshal_VOID__DOUBLE,
769
ev_job_fonts_new (EvDocument *document)
773
ev_debug_message (DEBUG_JOBS, NULL);
775
job = g_object_new (EV_TYPE_JOB_FONTS, NULL);
777
EV_JOB (job)->document = g_object_ref (document);
784
ev_job_load_init (EvJobLoad *job)
786
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
790
ev_job_load_dispose (GObject *object)
792
EvJobLoad *job = EV_JOB_LOAD (object);
794
ev_debug_message (DEBUG_JOBS, "%s", job->uri);
802
g_free (job->password);
803
job->password = NULL;
806
(* G_OBJECT_CLASS (ev_job_load_parent_class)->dispose) (object);
810
ev_job_load_run (EvJob *job)
812
EvJobLoad *job_load = EV_JOB_LOAD (job);
813
GError *error = NULL;
815
ev_debug_message (DEBUG_JOBS, "%s", job_load->uri);
816
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
818
ev_document_fc_mutex_lock ();
820
/* This job may already have a document even if the job didn't complete
821
because, e.g., a password is required - if so, just reload rather than
822
creating a new instance */
824
if (job_load->password) {
825
ev_document_security_set_password (EV_DOCUMENT_SECURITY (job->document),
830
job->finished = FALSE;
831
g_clear_error (&job->error);
833
ev_document_load (job->document,
837
job->document = ev_document_factory_get_document (job_load->uri,
841
ev_document_fc_mutex_unlock ();
844
ev_job_failed_from_error (job, error);
845
g_error_free (error);
847
ev_job_succeeded (job);
854
ev_job_load_class_init (EvJobLoadClass *class)
856
GObjectClass *oclass = G_OBJECT_CLASS (class);
857
EvJobClass *job_class = EV_JOB_CLASS (class);
859
oclass->dispose = ev_job_load_dispose;
860
job_class->run = ev_job_load_run;
864
ev_job_load_new (const gchar *uri)
868
ev_debug_message (DEBUG_JOBS, "%s", uri);
870
job = g_object_new (EV_TYPE_JOB_LOAD, NULL);
871
job->uri = g_strdup (uri);
877
ev_job_load_set_uri (EvJobLoad *job, const gchar *uri)
879
ev_debug_message (DEBUG_JOBS, "%s", uri);
883
job->uri = g_strdup (uri);
887
ev_job_load_set_password (EvJobLoad *job, const gchar *password)
889
ev_debug_message (DEBUG_JOBS, NULL);
892
g_free (job->password);
893
job->password = password ? g_strdup (password) : NULL;
898
ev_job_save_init (EvJobSave *job)
900
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
904
ev_job_save_dispose (GObject *object)
906
EvJobSave *job = EV_JOB_SAVE (object);
908
ev_debug_message (DEBUG_JOBS, "%s", job->uri);
915
if (job->document_uri) {
916
g_free (job->document_uri);
917
job->document_uri = NULL;
920
(* G_OBJECT_CLASS (ev_job_save_parent_class)->dispose) (object);
924
ev_job_save_run (EvJob *job)
926
EvJobSave *job_save = EV_JOB_SAVE (job);
931
GError *error = NULL;
933
ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", job_save->uri, job_save->document_uri);
934
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
936
filename = ev_tmp_filename ("saveacopy");
937
tmp_filename = g_strdup_printf ("%s.XXXXXX", filename);
940
fd = g_mkstemp (tmp_filename);
943
gint save_errno = errno;
945
display_name = g_filename_display_name (tmp_filename);
948
g_file_error_from_errno (save_errno),
949
_("Failed to create file ā%sā: %s"),
950
display_name, g_strerror (save_errno));
951
g_free (display_name);
952
g_free (tmp_filename);
957
ev_document_doc_mutex_lock ();
959
/* Save document to temp filename */
960
local_uri = g_filename_to_uri (tmp_filename, NULL, NULL);
961
ev_document_save (job->document, local_uri, &error);
964
ev_document_doc_mutex_unlock ();
968
ev_job_failed_from_error (job, error);
969
g_error_free (error);
974
/* If original document was compressed,
975
* compress it again before saving
977
if (g_object_get_data (G_OBJECT (job->document), "uri-uncompressed")) {
978
EvCompressionType ctype = EV_COMPRESSION_NONE;
982
ext = g_strrstr (job_save->document_uri, ".gz");
983
if (ext && g_ascii_strcasecmp (ext, ".gz") == 0)
984
ctype = EV_COMPRESSION_GZIP;
986
ext = g_strrstr (job_save->document_uri, ".bz2");
987
if (ext && g_ascii_strcasecmp (ext, ".bz2") == 0)
988
ctype = EV_COMPRESSION_BZIP2;
990
uri_comp = ev_file_compress (local_uri, ctype, &error);
992
ev_tmp_filename_unlink (tmp_filename);
994
if (!uri_comp || error) {
997
local_uri = uri_comp;
1001
g_free (tmp_filename);
1005
ev_job_failed_from_error (job, error);
1006
g_error_free (error);
1014
ev_xfer_uri_simple (local_uri, job_save->uri, &error);
1015
ev_tmp_uri_unlink (local_uri);
1018
ev_job_failed_from_error (job, error);
1019
g_error_free (error);
1021
ev_job_succeeded (job);
1028
ev_job_save_class_init (EvJobSaveClass *class)
1030
GObjectClass *oclass = G_OBJECT_CLASS (class);
1031
EvJobClass *job_class = EV_JOB_CLASS (class);
1033
oclass->dispose = ev_job_save_dispose;
1034
job_class->run = ev_job_save_run;
1038
ev_job_save_new (EvDocument *document,
1040
const gchar *document_uri)
1044
ev_debug_message (DEBUG_JOBS, "uri: %s, document_uri: %s", uri, document_uri);
1046
job = g_object_new (EV_TYPE_JOB_SAVE, NULL);
1048
EV_JOB (job)->document = g_object_ref (document);
1049
job->uri = g_strdup (uri);
1050
job->document_uri = g_strdup (document_uri);
1052
return EV_JOB (job);
1057
ev_job_find_init (EvJobFind *job)
1059
EV_JOB (job)->run_mode = EV_JOB_RUN_MAIN_LOOP;
1063
ev_job_find_dispose (GObject *object)
1065
EvJobFind *job = EV_JOB_FIND (object);
1067
ev_debug_message (DEBUG_JOBS, NULL);
1077
for (i = 0; i < job->n_pages; i++) {
1078
g_list_foreach (job->pages[i], (GFunc)g_free, NULL);
1079
g_list_free (job->pages[i]);
1082
g_free (job->pages);
1086
(* G_OBJECT_CLASS (ev_job_find_parent_class)->dispose) (object);
1090
ev_job_find_run (EvJob *job)
1092
EvJobFind *job_find = EV_JOB_FIND (job);
1093
EvDocumentFind *find = EV_DOCUMENT_FIND (job->document);
1097
ev_debug_message (DEBUG_JOBS, NULL);
1099
/* Do not block the main loop */
1100
if (!ev_document_doc_mutex_trylock ())
1103
#ifdef EV_ENABLE_DEBUG
1104
/* We use the #ifdef in this case because of the if */
1105
if (job_find->current_page == job_find->start_page)
1106
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
1109
ev_page = ev_document_get_page (job->document, job_find->current_page);
1110
matches = ev_document_find_find_text (find, ev_page, job_find->text,
1111
job_find->case_sensitive);
1112
g_object_unref (ev_page);
1114
ev_document_doc_mutex_unlock ();
1116
if (!job_find->has_results)
1117
job_find->has_results = (matches != NULL);
1119
job_find->pages[job_find->current_page] = matches;
1120
g_signal_emit (job_find, job_find_signals[FIND_UPDATED], 0, job_find->current_page);
1122
job_find->current_page = (job_find->current_page + 1) % job_find->n_pages;
1123
if (job_find->current_page == job_find->start_page) {
1124
ev_job_succeeded (job);
1133
ev_job_find_class_init (EvJobFindClass *class)
1135
EvJobClass *job_class = EV_JOB_CLASS (class);
1136
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
1138
job_class->run = ev_job_find_run;
1139
gobject_class->dispose = ev_job_find_dispose;
1141
job_find_signals[FIND_UPDATED] =
1142
g_signal_new ("updated",
1145
G_STRUCT_OFFSET (EvJobFindClass, updated),
1147
g_cclosure_marshal_VOID__INT,
1153
ev_job_find_new (EvDocument *document,
1157
gboolean case_sensitive)
1161
ev_debug_message (DEBUG_JOBS, NULL);
1163
job = g_object_new (EV_TYPE_JOB_FIND, NULL);
1165
EV_JOB (job)->document = g_object_ref (document);
1166
job->start_page = start_page;
1167
job->current_page = start_page;
1168
job->n_pages = n_pages;
1169
job->pages = g_new0 (GList *, n_pages);
1170
job->text = g_strdup (text);
1171
job->case_sensitive = case_sensitive;
1172
job->has_results = FALSE;
1174
return EV_JOB (job);
1178
ev_job_find_get_n_results (EvJobFind *job,
1181
return g_list_length (job->pages[page]);
1185
ev_job_find_get_progress (EvJobFind *job)
1189
if (ev_job_is_finished (EV_JOB (job)))
1192
if (job->current_page > job->start_page) {
1193
pages_done = job->current_page - job->start_page + 1;
1194
} else if (job->current_page == job->start_page) {
1195
pages_done = job->n_pages;
1197
pages_done = job->n_pages - job->start_page + job->current_page;
1200
return pages_done / (gdouble) job->n_pages;
1204
ev_job_find_has_results (EvJobFind *job)
1206
return job->has_results;
1210
ev_job_find_get_results (EvJobFind *job)
1217
ev_job_layers_init (EvJobLayers *job)
1219
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
1223
ev_job_layers_dispose (GObject *object)
1227
ev_debug_message (DEBUG_JOBS, NULL);
1229
job = EV_JOB_LAYERS (object);
1232
g_object_unref (job->model);
1236
(* G_OBJECT_CLASS (ev_job_layers_parent_class)->dispose) (object);
1240
ev_job_layers_run (EvJob *job)
1242
EvJobLayers *job_layers = EV_JOB_LAYERS (job);
1244
ev_debug_message (DEBUG_JOBS, NULL);
1245
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
1247
ev_document_doc_mutex_lock ();
1248
job_layers->model = ev_document_layers_get_layers (EV_DOCUMENT_LAYERS (job->document));
1249
ev_document_doc_mutex_unlock ();
1251
ev_job_succeeded (job);
1257
ev_job_layers_class_init (EvJobLayersClass *class)
1259
GObjectClass *oclass = G_OBJECT_CLASS (class);
1260
EvJobClass *job_class = EV_JOB_CLASS (class);
1262
oclass->dispose = ev_job_layers_dispose;
1263
job_class->run = ev_job_layers_run;
1267
ev_job_layers_new (EvDocument *document)
1271
ev_debug_message (DEBUG_JOBS, NULL);
1273
job = g_object_new (EV_TYPE_JOB_LAYERS, NULL);
1274
job->document = g_object_ref (document);
1281
ev_job_export_init (EvJobExport *job)
1283
EV_JOB (job)->run_mode = EV_JOB_RUN_THREAD;
1288
ev_job_export_dispose (GObject *object)
1292
ev_debug_message (DEBUG_JOBS, NULL);
1294
job = EV_JOB_EXPORT (object);
1297
g_object_unref (job->rc);
1301
(* G_OBJECT_CLASS (ev_job_export_parent_class)->dispose) (object);
1305
ev_job_export_run (EvJob *job)
1307
EvJobExport *job_export = EV_JOB_EXPORT (job);
1310
g_assert (job_export->page != -1);
1312
ev_debug_message (DEBUG_JOBS, NULL);
1313
ev_profiler_start (EV_PROFILE_JOBS, "%s (%p)", EV_GET_TYPE_NAME (job), job);
1315
ev_document_doc_mutex_lock ();
1317
ev_page = ev_document_get_page (job->document, job_export->page);
1318
if (job_export->rc) {
1319
job->failed = FALSE;
1320
job->finished = FALSE;
1321
g_clear_error (&job->error);
1323
ev_render_context_set_page (job_export->rc, ev_page);
1325
job_export->rc = ev_render_context_new (ev_page, 0, 1.0);
1327
g_object_unref (ev_page);
1329
ev_file_exporter_do_page (EV_FILE_EXPORTER (job->document), job_export->rc);
1331
ev_document_doc_mutex_unlock ();
1333
ev_job_succeeded (job);
1339
ev_job_export_class_init (EvJobExportClass *class)
1341
GObjectClass *oclass = G_OBJECT_CLASS (class);
1342
EvJobClass *job_class = EV_JOB_CLASS (class);
1344
oclass->dispose = ev_job_export_dispose;
1345
job_class->run = ev_job_export_run;
1349
ev_job_export_new (EvDocument *document)
1353
ev_debug_message (DEBUG_JOBS, NULL);
1355
job = g_object_new (EV_TYPE_JOB_EXPORT, NULL);
1356
job->document = g_object_ref (document);
1362
ev_job_export_set_page (EvJobExport *job,