From cbdeaed3897f8fdd01995a356c1e3a829fffbf7e Mon Sep 17 00:00:00 2001 From: Marco Pesenti Gritti Date: Sat, 11 Jun 2005 14:15:42 +0000 Subject: [PATCH] Make fonts model fill incrementally. 2005-06-11 Marco Pesenti Gritti * backend/ev-document-fonts.c: (ev_document_fonts_fill_model): * backend/ev-document-fonts.h: * pdf/ev-poppler.cc: Make fonts model fill incrementally. * shell/ev-job-queue.c: (handle_job), (search_for_jobs_unlocked), (no_jobs_available_unlocked), (ev_job_queue_init), (find_queue), (ev_job_queue_remove_job): * shell/ev-jobs.c: (ev_job_fonts_init), (ev_job_fonts_class_init), (ev_job_fonts_new), (ev_job_fonts_run): * shell/ev-jobs.h: New job for fonts scanning * shell/ev-properties.c: (job_fonts_finished_cb), (fill_fonts_treeview), (setup_fonts_view), (ev_properties_new): * shell/ev-properties.h: * shell/ev-window.c: (ev_window_cmd_file_properties): Incrementally feel the treeview using the new job. Show Loading... message until scanning is completed. Hopefully I didnt break the build without the poppler patch. --- ChangeLog | 27 ++++++++++++++ backend/ev-document-fonts.c | 11 +++--- backend/ev-document-fonts.h | 10 +++-- pdf/ev-poppler.cc | 74 ++++++++++++++++++------------------- shell/ev-job-queue.c | 16 +++++++- shell/ev-jobs.c | 35 ++++++++++++++++++ shell/ev-jobs.h | 26 +++++++++++++ shell/ev-properties.c | 63 ++++++++++++++++++++++++++++--- shell/ev-properties.h | 3 +- shell/ev-window.c | 9 +---- 10 files changed, 209 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index 0e8ee660..b446f786 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,30 @@ +2005-06-11 Marco Pesenti Gritti + + * backend/ev-document-fonts.c: (ev_document_fonts_fill_model): + * backend/ev-document-fonts.h: + * pdf/ev-poppler.cc: + + Make fonts model fill incrementally. + + * shell/ev-job-queue.c: (handle_job), (search_for_jobs_unlocked), + (no_jobs_available_unlocked), (ev_job_queue_init), (find_queue), + (ev_job_queue_remove_job): + * shell/ev-jobs.c: (ev_job_fonts_init), (ev_job_fonts_class_init), + (ev_job_fonts_new), (ev_job_fonts_run): + * shell/ev-jobs.h: + + New job for fonts scanning + + * shell/ev-properties.c: (job_fonts_finished_cb), + (fill_fonts_treeview), (setup_fonts_view), (ev_properties_new): + * shell/ev-properties.h: + * shell/ev-window.c: (ev_window_cmd_file_properties): + + Incrementally feel the treeview using the new job. Show Loading... + message until scanning is completed. + + Hopefully I didnt break the build without the poppler patch. + 2005-06-10 Nickolay V. Shmyrev * shell/ev-application.c: (ev_application_open): diff --git a/backend/ev-document-fonts.c b/backend/ev-document-fonts.c index fca19768..cd53d1e9 100644 --- a/backend/ev-document-fonts.c +++ b/backend/ev-document-fonts.c @@ -47,13 +47,12 @@ ev_document_fonts_get_type (void) return type; } -GtkTreeModel * -ev_document_fonts_get_fonts_model (EvDocumentFonts *document_fonts) +gboolean +ev_document_fonts_fill_model (EvDocumentFonts *document_fonts, + GtkTreeModel *model, + int n_pages) { EvDocumentFontsIface *iface = EV_DOCUMENT_FONTS_GET_IFACE (document_fonts); - GtkTreeModel *retval; - retval = iface->get_fonts_model (document_fonts); - - return retval; + return iface->fill_model (document_fonts, model, n_pages); } diff --git a/backend/ev-document-fonts.h b/backend/ev-document-fonts.h index 6cb07e2e..2a05e7ee 100644 --- a/backend/ev-document-fonts.h +++ b/backend/ev-document-fonts.h @@ -54,11 +54,15 @@ struct _EvDocumentFontsIface GTypeInterface base_iface; /* Methods */ - GtkTreeModel *(* get_fonts_model) (EvDocumentFonts *document_fonts); + gboolean (* fill_model) (EvDocumentFonts *document_fonts, + GtkTreeModel *model, + int n_pages); }; -GType ev_document_fonts_get_type (void); -GtkTreeModel *ev_document_fonts_get_fonts_model (EvDocumentFonts *document_fonts); +GType ev_document_fonts_get_type (void); +gboolean ev_document_fonts_fill_model (EvDocumentFonts *document_fonts, + GtkTreeModel *model, + int n_pages); G_END_DECLS diff --git a/pdf/ev-poppler.cc b/pdf/ev-poppler.cc index c65f1df1..8d555aff 100644 --- a/pdf/ev-poppler.cc +++ b/pdf/ev-poppler.cc @@ -495,58 +495,54 @@ pdf_document_security_iface_init (EvDocumentSecurityIface *iface) iface->set_password = pdf_document_set_password; } -#ifdef POPPLER_FONT_INFO -static void -build_fonts_list (PdfDocument *pdf_document, - GtkTreeModel *model, - GtkTreeIter *parent, - PopplerFontsIter *iter) -{ - do { - GtkTreeIter list_iter; - PopplerIndexIter *child; - const char *name; - - name = poppler_fonts_iter_get_name (iter); - gtk_list_store_append (GTK_LIST_STORE (model), &list_iter); - gtk_list_store_set (GTK_LIST_STORE (model), &list_iter, - EV_DOCUMENT_FONTS_COLUMN_NAME, name, - -1); - } while (poppler_fonts_iter_next (iter)); -} -#endif - -static GtkTreeModel * -pdf_document_fonts_get_fonts_model (EvDocumentFonts *document_fonts) +static gboolean +pdf_document_fonts_fill_model (EvDocumentFonts *document_fonts, + GtkTreeModel *model, + int n_pages) { - PdfDocument *pdf_document = PDF_DOCUMENT (document_fonts); - GtkTreeModel *model = NULL; #ifdef POPPLER_FONT_INFO + PdfDocument *pdf_document = PDF_DOCUMENT (document_fonts); + PopplerFontInfo *info; PopplerFontsIter *iter; -#endif + gboolean result; - g_return_val_if_fail (PDF_IS_DOCUMENT (document_fonts), NULL); + g_return_val_if_fail (PDF_IS_DOCUMENT (document_fonts), FALSE); -#ifdef POPPLER_FONT_INFO - iter = poppler_fonts_iter_new (pdf_document->document); - /* Create the model iff we have items*/ - if (iter != NULL) { -#endif - model = (GtkTreeModel *) gtk_list_store_new (EV_DOCUMENT_FONTS_COLUMN_NUM_COLUMNS, - G_TYPE_STRING); -#ifdef POPPLER_FONT_INFO - build_fonts_list (pdf_document, model, NULL, iter); + info = (PopplerFontInfo *)g_object_get_data (G_OBJECT (model), "font_info"); + if (info == NULL) { + info = poppler_font_info_new (pdf_document->document); + g_object_set_data_full (G_OBJECT (model), "font_info", + (PopplerFontInfo *)info, + (GDestroyNotify)poppler_font_info_free); + } + + result = poppler_font_info_scan (info, n_pages, &iter); + + if (iter) { + do { + GtkTreeIter list_iter; + PopplerIndexIter *child; + const char *name; + + name = poppler_fonts_iter_get_name (iter); + gtk_list_store_append (GTK_LIST_STORE (model), &list_iter); + gtk_list_store_set (GTK_LIST_STORE (model), &list_iter, + EV_DOCUMENT_FONTS_COLUMN_NAME, name, + -1); + } while (poppler_fonts_iter_next (iter)); poppler_fonts_iter_free (iter); } -#endif - return model; + return result; +#else + return FALSE; +#endif } static void pdf_document_document_fonts_iface_init (EvDocumentFontsIface *iface) { - iface->get_fonts_model = pdf_document_fonts_get_fonts_model; + iface->fill_model = pdf_document_fonts_fill_model; } static gboolean diff --git a/shell/ev-job-queue.c b/shell/ev-job-queue.c index 877aae81..a860f377 100644 --- a/shell/ev-job-queue.c +++ b/shell/ev-job-queue.c @@ -14,6 +14,7 @@ static GQueue *thumbnail_queue_high = NULL; static GQueue *thumbnail_queue_low = NULL; static GQueue *load_queue = NULL; static GQueue *xfer_queue = NULL; +static GQueue *fonts_queue = NULL; /* Queues used for backends supporting EvAsyncRender interface, they are executed on the main thread */ @@ -101,6 +102,8 @@ handle_job (EvJob *job) ev_job_xfer_run (EV_JOB_XFER (job)); else if (EV_IS_JOB_RENDER (job)) ev_job_render_run (EV_JOB_RENDER (job)); + else if (EV_IS_JOB_FONTS (job)) + ev_job_fonts_run (EV_JOB_FONTS (job)); if (!EV_JOB (job)->async) { /* We let the idle own a ref, as we (the queue) are done with the job. */ @@ -144,6 +147,10 @@ search_for_jobs_unlocked (void) if (job) return job; + job = (EvJob *) g_queue_pop_head (fonts_queue); + if (job) + return job; + return NULL; } @@ -156,7 +163,8 @@ no_jobs_available_unlocked (void) && g_queue_is_empty (load_queue) && g_queue_is_empty (xfer_queue) && g_queue_is_empty (thumbnail_queue_high) - && g_queue_is_empty (thumbnail_queue_low); + && g_queue_is_empty (thumbnail_queue_low) + && g_queue_is_empty (fonts_queue); } /* the thread mainloop function */ @@ -220,6 +228,7 @@ ev_job_queue_init (void) async_render_queue_low = g_queue_new (); thumbnail_queue_high = g_queue_new (); thumbnail_queue_low = g_queue_new (); + fonts_queue = g_queue_new (); g_thread_create (ev_render_thread, NULL, FALSE, NULL); @@ -256,6 +265,9 @@ find_queue (EvJob *job, } else if (EV_IS_JOB_LINKS (job)) { /* the priority doesn't effect links */ return links_queue; + } else if (EV_IS_JOB_FONTS (job)) { + /* the priority doesn't effect fonts */ + return fonts_queue; } } @@ -395,6 +407,8 @@ ev_job_queue_remove_job (EvJob *job) retval = remove_job_from_queue_locked (load_queue, job); } else if (EV_IS_JOB_XFER (job)) { retval = remove_job_from_queue_locked (xfer_queue, job); + } else if (EV_IS_JOB_FONTS (job)) { + retval = remove_job_from_queue_locked (fonts_queue, job); } else { g_assert_not_reached (); } diff --git a/shell/ev-jobs.c b/shell/ev-jobs.c index be1d3bc3..82f310f4 100644 --- a/shell/ev-jobs.c +++ b/shell/ev-jobs.c @@ -2,6 +2,7 @@ #include "ev-job-queue.h" #include "ev-document-thumbnails.h" #include "ev-document-links.h" +#include "ev-document-fonts.h" #include "ev-async-renderer.h" static void ev_job_init (EvJob *job); @@ -28,6 +29,7 @@ G_DEFINE_TYPE (EvJobLinks, ev_job_links, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobRender, ev_job_render, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobThumbnail, ev_job_thumbnail, EV_TYPE_JOB) G_DEFINE_TYPE (EvJobLoad, ev_job_load, EV_TYPE_JOB) +G_DEFINE_TYPE (EvJobFonts, ev_job_fonts, EV_TYPE_JOB) static void ev_job_init (EvJob *job) { /* Do Nothing */ } @@ -340,4 +342,37 @@ ev_job_load_run (EvJobLoad *job) ev_document_doc_mutex_unlock (); } +static void ev_job_fonts_init (EvJobFonts *job) { /* Do Nothing */ } +static void ev_job_fonts_class_init (EvJobFontsClass *class) { /* Do Nothing */ } + +EvJob * +ev_job_fonts_new (EvDocument *document, + GtkTreeModel *model) +{ + EvJobFonts *job; + + job = g_object_new (EV_TYPE_JOB_FONTS, NULL); + + EV_JOB (job)->document = g_object_ref (document); + job->model = g_object_ref (model); + + return EV_JOB (job); +} + +void +ev_job_fonts_run (EvJobFonts *job) +{ + EvDocumentFonts *fonts; + + g_return_if_fail (EV_IS_JOB_FONTS (job)); + + ev_document_doc_mutex_lock (); + + fonts = EV_DOCUMENT_FONTS (EV_JOB (job)->document); + job->scan_completed = !ev_document_fonts_fill_model (fonts, job->model, 20); + + EV_JOB (job)->finished = TRUE; + + ev_document_doc_mutex_unlock (); +} diff --git a/shell/ev-jobs.h b/shell/ev-jobs.h index 11a3f09d..d585d867 100644 --- a/shell/ev-jobs.h +++ b/shell/ev-jobs.h @@ -40,6 +40,9 @@ typedef struct _EvJobLinksClass EvJobLinksClass; typedef struct _EvJobLoad EvJobLoad; typedef struct _EvJobLoadClass EvJobLoadClass; +typedef struct _EvJobFonts EvJobFonts; +typedef struct _EvJobFontsClass EvJobFontsClass; + #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_CHACK_CLASS_CAST((klass), EV_TYPE_JOB, EvJobClass)) @@ -65,6 +68,11 @@ typedef struct _EvJobLoadClass EvJobLoadClass; #define EV_JOB_LOAD_CLASS(klass) (G_TYPE_CHACK_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_FONTS (ev_job_fonts_get_type()) +#define EV_JOB_FONTS(object) (G_TYPE_CHECK_INSTANCE_CAST((object), EV_TYPE_JOB_FONTS, EvJobFonts)) +#define EV_JOB_FONTS_CLASS(klass) (G_TYPE_CHACK_CLASS_CAST((klass), EV_TYPE_JOB_FONTS, EvJobFontsClass)) +#define EV_IS_JOB_FONTS(object) (G_TYPE_CHECK_INSTANCE_TYPE((object), EV_TYPE_JOB_FONTS)) + typedef enum { EV_JOB_PRIORITY_LOW, EV_JOB_PRIORITY_HIGH, @@ -141,6 +149,18 @@ struct _EvJobLoadClass EvJobClass parent_class; }; +struct _EvJobFonts +{ + EvJob parent; + GtkTreeModel *model; + gboolean scan_completed; +}; + +struct _EvJobFontsClass +{ + EvJobClass parent_class; +}; + /* Base job class */ GType ev_job_get_type (void); void ev_job_finished (EvJob *job); @@ -173,6 +193,12 @@ EvJob *ev_job_load_new (EvDocument *document, const gchar *uri); void ev_job_load_run (EvJobLoad *load); +/* EvJobFonts */ +GType ev_job_fonts_get_type (void); +EvJob *ev_job_fonts_new (EvDocument *document, + GtkTreeModel *model); +void ev_job_fonts_run (EvJobFonts *fonts); + G_END_DECLS #endif /* __EV_JOBS_H__ */ diff --git a/shell/ev-properties.c b/shell/ev-properties.c index 78303841..6007f134 100644 --- a/shell/ev-properties.c +++ b/shell/ev-properties.c @@ -24,6 +24,8 @@ #include "ev-properties.h" #include "ev-document-fonts.h" +#include "ev-jobs.h" +#include "ev-job-queue.h" #include #include @@ -31,6 +33,12 @@ #include #include +enum +{ + FONT_NAME_COL, + NUM_COLS +}; + typedef enum { TITLE_PROPERTY, @@ -98,14 +106,57 @@ set_property (GladeXML *xml, Property property, const char *text) } static void -setup_fonts_view (GladeXML *xml, GtkTreeModel *fonts) +job_fonts_finished_cb (EvJob *job, GtkTreeView *tree_view) +{ + GtkTreeModel *model = EV_JOB_FONTS (job)->model; + + if (EV_JOB_FONTS (job)->scan_completed) { + g_signal_handlers_disconnect_by_func + (job, job_fonts_finished_cb, tree_view); + gtk_tree_view_set_model (tree_view, model); + } else { + EvJob *new_job = ev_job_fonts_new (job->document, model); + ev_job_queue_add_job (job, EV_JOB_PRIORITY_LOW); + g_object_unref (new_job); + } +} + +static void +fill_fonts_treeview (GtkTreeView *tree_view, + EvDocument *document) +{ + GtkListStore *list_store; + EvJob *job; + + list_store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING); + g_object_set_data_full (G_OBJECT (tree_view), "list_store", + list_store, g_object_unref); + + job = ev_job_fonts_new (document, GTK_TREE_MODEL (list_store)); + g_signal_connect_object (job, "finished", + G_CALLBACK (job_fonts_finished_cb), + tree_view, 0); + ev_job_queue_add_job (job, EV_JOB_PRIORITY_LOW); + g_object_unref (job); +} + +static void +setup_fonts_view (GladeXML *xml, EvDocument *document) { GtkWidget *widget; GtkCellRenderer *renderer; GtkTreeViewColumn *column; + GtkListStore *list_store; + GtkTreeIter iter; widget = glade_xml_get_widget (xml, "fonts_treeview"); - gtk_tree_view_set_model (GTK_TREE_VIEW (widget), fonts); + + list_store = gtk_list_store_new (NUM_COLS, G_TYPE_STRING); + gtk_list_store_append (list_store, &iter); + gtk_list_store_set (list_store, &iter, FONT_NAME_COL, _("Loading..."), -1); + + gtk_tree_view_set_model (GTK_TREE_VIEW (widget), GTK_TREE_MODEL (list_store)); + g_object_unref (list_store); column = gtk_tree_view_column_new (); gtk_tree_view_column_set_expand (GTK_TREE_VIEW_COLUMN (column), TRUE); @@ -117,10 +168,12 @@ setup_fonts_view (GladeXML *xml, GtkTreeModel *fonts) gtk_tree_view_column_set_attributes (GTK_TREE_VIEW_COLUMN (column), renderer, "text", EV_DOCUMENT_FONTS_COLUMN_NAME, NULL); + + fill_fonts_treeview (GTK_TREE_VIEW (widget), document); } GtkDialog * -ev_properties_new (const EvDocumentInfo *info, GtkTreeModel *fonts) +ev_properties_new (EvDocument *document, const EvDocumentInfo *info) { GladeXML *xml; GtkWidget *dialog; @@ -182,9 +235,7 @@ ev_properties_new (const EvDocumentInfo *info, GtkTreeModel *fonts) set_property (xml, SECURITY_PROPERTY, info->security); } - if (fonts) { - setup_fonts_view (xml, fonts); - } + setup_fonts_view (xml, document); return GTK_DIALOG (dialog); } diff --git a/shell/ev-properties.h b/shell/ev-properties.h index 99c6fcb9..f17e9639 100644 --- a/shell/ev-properties.h +++ b/shell/ev-properties.h @@ -28,8 +28,7 @@ G_BEGIN_DECLS -GtkDialog *ev_properties_new (const EvDocumentInfo *info, - GtkTreeModel *fonts); +GtkDialog *ev_properties_new (EvDocument *document, const EvDocumentInfo *info); G_END_DECLS diff --git a/shell/ev-window.c b/shell/ev-window.c index 28921f03..46ae9a20 100644 --- a/shell/ev-window.c +++ b/shell/ev-window.c @@ -1249,16 +1249,9 @@ ev_window_cmd_file_properties (GtkAction *action, EvWindow *ev_window) EvDocument *document = ev_window->priv->document; const EvDocumentInfo *info; GtkDialog *dialog; - GtkTreeModel *fonts; - - if (EV_IS_DOCUMENT_FONTS (document)) { - fonts = ev_document_fonts_get_fonts_model (EV_DOCUMENT_FONTS (document)); - } else { - fonts = NULL; - } info = ev_page_cache_get_info (ev_window->priv->page_cache); - dialog = ev_properties_new (info, fonts); + dialog = ev_properties_new (document, info); gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (ev_window)); gtk_dialog_run (dialog); gtk_widget_destroy (GTK_WIDGET (dialog)); -- 2.43.5