[evince/wip/chpe/issue-1711: 3/3] libdocument: Move GDateTime members to the extended struct




commit 1e0a3efa24a4db67fc5b8f0939444d69771be196
Author: Christian Persch <chpe src gnome org>
Date:   Thu Dec 2 18:35:18 2021 +0100

    libdocument: Move GDateTime members to the extended struct
    
    Commit ed1e94af introduced an unintentional API and ABI break by
    changing the creation_date and modified_date members of EvDocumentInfo
    from GTime to GDateTime*.
    
    Revert this API/ABI break by adding the created and modified GDateTime
    members to EvDocumentInfoExtended, and add public getters and
    backend-private setters.
    
    Make the PDF backend set these, and adjust the properties view to use
    the new accessor functions.
    
    Fixes: https://gitlab.gnome.org/GNOME/evince/-/issues/1711

 backend/pdf/ev-poppler.c                           |  52 +++++-----
 .../libdocument/libevdocument-sections.txt         |   2 +
 libdocument/ev-document-info.c                     | 109 ++++++++++++++++++++-
 libdocument/ev-document-info.h                     |  16 ++-
 properties/ev-properties-view.c                    |  36 +++----
 5 files changed, 164 insertions(+), 51 deletions(-)
---
diff --git a/backend/pdf/ev-poppler.c b/backend/pdf/ev-poppler.c
index b019fe3b7..8dc9035e1 100644
--- a/backend/pdf/ev-poppler.c
+++ b/backend/pdf/ev-poppler.c
@@ -907,11 +907,11 @@ pdf_document_parse_metadata (const gchar    *metadata,
        gchar             *subject;
        gchar             *creatortool;
        gchar             *producer;
-       gchar             *datestr;
        gchar             *modified_date;
-       gchar             *creation_date;
+       gchar             *created_date;
        gchar             *metadata_date;
-       GDateTime         *dt = NULL;
+        GDateTime         *modified_datetime;
+        GDateTime         *metadata_datetime = NULL;
 
        doc = xmlParseMemory (metadata, strlen (metadata));
        if (doc == NULL)
@@ -926,9 +926,7 @@ pdf_document_parse_metadata (const gchar    *metadata,
        /* reads pdf metadata date */
        metadata_date = (gchar *)pdf_document_get_xmptag_from_path (xpathCtx, META_DATE);
        if (metadata_date != NULL) {
-               datestr = g_strdup_printf ("%s", metadata_date);
-               dt = g_date_time_new_from_iso8601 (datestr, NULL);
-               g_free (datestr);
+               metadata_datetime = g_date_time_new_from_iso8601 (metadata_date, NULL);
                g_free (metadata_date);
        }
 
@@ -936,8 +934,10 @@ pdf_document_parse_metadata (const gchar    *metadata,
         * it indicates that the file was edited by a non-XMP aware software.
         * Then, the information dictionary is considered authoritative and the
         * XMP metadata should not be displayed. */
-       if (info->modified_date == NULL || dt == NULL ||
-           ! (g_date_time_compare (dt, info->modified_date) == -1)) {
+        modified_datetime = ev_document_info_get_modified_datetime (info);
+       if (modified_datetime == NULL ||
+            metadata_datetime == NULL ||
+           g_date_time_compare (metadata_datetime, modified_datetime) >= 0) {
 
                fmt = pdf_document_get_format_from_metadata (xpathCtx);
                if (fmt != NULL) {
@@ -984,34 +984,31 @@ pdf_document_parse_metadata (const gchar    *metadata,
                /* reads modify date */
                modified_date = (gchar *)pdf_document_get_xmptag_from_path (xpathCtx, MOD_DATE);
                if (modified_date != NULL) {
-                       g_clear_pointer (&info->modified_date, g_date_time_unref);
+                        GDateTime *datetime;
 
-                       datestr = g_strdup_printf ("%s", modified_date);
-                       info->modified_date = g_date_time_new_from_iso8601 (datestr, NULL);
-                       g_free (datestr);
+                        datetime = g_date_time_new_from_iso8601 (modified_date, NULL);
+                       ev_document_info_take_modified_datetime (info, datetime);
                        g_free (modified_date);
                }
 
                /* reads pdf create date */
-               creation_date = (gchar *)pdf_document_get_xmptag_from_path (xpathCtx, CREATE_DATE);
-               if (creation_date != NULL) {
-                       g_clear_pointer (&info->creation_date, g_date_time_unref);
-
-                       datestr = g_strdup_printf ("%s", creation_date);
-                       info->creation_date = g_date_time_new_from_iso8601 (datestr, NULL);
-                       g_free (datestr);
-                       g_free (creation_date);
+               created_date = (gchar *)pdf_document_get_xmptag_from_path (xpathCtx, CREATE_DATE);
+               if (created_date != NULL) {
+                        GDateTime *datetime;
+
+                        datetime = g_date_time_new_from_iso8601 (created_date, NULL);
+                       ev_document_info_take_created_datetime (info, datetime);
+                       g_free (created_date);
                }
        }
 
        info->license = pdf_document_get_license_from_metadata (xpathCtx);
 
-       g_clear_pointer (&dt, g_date_time_unref);
+       g_clear_pointer (&metadata_datetime, g_date_time_unref);
        xmlXPathFreeContext (xpathCtx);
        xmlFreeDoc (doc);
 }
 
-
 static EvDocumentInfo *
 pdf_document_get_info (EvDocument *document)
 {
@@ -1022,6 +1019,8 @@ pdf_document_get_info (EvDocument *document)
        PopplerPermissions permissions;
        char *metadata;
        gboolean linearized;
+        GDateTime *created_datetime = NULL;
+        GDateTime *modified_datetime = NULL;
 
        info = ev_document_info_new ();
 
@@ -1036,8 +1035,6 @@ pdf_document_get_info (EvDocument *document)
                             EV_DOCUMENT_INFO_UI_HINTS |
                             EV_DOCUMENT_INFO_CREATOR |
                             EV_DOCUMENT_INFO_PRODUCER |
-                            EV_DOCUMENT_INFO_CREATION_DATE |
-                            EV_DOCUMENT_INFO_MOD_DATE |
                             EV_DOCUMENT_INFO_LINEARIZED |
                             EV_DOCUMENT_INFO_N_PAGES |
                             EV_DOCUMENT_INFO_SECURITY |
@@ -1057,8 +1054,8 @@ pdf_document_get_info (EvDocument *document)
                      "permissions", &permissions,
                      "creator", &(info->creator),
                      "producer", &(info->producer),
-                     "creation-datetime", &(info->creation_date),
-                     "mod-datetime", &(info->modified_date),
+                     "creation-datetime", &created_datetime,
+                     "mod-datetime", &modified_datetime,
                      "linearized", &linearized,
                      "metadata", &metadata,
                      NULL);
@@ -1177,6 +1174,9 @@ pdf_document_get_info (EvDocument *document)
        info->contains_js = EV_DOCUMENT_CONTAINS_JS_UNKNOWN;
 #endif
 
+        ev_document_info_take_created_datetime (info, created_datetime);
+        ev_document_info_take_modified_datetime (info, modified_datetime);
+
        return info;
 }
 
diff --git a/help/reference/libdocument/libevdocument-sections.txt 
b/help/reference/libdocument/libevdocument-sections.txt
index 1a9907432..01211405b 100644
--- a/help/reference/libdocument/libevdocument-sections.txt
+++ b/help/reference/libdocument/libevdocument-sections.txt
@@ -881,6 +881,8 @@ EvDocumentInfoFields
 ev_document_info_new
 ev_document_info_copy
 ev_document_info_free
+ev_document_info_get_created_datetime
+ev_document_info_get_modified_datetime
 ev_document_license_new
 ev_document_license_copy
 ev_document_license_free
diff --git a/libdocument/ev-document-info.c b/libdocument/ev-document-info.c
index 1215c049c..e17314a0c 100644
--- a/libdocument/ev-document-info.c
+++ b/libdocument/ev-document-info.c
@@ -1,6 +1,7 @@
 /*
  *  Copyright (C) 2009 Carlos Garcia Campos
  *  Copyright (C) 2004 Marco Pesenti Gritti
+ *  Copyright © 2021 Christian Persch
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -28,6 +29,9 @@
 typedef struct _EvDocumentInfoExtended EvDocumentInfoExtended;
 struct _EvDocumentInfoExtended {
         EvDocumentInfo info;
+
+        GDateTime *created_datetime;
+        GDateTime *modified_datetime;
 };
 
 G_DEFINE_BOXED_TYPE (EvDocumentInfo, ev_document_info, ev_document_info_copy, ev_document_info_free)
@@ -78,8 +82,8 @@ ev_document_info_copy (EvDocumentInfo *info)
        copy->producer = g_strdup (info->producer);
        copy->linearized = g_strdup (info->linearized);
 
-       copy->creation_date = g_date_time_add (info->creation_date, 0);
-       copy->modified_date = g_date_time_add (info->modified_date, 0);
+        copy->creation_date = info->creation_date;
+        copy->modified_date = info->modified_date;
        copy->layout = info->layout;
        copy->mode = info->mode;
        copy->ui_hints = info->ui_hints;
@@ -87,7 +91,9 @@ ev_document_info_copy (EvDocumentInfo *info)
        copy->n_pages = info->n_pages;
        copy->license = ev_document_license_copy (info->license);
 
-        copy->fields_mask |= info->fields_mask;
+        copy_ex->info.fields_mask |= info->fields_mask;
+        copy_ex->created_datetime = g_date_time_ref (info_ex->created_datetime);
+        copy_ex->modified_datetime = g_date_time_ref (info_ex->modified_datetime);
 
         return &copy_ex->info;
 }
@@ -117,13 +123,106 @@ ev_document_info_free (EvDocumentInfo *info)
        g_free (info->producer);
        g_free (info->linearized);
        g_free (info->security);
-       g_clear_pointer (&(info->creation_date), g_date_time_unref);
-       g_clear_pointer (&(info->modified_date), g_date_time_unref);
        ev_document_license_free (info->license);
 
+        g_clear_pointer (&info_ex->created_datetime, g_date_time_unref);
+        g_clear_pointer (&info_ex->modified_datetime, g_date_time_unref);
+
         g_free (info_ex);
 }
 
+/*
+ * ev_document_info_take_created_datetime:
+ * @info: a #EvDocumentInfo
+ * @datetime: (transfer full): a #GDateTime
+ *
+ * Sets the #GDateTime for when the document was created.
+ */
+void
+ev_document_info_take_created_datetime (EvDocumentInfo *info,
+                                        GDateTime      *datetime)
+{
+        EvDocumentInfoExtended *info_ex = (EvDocumentInfoExtended*)info;
+        gint64 ut;
+
+        g_return_if_fail (info_ex != NULL);
+        g_return_if_fail (info_ex->info.fields_mask & _EV_DOCUMENT_INFO_EXTENDED);
+
+        g_clear_pointer (&info_ex->created_datetime, g_date_time_unref);
+        info_ex->created_datetime = datetime; /* adopts */
+
+        if (datetime != NULL && (ut = g_date_time_to_unix (datetime)) < G_MAXINT) {
+                info_ex->info.creation_date = (GTime) ut;
+                info_ex->info.fields_mask |= EV_DOCUMENT_INFO_CREATION_DATE;
+        } else {
+                info_ex->info.creation_date = 0;
+                info_ex->info.fields_mask &= ~EV_DOCUMENT_INFO_CREATION_DATE;
+        }
+}
+
+/**
+ * ev_document_info_get_created_datetime:
+ * @info: a #EvDocumentInfo
+ *
+ * Returns: (transfer none) (nullable): a #GDateTime for when the document was created
+ */
+GDateTime *
+ev_document_info_get_created_datetime (const EvDocumentInfo *info)
+{
+        EvDocumentInfoExtended *info_ex = (EvDocumentInfoExtended*)info;
+
+        g_return_val_if_fail (info_ex != NULL, NULL);
+        g_return_val_if_fail (info_ex->info.fields_mask & _EV_DOCUMENT_INFO_EXTENDED, NULL);
+
+        return info_ex->created_datetime;
+}
+
+/*
+ * ev_document_info_take_modified_datetime:
+ * @info: a #EvDocumentInfo
+ * @datetime: (transfer full): a #GDateTime
+ *
+ * Sets the #GDateTime for when the document was last modified.
+ */
+void
+ev_document_info_take_modified_datetime (EvDocumentInfo *info,
+                                         GDateTime      *datetime)
+{
+        EvDocumentInfoExtended *info_ex = (EvDocumentInfoExtended*)info;
+        gint64 ut;
+
+        g_return_if_fail (info_ex != NULL);
+        g_return_if_fail (info_ex->info.fields_mask & _EV_DOCUMENT_INFO_EXTENDED);
+
+        g_clear_pointer (&info_ex->modified_datetime, g_date_time_unref);
+        info_ex->modified_datetime = datetime; /* adopts */
+
+        if (datetime != NULL && (ut = g_date_time_to_unix (datetime)) < G_MAXINT) {
+                info_ex->info.modified_date = (GTime) ut;
+                info_ex->info.fields_mask |= EV_DOCUMENT_INFO_MOD_DATE;
+        } else {
+                info_ex->info.modified_date = 0;
+                info_ex->info.fields_mask &= ~EV_DOCUMENT_INFO_MOD_DATE;
+        }
+}
+
+/**
+ * ev_document_info_get_modified_datetime:
+ * @info: a #EvDocumentInfo
+ *
+ * Returns: (transfer none) (nullable): a #GDateTime for when the document was last modified
+ */
+GDateTime *
+ev_document_info_get_modified_datetime (const EvDocumentInfo *info)
+{
+        EvDocumentInfoExtended *info_ex = (EvDocumentInfoExtended*)info;
+
+        g_return_val_if_fail (info_ex != NULL, NULL);
+        g_return_val_if_fail (info_ex->info.fields_mask & _EV_DOCUMENT_INFO_EXTENDED, NULL);
+
+        return info_ex->modified_datetime;
+}
+
 /* EvDocumentLicense */
 G_DEFINE_BOXED_TYPE (EvDocumentLicense, ev_document_license, ev_document_license_copy, 
ev_document_license_free)
 
diff --git a/libdocument/ev-document-info.h b/libdocument/ev-document-info.h
index 1068325a2..52fa4b6d5 100644
--- a/libdocument/ev-document-info.h
+++ b/libdocument/ev-document-info.h
@@ -1,6 +1,7 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8; c-indent-level: 8 -*- */
 /*
  *  Copyright (C) 2000-2003 Marco Pesenti Gritti
+ *  Copyright © 2021 Christian Persch
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -126,8 +127,8 @@ struct _EvDocumentInfo
        char *producer;
        char *linearized;
         char *security;
-       GDateTime *creation_date;
-       GDateTime *modified_date;
+       GTime creation_date G_GNUC_DEPRECATED_FOR(ev_document_info_get_created_datetime);
+       GTime modified_date G_GNUC_DEPRECATED_FOR(ev_document_info_get_modified_datetime);
        EvDocumentLayout layout;
        EvDocumentMode mode;
        guint ui_hints;
@@ -151,6 +152,17 @@ EV_PUBLIC
 EvDocumentInfo *ev_document_info_copy     (EvDocumentInfo *info);
 EV_PUBLIC
 void            ev_document_info_free     (EvDocumentInfo *info);
+EV_PUBLIC
+GDateTime      *ev_document_info_get_created_datetime   (const EvDocumentInfo *info);
+EV_PUBLIC
+GDateTime      *ev_document_info_get_modified_datetime  (const EvDocumentInfo *info);
+
+EV_PRIVATE
+void            ev_document_info_take_created_datetime  (EvDocumentInfo *info,
+                                                         GDateTime      *datetime);
+EV_PRIVATE
+void            ev_document_info_take_modified_datetime (EvDocumentInfo *info,
+                                                         GDateTime      *datetime);
 
 /* EvDocumentLicense */
 #define EV_TYPE_DOCUMENT_LICENSE (ev_document_license_get_type())
diff --git a/properties/ev-properties-view.c b/properties/ev-properties-view.c
index e964af3c4..8d5a96213 100644
--- a/properties/ev-properties-view.c
+++ b/properties/ev-properties-view.c
@@ -369,6 +369,7 @@ ev_properties_view_set_info (EvPropertiesView *properties, const EvDocumentInfo
        GtkWidget *grid;
        gchar     *text;
        gint       row = 0;
+        GDateTime *datetime;
 
        grid = properties->grid;
 
@@ -391,24 +392,23 @@ ev_properties_view_set_info (EvPropertiesView *properties, const EvDocumentInfo
        if (info->fields_mask & EV_DOCUMENT_INFO_CREATOR) {
                set_property (properties, GTK_GRID (grid), CREATOR_PROPERTY, info->creator, &row);
        }
-       if (info->fields_mask & EV_DOCUMENT_INFO_CREATION_DATE) {
-               if (info->creation_date == NULL) {
-                       set_property (properties, GTK_GRID (grid), CREATION_DATE_PROPERTY, NULL, &row);
-               } else {
-                       text = ev_document_misc_format_datetime (info->creation_date);
-                       set_property (properties, GTK_GRID (grid), CREATION_DATE_PROPERTY, text, &row);
-                       g_free (text);
-               }
-       }
-       if (info->fields_mask & EV_DOCUMENT_INFO_MOD_DATE) {
-               if (info->modified_date == NULL) {
-                       set_property (properties, GTK_GRID (grid), MOD_DATE_PROPERTY, NULL, &row);
-               } else {
-                       text = ev_document_misc_format_datetime (info->modified_date);
-                       set_property (properties, GTK_GRID (grid), MOD_DATE_PROPERTY, text, &row);
-                       g_free (text);
-               }
-       }
+
+        datetime = ev_document_info_get_created_datetime (info);
+        if (datetime != NULL) {
+                text = ev_document_misc_format_datetime (datetime);
+                set_property (properties, GTK_GRID (grid), CREATION_DATE_PROPERTY, text, &row);
+                g_free (text);
+        } else {
+                set_property (properties, GTK_GRID (grid), CREATION_DATE_PROPERTY, NULL, &row);
+        }
+        datetime = ev_document_info_get_modified_datetime (info);
+        if (datetime != NULL) {
+                text = ev_document_misc_format_datetime (datetime);
+                set_property (properties, GTK_GRID (grid), MOD_DATE_PROPERTY, text, &row);
+                g_free (text);
+        } else {
+                set_property (properties, GTK_GRID (grid), MOD_DATE_PROPERTY, NULL, &row);
+        }
        if (info->fields_mask & EV_DOCUMENT_INFO_FORMAT) {
                set_property (properties, GTK_GRID (grid), FORMAT_PROPERTY, info->format, &row);
        }


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