[devhelp/wip/empty-book-manager] BookManager: remove all the implementation



commit b06ef6a150d0c4b7c7f077431006447e9c35593f
Author: Sébastien Wilmet <swilmet gnome org>
Date:   Fri Apr 27 17:26:41 2018 +0200

    BookManager: remove all the implementation
    
    There is now a new infrastructure: DhProfile, DhSettings, DhBookList.
    
    So the other classes in Devhelp will need to be ported to the new
    infrastructure. Now the DhBookManager is empty and doesn't send signals.
    Some of the DhBookManager API is still used in some IDEs, so to not
    break those apps we must not remove completely the API.
    
    But if IDEs are not adapted they will still work fine, because the
    default DhProfile will be used in that case, which corresponds exactly
    to how DhBookManager was implemented (it'll be the same content).

 devhelp/dh-book-manager.c |  560 +--------------------------------------------
 1 files changed, 12 insertions(+), 548 deletions(-)
---
diff --git a/devhelp/dh-book-manager.c b/devhelp/dh-book-manager.c
index 813a880..b6b4eff 100644
--- a/devhelp/dh-book-manager.c
+++ b/devhelp/dh-book-manager.c
@@ -23,111 +23,23 @@
  * along with Devhelp.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#include "config.h"
 #include "dh-book-manager.h"
 #include "dh-book.h"
-#include "dh-settings.h"
-#include "dh-util-lib.h"
 
 /**
  * SECTION:dh-book-manager
  * @Title: DhBookManager
  * @Short_description: Aggregation of all #DhBook's
  *
- * #DhBookManager is a singleton class containing all the #DhBook's.
- */
-
-/* TODO: Re-architect DhBookManager and DhBook.
- *
- * DhBookManager and DhBook are not very flexible:
- * 1. Whether a DhBook is enabled or disabled is hard-coded into the DhBook
- * objects. It's bound to the "books-disabled" GSetting.
- *
- * 2. The list of directories where DhBookManager searches the books is more or
- * less hard-coded inside DhBookManager (it's just configurable with XDG env
- * variables, see the populate() function, it's documented in the README). It
- * would be nice to have total control over which directories are searched,
- * without duplicating them if two different "views" have a directory in common
- * (especially not duplicating GFileMonitor's).
- *
- * Ideas:
- * - Create a DhBookSelection class (or set of classes, with maybe an interface
- *   or base class), and remove the "enabled" property from DhBook. The
- *   books-disabled GSetting would be implemented by one implementation of
- *   DhBookSelection. A :book-selection property could be added to some classes,
- *   and if that property is NULL take the "default selection" (by default the
- *   one for the books-disabled GSetting). Another possible name: DhBookFilter
- *   (or have both).
- *
- *   Have ::book-added and ::book-removed signals. A single ::changed signal is
- *   I think not appropriate: for example for DhBookTree, a full repopulate
- *   could be done when ::changed is emitted, but in that case DhBookTree would
- *   loose its selection.
- *
- * - Factor out a DhBookListDirectory class, finding and monitoring a list of
- *   books in one directory. The constructor would roughly be
- *   find_books_in_dir(). DhBookManager would just contain a list of
- *   DhBookListDirectory objects, ensuring that there are no duplicates. A list
- *   of DhBookListDirectory's could be added to a DhBookSelection, and it's
- *   DhBookSelection which applies priorities. So two different DhBookSelection
- *   objects could apply different priorities between the directories.
- *   Ensuring that a book ID is unique would be done by each DhBookListDirectory
- *   object, and also by DhBookSelection; which means that Devhelp would use
- *   more memory since some DhBooks would not be freed since they are contained
- *   in different DhBookListDirectory objects, but the index files anyway needed
- *   to be parsed to know the book ID, so it's not a big issue.
- *
- * Relevant bugzilla tickets:
- * - https://bugzilla.gnome.org/show_bug.cgi?id=784491
- *   "BookManager: allow custom search paths for documentation"
- *
- *   For gnome-builder needs.
- *
- * - https://bugzilla.gnome.org/show_bug.cgi?id=792068
- *   "Make it work with Flatpak"
- *
- *   The directories probably need to be adjusted.
+ * #DhBookManager was a singleton class containing all the #DhBook's. It is now
+ * empty.
  *
- * - https://bugzilla.gnome.org/show_bug.cgi?id=761284
- *   "Have the latest stable/unstable GNOME API references"
- *
- *   The books can be downloaded in different directories, one directory for
- *   "GNOME stable" and another directory for "GNOME unstable" (or for specific
- *   versions). Switching between versions would just be a matter of changing
- *   the DhBookSelection.
- *
- * - https://bugzilla.gnome.org/show_bug.cgi?id=118423
- *   "Individual bookshelfs"
- *
- * - https://bugzilla.gnome.org/show_bug.cgi?id=764441
- *   "Implement language switching feature"
- *
- *   Basically have the same book ID/name available for different programming
- *   languages. DhBookSelection could filter by programming language. Out of
- *   scope for now, because language switching is implemented in JavaScript for
- *   hot-doc, and gtk-doc doesn't support yet producing documentation for
- *   different programming languages.
+ * <warning>
+ * This class is entirely deprecated, you need to use #DhProfile, #DhSettings
+ * and #DhBookList instead.
+ * </warning>
  */
 
-#define NEW_POSSIBLE_BOOK_TIMEOUT_SECS 5
-
-typedef struct {
-        DhBookManager *book_manager; /* unowned */
-        GFile *book_directory;
-        guint timeout_id;
-} NewPossibleBookData;
-
-typedef struct {
-        /* The list of all DhBooks* found in the system */
-        GList *books;
-
-        /* GFile* -> GFileMonitor* */
-        GHashTable *monitors;
-
-        /* List of NewPossibleBookData* */
-        GSList *new_possible_books_data;
-} DhBookManagerPrivate;
-
 enum {
         SIGNAL_BOOK_CREATED,
         SIGNAL_BOOK_DELETED,
@@ -140,60 +52,7 @@ static guint signals[N_SIGNALS] = { 0 };
 
 static DhBookManager *singleton = NULL;
 
-G_DEFINE_TYPE_WITH_PRIVATE (DhBookManager, dh_book_manager, G_TYPE_OBJECT);
-
-static gboolean create_book_from_index_file (DhBookManager *book_manager,
-                                             GFile         *index_file);
-
-static NewPossibleBookData *
-new_possible_book_data_new (DhBookManager *book_manager,
-                            GFile         *book_directory)
-{
-        NewPossibleBookData *data;
-
-        data = g_new0 (NewPossibleBookData, 1);
-        data->book_manager = book_manager;
-        data->book_directory = g_object_ref (book_directory);
-
-        return data;
-}
-
-static void
-new_possible_book_data_free (gpointer _data)
-{
-        NewPossibleBookData *data = _data;
-
-        if (data == NULL)
-                return;
-
-        g_clear_object (&data->book_directory);
-
-        if (data->timeout_id != 0)
-                g_source_remove (data->timeout_id);
-
-        g_free (data);
-}
-
-static void
-dh_book_manager_dispose (GObject *object)
-{
-        DhBookManagerPrivate *priv;
-
-        priv = dh_book_manager_get_instance_private (DH_BOOK_MANAGER (object));
-
-        g_list_free_full (priv->books, g_object_unref);
-        priv->books = NULL;
-
-        if (priv->monitors != NULL) {
-                g_hash_table_destroy (priv->monitors);
-                priv->monitors = NULL;
-        }
-
-        g_slist_free_full (priv->new_possible_books_data, new_possible_book_data_free);
-        priv->new_possible_books_data = NULL;
-
-        G_OBJECT_CLASS (dh_book_manager_parent_class)->dispose (object);
-}
+G_DEFINE_TYPE (DhBookManager, dh_book_manager, G_TYPE_OBJECT);
 
 static void
 dh_book_manager_finalize (GObject *object)
@@ -209,7 +68,6 @@ dh_book_manager_class_init (DhBookManagerClass *klass)
 {
         GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-        object_class->dispose = dh_book_manager_dispose;
         object_class->finalize = dh_book_manager_finalize;
 
         /**
@@ -274,404 +132,20 @@ dh_book_manager_class_init (DhBookManagerClass *klass)
 }
 
 static void
-remove_book (DhBookManager *book_manager,
-             DhBook        *book)
-{
-        DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
-        GList *node;
-
-        node = g_list_find (priv->books, book);
-
-        if (node != NULL) {
-                priv->books = g_list_delete_link (priv->books, node);
-
-                g_signal_emit (book_manager,
-                               signals[SIGNAL_BOOK_DELETED],
-                               0,
-                               book);
-
-                g_object_unref (book);
-        }
-}
-
-static void
-book_deleted_cb (DhBook        *book,
-                 DhBookManager *book_manager)
-{
-        remove_book (book_manager, book);
-}
-
-static void
-book_updated_cb (DhBook        *book,
-                 DhBookManager *book_manager)
-{
-        GFile *index_file;
-
-        /* Re-create the DhBook to parse again the index file. */
-
-        index_file = dh_book_get_index_file (book);
-        g_object_ref (index_file);
-
-        remove_book (book_manager, book);
-
-        create_book_from_index_file (book_manager, index_file);
-        g_object_unref (index_file);
-}
-
-static void
-book_enabled_cb (DhBook        *book,
-                 DhBookManager *book_manager)
-{
-        DhSettings *settings;
-
-        settings = dh_settings_get_default ();
-        g_return_if_fail (!dh_settings_is_book_enabled (settings, book));
-        dh_settings_set_book_enabled (settings, book, TRUE);
-
-        g_signal_emit (book_manager,
-                       signals[SIGNAL_BOOK_ENABLED],
-                       0,
-                       book);
-}
-
-static void
-book_disabled_cb (DhBook        *book,
-                  DhBookManager *book_manager)
-{
-        DhSettings *settings;
-
-        settings = dh_settings_get_default ();
-        g_return_if_fail (dh_settings_is_book_enabled (settings, book));
-        dh_settings_set_book_enabled (settings, book, FALSE);
-
-        g_signal_emit (book_manager,
-                       signals[SIGNAL_BOOK_DISABLED],
-                       0,
-                       book);
-}
-
-/* Returns TRUE if "successful", FALSE if the next possible index file in the
- * book directory needs to be tried.
- */
-static gboolean
-create_book_from_index_file (DhBookManager *book_manager,
-                             GFile         *index_file)
-{
-        DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
-        DhBook *book;
-        DhSettings *settings;
-        GList *l;
-
-        /* Check if a DhBook at the same location has already been loaded. */
-        for (l = priv->books; l != NULL; l = l->next) {
-                DhBook *cur_book = DH_BOOK (l->data);
-                GFile *cur_index_file;
-
-                cur_index_file = dh_book_get_index_file (cur_book);
-
-                if (g_file_equal (index_file, cur_index_file))
-                        return TRUE;
-        }
-
-        book = dh_book_new (index_file);
-        if (book == NULL)
-                return FALSE;
-
-        /* Check if book with same ID was already loaded in the manager (we need
-         * to force unique book IDs).
-         */
-        if (g_list_find_custom (priv->books,
-                                book,
-                                (GCompareFunc)dh_book_cmp_by_id)) {
-                g_object_unref (book);
-                return TRUE;
-        }
-
-        priv->books = g_list_insert_sorted (priv->books,
-                                            book,
-                                            (GCompareFunc)dh_book_cmp_by_title);
-
-        settings = dh_settings_get_default ();
-        dh_book_set_enabled (book, dh_settings_is_book_enabled (settings, book));
-
-        g_signal_connect_object (book,
-                                 "deleted",
-                                 G_CALLBACK (book_deleted_cb),
-                                 book_manager,
-                                 0);
-
-        g_signal_connect_object (book,
-                                 "updated",
-                                 G_CALLBACK (book_updated_cb),
-                                 book_manager,
-                                 0);
-
-        g_signal_connect_object (book,
-                                 "enabled",
-                                 G_CALLBACK (book_enabled_cb),
-                                 book_manager,
-                                 0);
-
-        g_signal_connect_object (book,
-                                 "disabled",
-                                 G_CALLBACK (book_disabled_cb),
-                                 book_manager,
-                                 0);
-
-        g_signal_emit (book_manager,
-                       signals[SIGNAL_BOOK_CREATED],
-                       0,
-                       book);
-
-        return TRUE;
-}
-
-static void
-create_book_from_directory (DhBookManager *book_manager,
-                            GFile         *book_directory)
-{
-        GSList *possible_index_files;
-        GSList *l;
-
-        possible_index_files = _dh_util_get_possible_index_files (book_directory);
-
-        for (l = possible_index_files; l != NULL; l = l->next) {
-                GFile *index_file = G_FILE (l->data);
-
-                if (create_book_from_index_file (book_manager, index_file))
-                        break;
-        }
-
-        g_slist_free_full (possible_index_files, g_object_unref);
-}
-
-static gboolean
-new_possible_book_timeout_cb (gpointer user_data)
-{
-        NewPossibleBookData *data = user_data;
-        DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (data->book_manager);
-
-        data->timeout_id = 0;
-
-        create_book_from_directory (data->book_manager, data->book_directory);
-
-        priv->new_possible_books_data = g_slist_remove (priv->new_possible_books_data, data);
-        new_possible_book_data_free (data);
-
-        return G_SOURCE_REMOVE;
-}
-
-static void
-books_directory_changed_cb (GFileMonitor      *directory_monitor,
-                            GFile             *file,
-                            GFile             *other_file,
-                            GFileMonitorEvent  event_type,
-                            DhBookManager     *book_manager)
-{
-        DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
-        NewPossibleBookData *data;
-
-        /* With the GFileMonitor here we only handle events for new directories
-         * created. Book deletions and updates are handled by the GFileMonitor
-         * in each DhBook object.
-         */
-        if (event_type != G_FILE_MONITOR_EVENT_CREATED)
-                return;
-
-        data = new_possible_book_data_new (book_manager, file);
-
-        /* We add a timeout of several seconds so that we give time to the whole
-         * documentation to get installed. If we don't do this, we may end up
-         * trying to add the new book when even the *.devhelp2 index file is not
-         * installed yet.
-         */
-        data->timeout_id = g_timeout_add_seconds (NEW_POSSIBLE_BOOK_TIMEOUT_SECS,
-                                                  new_possible_book_timeout_cb,
-                                                  data);
-
-        priv->new_possible_books_data = g_slist_prepend (priv->new_possible_books_data, data);
-}
-
-static void
-monitor_books_directory (DhBookManager *book_manager,
-                         GFile         *books_directory)
-{
-        DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
-        GFileMonitor *directory_monitor;
-        GError *error = NULL;
-
-        /* If monitor already exists, do not re-create it. */
-        if (priv->monitors != NULL &&
-            g_hash_table_lookup (priv->monitors, books_directory) != NULL) {
-                return;
-        }
-
-        directory_monitor = g_file_monitor_directory (books_directory,
-                                                      G_FILE_MONITOR_NONE,
-                                                      NULL,
-                                                      &error);
-
-        if (error != NULL) {
-                gchar *parse_name;
-
-                parse_name = g_file_get_parse_name (books_directory);
-
-                g_warning ("Failed to create file monitor on directory “%s”: %s",
-                           parse_name,
-                           error->message);
-
-                g_free (parse_name);
-                g_clear_error (&error);
-        }
-
-        if (directory_monitor != NULL) {
-                if (G_UNLIKELY (priv->monitors == NULL)) {
-                        priv->monitors = g_hash_table_new_full (g_file_hash,
-                                                                (GEqualFunc) g_file_equal,
-                                                                g_object_unref,
-                                                                g_object_unref);
-                }
-
-                g_hash_table_insert (priv->monitors,
-                                     g_object_ref (books_directory),
-                                     directory_monitor);
-
-                g_signal_connect_object (directory_monitor,
-                                         "changed",
-                                         G_CALLBACK (books_directory_changed_cb),
-                                         book_manager,
-                                         0);
-        }
-}
-
-static void
-find_books_in_dir (DhBookManager *book_manager,
-                   const gchar   *dir_path)
-{
-        GFile *directory;
-        GFileEnumerator *enumerator;
-        GError *error = NULL;
-
-        g_return_if_fail (dir_path != NULL);
-
-        directory = g_file_new_for_path (dir_path);
-
-        enumerator = g_file_enumerate_children (directory,
-                                                G_FILE_ATTRIBUTE_STANDARD_NAME,
-                                                G_FILE_QUERY_INFO_NONE,
-                                                NULL,
-                                                &error);
-
-        if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
-                g_clear_error (&error);
-                goto out;
-        }
-
-        if (error != NULL) {
-                g_warning ("Error when reading directory '%s': %s",
-                           dir_path,
-                           error->message);
-                g_clear_error (&error);
-                goto out;
-        }
-
-        monitor_books_directory (book_manager, directory);
-
-        while (TRUE) {
-                GFile *book_directory = NULL;
-
-                g_file_enumerator_iterate (enumerator, NULL, &book_directory, NULL, &error);
-
-                if (error != NULL) {
-                        g_warning ("Error when enumerating directory '%s': %s",
-                                   dir_path,
-                                   error->message);
-                        g_clear_error (&error);
-                        break;
-                }
-
-                if (book_directory == NULL)
-                        break;
-
-                create_book_from_directory (book_manager, book_directory);
-        }
-
-out:
-        g_object_unref (directory);
-        g_clear_object (&enumerator);
-}
-
-static void
-find_books_in_data_dir (DhBookManager *book_manager,
-                        const gchar   *data_dir)
-{
-        gchar *dir;
-
-        g_return_if_fail (data_dir != NULL);
-
-        dir = g_build_filename (data_dir, "gtk-doc", "html", NULL);
-        find_books_in_dir (book_manager, dir);
-        g_free (dir);
-
-        dir = g_build_filename (data_dir, "devhelp", "books", NULL);
-        find_books_in_dir (book_manager, dir);
-        g_free (dir);
-}
-
-static void
-populate (DhBookManager *book_manager)
-{
-        const gchar * const *system_dirs;
-        gint i;
-
-        find_books_in_data_dir (book_manager, g_get_user_data_dir ());
-
-        system_dirs = g_get_system_data_dirs ();
-        g_return_if_fail (system_dirs != NULL);
-
-        for (i = 0; system_dirs[i] != NULL; i++) {
-                find_books_in_data_dir (book_manager, system_dirs[i]);
-        }
-
-        /* For Flatpak, to see the books installed on the host by traditional
-         * Linux distro packages.
-         *
-         * It is not a good idea to add the directory to XDG_DATA_DIRS, see:
-         * https://github.com/flatpak/flatpak/issues/1299
-         * "all sorts of things will break if we add all host config to each
-         * app, which is totally opposite to the entire point of flatpak."
-         * "i don't think XDG_DATA_DIRS is the right thing, because all sorts of
-         * libraries will start reading files from there, like dconf, dbus,
-         * service files, mimetypes, etc. It would be preferable to have
-         * something that targeted just gtk-doc files."
-         *
-         * So instead of adapting XDG_DATA_DIRS, add the directory here, with
-         * the path hard-coded.
-         *
-         * https://bugzilla.gnome.org/show_bug.cgi?id=792068
-         */
-#ifdef FLATPAK_BUILD
-        find_books_in_data_dir (book_manager, "/run/host/usr/share");
-#endif
-}
-
-static void
 dh_book_manager_init (DhBookManager *book_manager)
 {
-        populate (book_manager);
 }
 
 /**
  * dh_book_manager_new:
  *
- * Returns: (transfer full): the #DhBookManager singleton instance. You need to
- * unref it when no longer needed.
- * Deprecated: 3.26: Call dh_book_manager_get_singleton() instead.
+ * Returns: (transfer full): a new #DhBookManager object.
+ * Deprecated: 3.26: the #DhBookManager class is deprecated.
  */
 DhBookManager *
 dh_book_manager_new (void)
 {
-        return g_object_ref (dh_book_manager_get_singleton ());
+        return g_object_new (DH_TYPE_BOOK_MANAGER, NULL);
 }
 
 /**
@@ -705,11 +179,7 @@ _dh_book_manager_unref_singleton (void)
  * dh_book_manager_populate:
  * @book_manager: a #DhBookManager.
  *
- * Populates the #DhBookManager with all books found on the system and user
- * directories.
- *
- * Deprecated: 3.26: The #DhBookManager is now automatically populated when the
- * object is created, there is no need to call this function anymore.
+ * Deprecated: 3.26: the #DhBookManager class is deprecated.
  */
 void
 dh_book_manager_populate (DhBookManager *book_manager)
@@ -726,11 +196,5 @@ dh_book_manager_populate (DhBookManager *book_manager)
 GList *
 dh_book_manager_get_books (DhBookManager *book_manager)
 {
-        DhBookManagerPrivate *priv;
-
-        g_return_val_if_fail (DH_IS_BOOK_MANAGER (book_manager), NULL);
-
-        priv = dh_book_manager_get_instance_private (book_manager);
-
-        return priv->books;
+        return NULL;
 }


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