[balsa/wip/gtk4: 179/351] address-book-rubrica: Declare it final



commit a40117db742d9bf7d28e20c82a84a6031cb0a493
Author: Peter Bloomfield <PeterBloomfield bellsouth net>
Date:   Thu Feb 15 17:34:52 2018 -0500

    address-book-rubrica: Declare it final
    
    Use G_DECLARE_FINAL_TYPE for LibBalsaAddressBookRubrica and make object
    and class opaque.
    
    LibBalsaAddressBookRubrica made liberal use of the members of
    LibBalsaAddressBookText, which are now private. The path can be changed
    and has a getter and a setter, so ab_rubrica uses those. The other
    members are essentially private to ab_rubrica, so the storage for those
    is duplicated in the LibBalsaAddressBookRubrica object, a small price to
    pay for the convenience of direct access.

 libbalsa/address-book-rubrica.c |  112 +++++++++++++++++++++++----------------
 libbalsa/address-book-rubrica.h |   22 +-------
 2 files changed, 70 insertions(+), 64 deletions(-)
---
diff --git a/libbalsa/address-book-rubrica.c b/libbalsa/address-book-rubrica.c
index 2977de6..c14d6ca 100644
--- a/libbalsa/address-book-rubrica.c
+++ b/libbalsa/address-book-rubrica.c
@@ -90,6 +90,30 @@ static gchar *xml_node_get_text(xmlNodePtr node);
 
 #define CXMLCHARP(x)  ((const xmlChar *)(x))
 
+struct _LibBalsaAddressBookRubrica {
+    LibBalsaAddressBookText parent;
+
+    /*
+     * These are also in LibBalsaAddressBookTextPrivate, but accessing
+     * them with setters and getters would be much overhead, so we
+     * duplicate the storage as the price for having direct access to
+     * them.
+     *
+     * LibBalsaAddressBookTextPrivate also contains the path, but that
+     * can be changed at any time, so we use the getter to make sure we
+     * have the current path.
+     */
+    GSList *item_list;
+
+    time_t mtime;
+
+    LibBalsaCompletion *name_complete;
+};
+
+struct _LibBalsaAddressBookRubricaClass {
+    LibBalsaAddressBookTextClass parent_class;
+};
+
 G_DEFINE_TYPE(LibBalsaAddressBookRubrica, libbalsa_address_book_rubrica,
         LIBBALSA_TYPE_ADDRESS_BOOK_TEXT);
 
@@ -121,28 +145,20 @@ libbalsa_address_book_rubrica_class_init(LibBalsaAddressBookRubricaClass *
 static void
 libbalsa_address_book_rubrica_init(LibBalsaAddressBookRubrica * ab_rubrica)
 {
-    LibBalsaAddressBookText *ab_text =
-        LIBBALSA_ADDRESS_BOOK_TEXT(ab_rubrica);
-    ab_text->path = NULL;
-    ab_text->item_list = NULL;
-    ab_text->mtime = 0;
-
-    ab_text->name_complete =
+    ab_rubrica->name_complete =
         libbalsa_completion_new((LibBalsaCompletionFunc)
                                 completion_data_extract);
-    libbalsa_completion_set_compare(ab_text->name_complete, strncmp_word);
+    libbalsa_completion_set_compare(ab_rubrica->name_complete, strncmp_word);
 }
 
 static void
 libbalsa_address_book_rubrica_finalize(GObject * object)
 {
-    LibBalsaAddressBookText *ab_text;
+    LibBalsaAddressBookRubrica *ab_rubrica;
 
-    ab_text = LIBBALSA_ADDRESS_BOOK_TEXT(object);
+    ab_rubrica = LIBBALSA_ADDRESS_BOOK_RUBRICA(object);
 
-    /* item_list is different from the default
-     * LibBalsaAddressBookText::item_list, so we free it here. */
-    g_slist_free_full(ab_text->item_list, g_object_unref);
+    g_slist_free_full(ab_rubrica->item_list, g_object_unref);
 
     G_OBJECT_CLASS(libbalsa_address_book_rubrica_parent_class)->finalize(object);
 }
@@ -162,8 +178,8 @@ libbalsa_address_book_rubrica_new(const gchar * name, const gchar * path)
     ab_text = LIBBALSA_ADDRESS_BOOK_TEXT(ab_rubrica);
     ab = LIBBALSA_ADDRESS_BOOK(ab_rubrica);
 
-    ab->name = g_strdup(name);
-    ab_text->path = g_strdup(path);
+    libbalsa_address_book_set_name(ab, name);
+    libbalsa_address_book_text_set_path(ab_text, path);
 
     return ab;
 }
@@ -182,7 +198,8 @@ libbalsa_address_book_rubrica_load(LibBalsaAddressBook * ab,
     gchar *filter_hi = NULL;
     GSList *list;
 
-    g_return_val_if_fail(ab_text->path != NULL, LBABERR_CANNOT_READ);
+    g_return_val_if_fail(libbalsa_address_book_text_get_path(ab_text) != NULL,
+                         LBABERR_CANNOT_READ);
 
     /* try to load the xml file if necessary */
     load_res = lbab_rubrica_load_xml(ab_rubrica, NULL);
@@ -192,7 +209,7 @@ libbalsa_address_book_rubrica_load(LibBalsaAddressBook * ab,
     if (filter)
        filter_hi = g_utf8_strup(filter, -1);
 
-    for (list = ab_text->item_list; list; list = list->next) {
+    for (list = ab_rubrica->item_list; list; list = list->next) {
        LibBalsaAddress *address = LIBBALSA_ADDRESS(list->data);
 
        if (!address)
@@ -219,20 +236,19 @@ libbalsa_address_book_rubrica_alias_complete(LibBalsaAddressBook * ab,
 {
     LibBalsaAddressBookRubrica *ab_rubrica =
         LIBBALSA_ADDRESS_BOOK_RUBRICA(ab);
-    LibBalsaAddressBookText *ab_text = LIBBALSA_ADDRESS_BOOK_TEXT(ab);
     GList *list;
     GList *res = NULL;
 
-    if (ab->expand_aliases == FALSE)
+    if (!libbalsa_address_book_get_expand_aliases(ab))
         return NULL;
 
     if (lbab_rubrica_load_xml(ab_rubrica, NULL) != LBABERR_OK)
         return NULL;
 
     for (list =
-         libbalsa_completion_complete(ab_text->name_complete,
+         libbalsa_completion_complete(ab_rubrica->name_complete,
                                       (gchar *) prefix);
-         list; list = list->next) {
+         list != NULL; list = list->next) {
         InternetAddress *ia = ((CompletionData *) list->data)->ia;
         res = g_list_prepend(res, g_object_ref(ia));
     }
@@ -248,6 +264,7 @@ libbalsa_address_book_rubrica_add_address(LibBalsaAddressBook * ab,
     LibBalsaAddressBookRubrica *ab_rubrica =
        LIBBALSA_ADDRESS_BOOK_RUBRICA(ab);
     LibBalsaAddressBookText *ab_text = LIBBALSA_ADDRESS_BOOK_TEXT(ab);
+    const gchar *path;
     int fd;
     xmlDocPtr doc = NULL;
     xmlNodePtr root_element = NULL;
@@ -259,18 +276,19 @@ libbalsa_address_book_rubrica_add_address(LibBalsaAddressBook * ab,
        return result;
 
     /* eject if we already have this address */
-    if (g_slist_find_custom(ab_text->item_list, new_address,
+    if (g_slist_find_custom(ab_rubrica->item_list, new_address,
                            (GCompareFunc) address_compare)) {
        xmlFreeDoc(doc);
        return LBABERR_DUPLICATE;
     }
 
     /* try to open the address book for writing */
-    if ((fd = open(ab_text->path, O_WRONLY | O_CREAT, 0666)) == -1) {
+    path = libbalsa_address_book_text_get_path(ab_text);
+    if ((fd = open(path, O_WRONLY | O_CREAT, 0666)) == -1) {
        xmlFreeDoc(doc);
        return LBABERR_CANNOT_WRITE;
     }
-    if (libbalsa_lock_file(ab_text->path, fd, TRUE, TRUE, FALSE) < 0) {
+    if (libbalsa_lock_file(path, fd, TRUE, TRUE, FALSE) < 0) {
        xmlFreeDoc(doc);
        close(fd);
        return LBABERR_CANNOT_WRITE;
@@ -293,14 +311,14 @@ libbalsa_address_book_rubrica_add_address(LibBalsaAddressBook * ab,
     lbab_insert_address_node(new_address, root_element);
 
     /* store the document */
-    if (xmlSaveFormatFileEnc(ab_text->path, doc, "UTF-8", 1) == -1)
+    if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1)
        result = LBABERR_CANNOT_WRITE;
     else
        result = LBABERR_OK;
-    libbalsa_unlock_file(ab_text->path, fd, FALSE);
+    libbalsa_unlock_file(path, fd, FALSE);
     close(fd);
     xmlFreeDoc(doc);
-    ab_text->mtime = 0;        /* force re-load upon the next access */
+    ab_rubrica->mtime = 0;     /* force re-load upon the next access */
 
     /* done */
     return result;
@@ -329,6 +347,7 @@ libbalsa_address_book_rubrica_modify_address(LibBalsaAddressBook * ab,
     xmlNodePtr card;
     LibBalsaABErr result;
     gboolean found;
+    const gchar *path;
 
     /* try to load the current file */
     if ((result = lbab_rubrica_load_xml(ab_rubrica, &doc)) != LBABERR_OK)
@@ -365,26 +384,27 @@ libbalsa_address_book_rubrica_modify_address(LibBalsaAddressBook * ab,
     if (newval)
        lbab_insert_address_node(newval, root_element);
 
+    path = libbalsa_address_book_text_get_path(ab_text);
     /* try to open the address book for writing */
-    if ((fd = open(ab_text->path, O_WRONLY | O_CREAT, 0666)) == -1) {
+    if ((fd = open(path, O_WRONLY | O_CREAT, 0666)) == -1) {
        xmlFreeDoc(doc);
        return LBABERR_CANNOT_WRITE;
     }
-    if (libbalsa_lock_file(ab_text->path, fd, TRUE, TRUE, FALSE) < 0) {
+    if (libbalsa_lock_file(path, fd, TRUE, TRUE, FALSE) < 0) {
        xmlFreeDoc(doc);
        close(fd);
        return LBABERR_CANNOT_WRITE;
     }
 
     /* store the document */
-    if (xmlSaveFormatFileEnc(ab_text->path, doc, "UTF-8", 1) == -1)
+    if (xmlSaveFormatFileEnc(path, doc, "UTF-8", 1) == -1)
        result = LBABERR_CANNOT_WRITE;
     else
        result = LBABERR_OK;
-    libbalsa_unlock_file(ab_text->path, fd, FALSE);
+    libbalsa_unlock_file(path, fd, FALSE);
     close(fd);
     xmlFreeDoc(doc);
-    ab_text->mtime = 0;        /* force re-load upon the next access */
+    ab_rubrica->mtime = 0;     /* force re-load upon the next access */
 
     /* done */
     return result;
@@ -398,6 +418,7 @@ lbab_rubrica_load_xml(LibBalsaAddressBookRubrica * ab_rubrica,
     LibBalsaAddressBookText *ab_text =
         LIBBALSA_ADDRESS_BOOK_TEXT(ab_rubrica);
     struct stat stat_buf;
+    const gchar *path;
     int fd;
     xmlDocPtr doc = NULL;
     xmlNodePtr root_element = NULL;
@@ -410,28 +431,29 @@ lbab_rubrica_load_xml(LibBalsaAddressBookRubrica * ab_rubrica,
        *docptr = NULL;
 
     /* eject if the file did not change on disk and no document result pointer is passed */
-    if (!docptr && stat(ab_text->path, &stat_buf) == 0) {
-       if (stat_buf.st_mtime == ab_text->mtime)
+    path = libbalsa_address_book_text_get_path(ab_text);
+    if (!docptr && stat(path, &stat_buf) == 0) {
+       if (stat_buf.st_mtime == ab_rubrica->mtime)
            return LBABERR_OK;
        else
-           ab_text->mtime = stat_buf.st_mtime;
+           ab_rubrica->mtime = stat_buf.st_mtime;
     }
 
     /* free old data */
-    libbalsa_clear_slist(&ab_text->item_list, g_object_unref);
-    libbalsa_completion_clear_items(ab_text->name_complete);
+    libbalsa_clear_slist(&ab_rubrica->item_list, g_object_unref);
+    libbalsa_completion_clear_items(ab_rubrica->name_complete);
 
 
     /* try to read the address book */
-    if ((fd = open(ab_text->path, O_RDONLY)) == -1)
+    if ((fd = open(path, O_RDONLY)) == -1)
        return LBABERR_CANNOT_READ;
-    if (libbalsa_lock_file(ab_text->path, fd, FALSE, TRUE, FALSE) < 0) {
+    if (libbalsa_lock_file(path, fd, FALSE, TRUE, FALSE) < 0) {
        close(fd);
        return LBABERR_CANNOT_READ;
     }
 
-    doc = xmlParseFile(ab_text->path);
-    libbalsa_unlock_file(ab_text->path, fd, FALSE);
+    doc = xmlParseFile(path);
+    libbalsa_unlock_file(path, fd, FALSE);
     close(fd);
     if (!doc)
        return LBABERR_CANNOT_READ;
@@ -439,7 +461,7 @@ lbab_rubrica_load_xml(LibBalsaAddressBookRubrica * ab_rubrica,
     /* Get the root element node and extract cards if it is a Rubrica book */
     root_element = xmlDocGetRootElement(doc);
     if (!xmlStrcmp(root_element->name, CXMLCHARP("Rubrica")))
-       ab_text->item_list = extract_cards(root_element->children);
+       ab_rubrica->item_list = extract_cards(root_element->children);
 
     /* return the document if requested of free it */
     if (docptr)
@@ -450,7 +472,7 @@ lbab_rubrica_load_xml(LibBalsaAddressBookRubrica * ab_rubrica,
     /* build the completion list */
     // FIXME - Rubrica provides groups...
     completion_list = NULL;
-    for (list = ab_text->item_list; list; list = list->next) {
+    for (list = ab_rubrica->item_list; list; list = list->next) {
        LibBalsaAddress *address = LIBBALSA_ADDRESS(list->data);
        GList *l;
 
@@ -458,7 +480,7 @@ lbab_rubrica_load_xml(LibBalsaAddressBookRubrica * ab_rubrica,
            continue;
 
        if (address->address_list->next
-           && LIBBALSA_ADDRESS_BOOK(ab_rubrica)->dist_list_mode) {
+           && libbalsa_address_book_get_dist_list_mode(LIBBALSA_ADDRESS_BOOK(ab_rubrica))) {
            /* Create a group address. */
            InternetAddress *ia =
                internet_address_group_new(address->full_name);
@@ -489,7 +511,7 @@ lbab_rubrica_load_xml(LibBalsaAddressBookRubrica * ab_rubrica,
     }
 
     completion_list = g_list_reverse(completion_list);
-    libbalsa_completion_add_items(ab_text->name_complete, completion_list);
+    libbalsa_completion_add_items(ab_rubrica->name_complete, completion_list);
     g_list_free(completion_list);
 
     return LBABERR_OK;
diff --git a/libbalsa/address-book-rubrica.h b/libbalsa/address-book-rubrica.h
index 571ce62..2902c5a 100644
--- a/libbalsa/address-book-rubrica.h
+++ b/libbalsa/address-book-rubrica.h
@@ -30,25 +30,9 @@
 
 #include "address-book-text.h"
 
-#define LIBBALSA_TYPE_ADDRESS_BOOK_RUBRICA             (libbalsa_address_book_rubrica_get_type())
-#define LIBBALSA_ADDRESS_BOOK_RUBRICA(obj)             (G_TYPE_CHECK_INSTANCE_CAST (obj, 
LIBBALSA_TYPE_ADDRESS_BOOK_RUBRICA, LibBalsaAddressBookRubrica))
-#define LIBBALSA_ADDRESS_BOOK_RUBRICA_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST (klass, 
LIBBALSA_TYPE_ADDRESS_BOOK_RUBRICA, LibBalsaAddressBookRubricaClass))
-#define LIBBALSA_IS_ADDRESS_BOOK_RUBRICA(obj)          (G_TYPE_CHECK_INSTANCE_TYPE (obj, 
LIBBALSA_TYPE_ADDRESS_BOOK_RUBRICA))
-#define LIBBALSA_IS_ADDRESS_BOOK_RUBRICA_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE (klass, 
LIBBALSA_TYPE_ADDRESS_BOOK_RUBRICA))
-
-struct _LibBalsaAddressBookRubrica {
-    LibBalsaAddressBookText parent;
-};
-
-struct _LibBalsaAddressBookRubricaClass {
-    LibBalsaAddressBookTextClass parent_class;
-};
-
-typedef struct _LibBalsaAddressBookRubrica LibBalsaAddressBookRubrica;
-typedef struct _LibBalsaAddressBookRubricaClass
-    LibBalsaAddressBookRubricaClass;
-
-GType libbalsa_address_book_rubrica_get_type(void);
+#define LIBBALSA_TYPE_ADDRESS_BOOK_RUBRICA (libbalsa_address_book_rubrica_get_type())
+G_DECLARE_FINAL_TYPE(LibBalsaAddressBookRubrica, libbalsa_address_book_rubrica,
+                     LIBBALSA, ADDRESS_BOOK_RUBRICA, LibBalsaAddressBookText)
 
 LibBalsaAddressBook *libbalsa_address_book_rubrica_new(const gchar * name,
                                                       const gchar * path);


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