|
Packit |
116408 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
|
|
Packit |
116408 |
/*
|
|
Packit |
116408 |
* Copyright (C) 2002 CodeFactory AB
|
|
Packit |
116408 |
* Copyright (C) 2002 Mikael Hallendal <micke@imendio.com>
|
|
Packit |
116408 |
* Copyright (C) 2004-2008 Imendio AB
|
|
Packit |
116408 |
* Copyright (C) 2010 Lanedo GmbH
|
|
Packit |
116408 |
* Copyright (C) 2012 Thomas Bechtold <toabctl@gnome.org>
|
|
Packit |
116408 |
* Copyright (C) 2017 Sébastien Wilmet <swilmet@gnome.org>
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* This program is free software; you can redistribute it and/or
|
|
Packit |
116408 |
* modify it under the terms of the GNU General Public License as
|
|
Packit |
116408 |
* published by the Free Software Foundation; either version 2 of the
|
|
Packit |
116408 |
* License, or (at your option) any later version.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* This program is distributed in the hope that it will be useful,
|
|
Packit |
116408 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
116408 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
116408 |
* General Public License for more details.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* You should have received a copy of the GNU General Public License
|
|
Packit |
116408 |
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
|
|
Packit |
116408 |
#include "config.h"
|
|
Packit |
116408 |
#include "dh-book-manager.h"
|
|
Packit |
116408 |
#include "dh-book.h"
|
|
Packit |
116408 |
#include "dh-settings.h"
|
|
Packit |
116408 |
#include "dh-util.h"
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* SECTION:dh-book-manager
|
|
Packit |
116408 |
* @Title: DhBookManager
|
|
Packit |
116408 |
* @Short_description: Aggregation of all #DhBook's
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* #DhBookManager is a singleton class containing all the #DhBook's.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* TODO: Re-architect DhBookManager and DhBook.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* DhBookManager and DhBook are not very flexible:
|
|
Packit |
116408 |
* 1. Whether a DhBook is enabled or disabled is hard-coded into the DhBook
|
|
Packit |
116408 |
* objects. It's bound to the "books-disabled" GSetting.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* 2. The list of directories where DhBookManager searches the books is more or
|
|
Packit |
116408 |
* less hard-coded inside DhBookManager (it's just configurable with XDG env
|
|
Packit |
116408 |
* variables, see the populate() function, it's documented in the README). It
|
|
Packit |
116408 |
* would be nice to have total control over which directories are searched,
|
|
Packit |
116408 |
* without duplicating them if two different "views" have a directory in common
|
|
Packit |
116408 |
* (especially not duplicating GFileMonitor's).
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Ideas:
|
|
Packit |
116408 |
* - Create a DhBookSelection class (or set of classes, with maybe an interface
|
|
Packit |
116408 |
* or base class), and remove the "enabled" property from DhBook. The
|
|
Packit |
116408 |
* books-disabled GSetting would be implemented by one implementation of
|
|
Packit |
116408 |
* DhBookSelection. A :book-selection property could be added to some classes,
|
|
Packit |
116408 |
* and if that property is NULL take the "default selection" (by default the
|
|
Packit |
116408 |
* one for the books-disabled GSetting). Another possible name: DhBookFilter
|
|
Packit |
116408 |
* (or have both).
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Have ::book-added and ::book-removed signals. A single ::changed signal is
|
|
Packit |
116408 |
* I think not appropriate: for example for DhBookTree, a full repopulate
|
|
Packit |
116408 |
* could be done when ::changed is emitted, but in that case DhBookTree would
|
|
Packit |
116408 |
* loose its selection.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* - Factor out a DhBookListDirectory class, finding and monitoring a list of
|
|
Packit |
116408 |
* books in one directory. The constructor would roughly be
|
|
Packit |
116408 |
* find_books_in_dir(). DhBookManager would just contain a list of
|
|
Packit |
116408 |
* DhBookListDirectory objects, ensuring that there are no duplicates. A list
|
|
Packit |
116408 |
* of DhBookListDirectory's could be added to a DhBookSelection, and it's
|
|
Packit |
116408 |
* DhBookSelection which applies priorities. So two different DhBookSelection
|
|
Packit |
116408 |
* objects could apply different priorities between the directories.
|
|
Packit |
116408 |
* Ensuring that a book ID is unique would be done by each DhBookListDirectory
|
|
Packit |
116408 |
* object, and also by DhBookSelection; which means that Devhelp would use
|
|
Packit |
116408 |
* more memory since some DhBooks would not be freed since they are contained
|
|
Packit |
116408 |
* in different DhBookListDirectory objects, but the index files anyway needed
|
|
Packit |
116408 |
* to be parsed to know the book ID, so it's not a big issue.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Relevant bugzilla tickets:
|
|
Packit |
116408 |
* - https://bugzilla.gnome.org/show_bug.cgi?id=784491
|
|
Packit |
116408 |
* "BookManager: allow custom search paths for documentation"
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* For gnome-builder needs.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* - https://bugzilla.gnome.org/show_bug.cgi?id=792068
|
|
Packit |
116408 |
* "Make it work with Flatpak"
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* The directories probably need to be adjusted.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* - https://bugzilla.gnome.org/show_bug.cgi?id=761284
|
|
Packit |
116408 |
* "Have the latest stable/unstable GNOME API references"
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* The books can be downloaded in different directories, one directory for
|
|
Packit |
116408 |
* "GNOME stable" and another directory for "GNOME unstable" (or for specific
|
|
Packit |
116408 |
* versions). Switching between versions would just be a matter of changing
|
|
Packit |
116408 |
* the DhBookSelection.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* - https://bugzilla.gnome.org/show_bug.cgi?id=118423
|
|
Packit |
116408 |
* "Individual bookshelfs"
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* - https://bugzilla.gnome.org/show_bug.cgi?id=764441
|
|
Packit |
116408 |
* "Implement language switching feature"
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Basically have the same book ID/name available for different programming
|
|
Packit |
116408 |
* languages. DhBookSelection could filter by programming language. Out of
|
|
Packit |
116408 |
* scope for now, because language switching is implemented in JavaScript for
|
|
Packit |
116408 |
* hot-doc, and gtk-doc doesn't support yet producing documentation for
|
|
Packit |
116408 |
* different programming languages.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
|
|
Packit |
116408 |
#define NEW_POSSIBLE_BOOK_TIMEOUT_SECS 5
|
|
Packit |
116408 |
|
|
Packit |
116408 |
typedef struct {
|
|
Packit |
116408 |
DhBookManager *book_manager; /* unowned */
|
|
Packit |
116408 |
GFile *book_directory;
|
|
Packit |
116408 |
guint timeout_id;
|
|
Packit |
116408 |
} NewPossibleBookData;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
typedef struct {
|
|
Packit |
116408 |
/* The list of all DhBooks* found in the system */
|
|
Packit |
116408 |
GList *books;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* GFile* -> GFileMonitor* */
|
|
Packit |
116408 |
GHashTable *monitors;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* List of NewPossibleBookData* */
|
|
Packit |
116408 |
GSList *new_possible_books_data;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* List of book IDs (gchar*) currently disabled */
|
|
Packit |
116408 |
GList *books_disabled;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
guint group_by_language : 1;
|
|
Packit |
116408 |
} DhBookManagerPrivate;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
enum {
|
|
Packit |
116408 |
SIGNAL_BOOK_CREATED,
|
|
Packit |
116408 |
SIGNAL_BOOK_DELETED,
|
|
Packit |
116408 |
SIGNAL_BOOK_ENABLED,
|
|
Packit |
116408 |
SIGNAL_BOOK_DISABLED,
|
|
Packit |
116408 |
N_SIGNALS
|
|
Packit |
116408 |
};
|
|
Packit |
116408 |
|
|
Packit |
116408 |
enum {
|
|
Packit |
116408 |
PROP_0,
|
|
Packit |
116408 |
PROP_GROUP_BY_LANGUAGE
|
|
Packit |
116408 |
};
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static guint signals[N_SIGNALS] = { 0 };
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static DhBookManager *singleton = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
G_DEFINE_TYPE_WITH_PRIVATE (DhBookManager, dh_book_manager, G_TYPE_OBJECT);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static gboolean create_book_from_index_file (DhBookManager *book_manager,
|
|
Packit |
116408 |
GFile *index_file);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static NewPossibleBookData *
|
|
Packit |
116408 |
new_possible_book_data_new (DhBookManager *book_manager,
|
|
Packit |
116408 |
GFile *book_directory)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
NewPossibleBookData *data;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
data = g_new0 (NewPossibleBookData, 1);
|
|
Packit |
116408 |
data->book_manager = book_manager;
|
|
Packit |
116408 |
data->book_directory = g_object_ref (book_directory);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return data;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
new_possible_book_data_free (gpointer _data)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
NewPossibleBookData *data = _data;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (data == NULL)
|
|
Packit |
116408 |
return;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_clear_object (&data->book_directory);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (data->timeout_id != 0)
|
|
Packit |
116408 |
g_source_remove (data->timeout_id);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_free (data);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
dh_book_manager_get_property (GObject *object,
|
|
Packit |
116408 |
guint prop_id,
|
|
Packit |
116408 |
GValue *value,
|
|
Packit |
116408 |
GParamSpec *pspec)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManager *book_manager = DH_BOOK_MANAGER (object);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
switch (prop_id)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
case PROP_GROUP_BY_LANGUAGE:
|
|
Packit |
116408 |
g_value_set_boolean (value, dh_book_manager_get_group_by_language (book_manager));
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
default:
|
|
Packit |
116408 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
dh_book_manager_set_property (GObject *object,
|
|
Packit |
116408 |
guint prop_id,
|
|
Packit |
116408 |
const GValue *value,
|
|
Packit |
116408 |
GParamSpec *pspec)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManager *book_manager = DH_BOOK_MANAGER (object);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
switch (prop_id)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
case PROP_GROUP_BY_LANGUAGE:
|
|
Packit |
116408 |
dh_book_manager_set_group_by_language (book_manager, g_value_get_boolean (value));
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
default:
|
|
Packit |
116408 |
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
dh_book_manager_dispose (GObject *object)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv = dh_book_manager_get_instance_private (DH_BOOK_MANAGER (object));
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_list_free_full (priv->books, g_object_unref);
|
|
Packit |
116408 |
priv->books = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (priv->monitors != NULL) {
|
|
Packit |
116408 |
g_hash_table_destroy (priv->monitors);
|
|
Packit |
116408 |
priv->monitors = NULL;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_slist_free_full (priv->new_possible_books_data, new_possible_book_data_free);
|
|
Packit |
116408 |
priv->new_possible_books_data = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
G_OBJECT_CLASS (dh_book_manager_parent_class)->dispose (object);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
dh_book_manager_finalize (GObject *object)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManager *book_manager = DH_BOOK_MANAGER (object);
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_list_free_full (priv->books_disabled, g_free);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (singleton == book_manager)
|
|
Packit |
116408 |
singleton = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
G_OBJECT_CLASS (dh_book_manager_parent_class)->finalize (object);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
dh_book_manager_class_init (DhBookManagerClass *klass)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
object_class->get_property = dh_book_manager_get_property;
|
|
Packit |
116408 |
object_class->set_property = dh_book_manager_set_property;
|
|
Packit |
116408 |
object_class->dispose = dh_book_manager_dispose;
|
|
Packit |
116408 |
object_class->finalize = dh_book_manager_finalize;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* DhBookManager::book-created:
|
|
Packit |
116408 |
* @book_manager: the #DhBookManager.
|
|
Packit |
116408 |
* @book: the created #DhBook.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_CREATED] =
|
|
Packit |
116408 |
g_signal_new ("book-created",
|
|
Packit |
116408 |
G_TYPE_FROM_CLASS (klass),
|
|
Packit |
116408 |
G_SIGNAL_RUN_LAST,
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
NULL, NULL, NULL,
|
|
Packit |
116408 |
G_TYPE_NONE,
|
|
Packit |
116408 |
1,
|
|
Packit |
116408 |
DH_TYPE_BOOK);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* DhBookManager::book-deleted:
|
|
Packit |
116408 |
* @book_manager: the #DhBookManager.
|
|
Packit |
116408 |
* @book: the deleted #DhBook.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_DELETED] =
|
|
Packit |
116408 |
g_signal_new ("book-deleted",
|
|
Packit |
116408 |
G_TYPE_FROM_CLASS (klass),
|
|
Packit |
116408 |
G_SIGNAL_RUN_LAST,
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
NULL, NULL, NULL,
|
|
Packit |
116408 |
G_TYPE_NONE,
|
|
Packit |
116408 |
1,
|
|
Packit |
116408 |
DH_TYPE_BOOK);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* DhBookManager::book-enabled:
|
|
Packit |
116408 |
* @book_manager: the #DhBookManager.
|
|
Packit |
116408 |
* @book: the enabled #DhBook.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_ENABLED] =
|
|
Packit |
116408 |
g_signal_new ("book-enabled",
|
|
Packit |
116408 |
G_TYPE_FROM_CLASS (klass),
|
|
Packit |
116408 |
G_SIGNAL_RUN_LAST,
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
NULL, NULL, NULL,
|
|
Packit |
116408 |
G_TYPE_NONE,
|
|
Packit |
116408 |
1,
|
|
Packit |
116408 |
DH_TYPE_BOOK);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* DhBookManager::book-disabled:
|
|
Packit |
116408 |
* @book_manager: the #DhBookManager.
|
|
Packit |
116408 |
* @book: the disabled #DhBook.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_DISABLED] =
|
|
Packit |
116408 |
g_signal_new ("book-disabled",
|
|
Packit |
116408 |
G_TYPE_FROM_CLASS (klass),
|
|
Packit |
116408 |
G_SIGNAL_RUN_LAST,
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
NULL, NULL, NULL,
|
|
Packit |
116408 |
G_TYPE_NONE,
|
|
Packit |
116408 |
1,
|
|
Packit |
116408 |
DH_TYPE_BOOK);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* DhBookManager:group-by-language:
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Whether books should be grouped by programming language.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
g_object_class_install_property (object_class,
|
|
Packit |
116408 |
PROP_GROUP_BY_LANGUAGE,
|
|
Packit |
116408 |
g_param_spec_boolean ("group-by-language",
|
|
Packit |
116408 |
"Group by language",
|
|
Packit |
116408 |
"",
|
|
Packit |
116408 |
FALSE,
|
|
Packit |
116408 |
G_PARAM_READWRITE |
|
|
Packit |
116408 |
G_PARAM_STATIC_STRINGS));
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
load_books_disabled (DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
DhSettings *settings;
|
|
Packit |
116408 |
GSettings *contents_settings;
|
|
Packit |
116408 |
gchar **books_disabled_strv;
|
|
Packit |
116408 |
gint i;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_assert (priv->books_disabled == NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
settings = dh_settings_get_singleton ();
|
|
Packit |
116408 |
contents_settings = dh_settings_peek_contents_settings (settings);
|
|
Packit |
116408 |
books_disabled_strv = g_settings_get_strv (contents_settings, "books-disabled");
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (books_disabled_strv == NULL)
|
|
Packit |
116408 |
return;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
for (i = 0; books_disabled_strv[i] != NULL; i++) {
|
|
Packit |
116408 |
gchar *book_id = books_disabled_strv[i];
|
|
Packit |
116408 |
priv->books_disabled = g_list_prepend (priv->books_disabled, book_id);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv->books_disabled = g_list_reverse (priv->books_disabled);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_free (books_disabled_strv);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
store_books_disabled (DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
DhSettings *settings;
|
|
Packit |
116408 |
GSettings *contents_settings;
|
|
Packit |
116408 |
GVariantBuilder *builder;
|
|
Packit |
116408 |
GVariant *variant;
|
|
Packit |
116408 |
GList *l;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
builder = g_variant_builder_new (G_VARIANT_TYPE_STRING_ARRAY);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
for (l = priv->books_disabled; l != NULL; l = l->next) {
|
|
Packit |
116408 |
const gchar *book_id = l->data;
|
|
Packit |
116408 |
g_variant_builder_add (builder, "s", book_id);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
variant = g_variant_builder_end (builder);
|
|
Packit |
116408 |
g_variant_builder_unref (builder);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
settings = dh_settings_get_singleton ();
|
|
Packit |
116408 |
contents_settings = dh_settings_peek_contents_settings (settings);
|
|
Packit |
116408 |
g_settings_set_value (contents_settings, "books-disabled", variant);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static GList *
|
|
Packit |
116408 |
find_book_in_disabled_list (GList *books_disabled,
|
|
Packit |
116408 |
DhBook *book)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
const gchar *book_id;
|
|
Packit |
116408 |
GList *node;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
book_id = dh_book_get_id (book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
for (node = books_disabled; node != NULL; node = node->next) {
|
|
Packit |
116408 |
const gchar *cur_book_id = node->data;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (g_strcmp0 (book_id, cur_book_id) == 0)
|
|
Packit |
116408 |
return node;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return NULL;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static gboolean
|
|
Packit |
116408 |
is_book_disabled_in_conf (DhBookManager *book_manager,
|
|
Packit |
116408 |
DhBook *book)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return find_book_in_disabled_list (priv->books_disabled, book) != NULL;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
remove_book (DhBookManager *book_manager,
|
|
Packit |
116408 |
DhBook *book)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
GList *node;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
node = g_list_find (priv->books, book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (node != NULL) {
|
|
Packit |
116408 |
g_signal_emit (book_manager,
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_DELETED],
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv->books = g_list_delete_link (priv->books, node);
|
|
Packit |
116408 |
g_object_unref (book);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
book_deleted_cb (DhBook *book,
|
|
Packit |
116408 |
DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
remove_book (book_manager, book);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
book_updated_cb (DhBook *book,
|
|
Packit |
116408 |
DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
GFile *index_file;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Re-create the DhBook to parse again the index file. */
|
|
Packit |
116408 |
|
|
Packit |
116408 |
index_file = dh_book_get_index_file (book);
|
|
Packit |
116408 |
g_object_ref (index_file);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
remove_book (book_manager, book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
create_book_from_index_file (book_manager, index_file);
|
|
Packit |
116408 |
g_object_unref (index_file);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
book_enabled_cb (DhBook *book,
|
|
Packit |
116408 |
DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
GList *node;
|
|
Packit |
116408 |
gchar *book_id;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
node = find_book_in_disabled_list (priv->books_disabled, book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* When setting as enabled a given book, we should have it in the
|
|
Packit |
116408 |
* disabled books list!
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
g_return_if_fail (node != NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
book_id = node->data;
|
|
Packit |
116408 |
g_free (book_id);
|
|
Packit |
116408 |
priv->books_disabled = g_list_delete_link (priv->books_disabled, node);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
store_books_disabled (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_emit (book_manager,
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_ENABLED],
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
book);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
book_disabled_cb (DhBook *book,
|
|
Packit |
116408 |
DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
GList *node;
|
|
Packit |
116408 |
const gchar *book_id;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
node = find_book_in_disabled_list (priv->books_disabled, book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* When setting as disabled a given book, we shouldn't have it in the
|
|
Packit |
116408 |
* disabled books list!
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
g_return_if_fail (node == NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
book_id = dh_book_get_id (book);
|
|
Packit |
116408 |
priv->books_disabled = g_list_append (priv->books_disabled,
|
|
Packit |
116408 |
g_strdup (book_id));
|
|
Packit |
116408 |
store_books_disabled (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_emit (book_manager,
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_DISABLED],
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
book);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Returns TRUE if "successful", FALSE if the next possible index file in the
|
|
Packit |
116408 |
* book directory needs to be tried.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
static gboolean
|
|
Packit |
116408 |
create_book_from_index_file (DhBookManager *book_manager,
|
|
Packit |
116408 |
GFile *index_file)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv;
|
|
Packit |
116408 |
DhBook *book;
|
|
Packit |
116408 |
gboolean book_enabled;
|
|
Packit |
116408 |
GList *l;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Check if a DhBook at the same location has already been loaded. */
|
|
Packit |
116408 |
for (l = priv->books; l != NULL; l = l->next) {
|
|
Packit |
116408 |
DhBook *cur_book = DH_BOOK (l->data);
|
|
Packit |
116408 |
GFile *cur_index_file;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
cur_index_file = dh_book_get_index_file (cur_book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (g_file_equal (index_file, cur_index_file))
|
|
Packit |
116408 |
return TRUE;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
book = dh_book_new (index_file);
|
|
Packit |
116408 |
if (book == NULL)
|
|
Packit |
116408 |
return FALSE;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* Check if book with same ID was already loaded in the manager (we need
|
|
Packit |
116408 |
* to force unique book IDs).
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
if (g_list_find_custom (priv->books,
|
|
Packit |
116408 |
book,
|
|
Packit |
116408 |
(GCompareFunc)dh_book_cmp_by_id)) {
|
|
Packit |
116408 |
g_object_unref (book);
|
|
Packit |
116408 |
return TRUE;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv->books = g_list_insert_sorted (priv->books,
|
|
Packit |
116408 |
book,
|
|
Packit |
116408 |
(GCompareFunc)dh_book_cmp_by_title);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
book_enabled = !is_book_disabled_in_conf (book_manager, book);
|
|
Packit |
116408 |
dh_book_set_enabled (book, book_enabled);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_connect_object (book,
|
|
Packit |
116408 |
"deleted",
|
|
Packit |
116408 |
G_CALLBACK (book_deleted_cb),
|
|
Packit |
116408 |
book_manager,
|
|
Packit |
116408 |
0);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_connect_object (book,
|
|
Packit |
116408 |
"updated",
|
|
Packit |
116408 |
G_CALLBACK (book_updated_cb),
|
|
Packit |
116408 |
book_manager,
|
|
Packit |
116408 |
0);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_connect_object (book,
|
|
Packit |
116408 |
"enabled",
|
|
Packit |
116408 |
G_CALLBACK (book_enabled_cb),
|
|
Packit |
116408 |
book_manager,
|
|
Packit |
116408 |
0);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_connect_object (book,
|
|
Packit |
116408 |
"disabled",
|
|
Packit |
116408 |
G_CALLBACK (book_disabled_cb),
|
|
Packit |
116408 |
book_manager,
|
|
Packit |
116408 |
0);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_emit (book_manager,
|
|
Packit |
116408 |
signals[SIGNAL_BOOK_CREATED],
|
|
Packit |
116408 |
0,
|
|
Packit |
116408 |
book);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return TRUE;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
create_book_from_directory (DhBookManager *book_manager,
|
|
Packit |
116408 |
GFile *book_directory)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
GSList *possible_index_files;
|
|
Packit |
116408 |
GSList *l;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
possible_index_files = _dh_util_get_possible_index_files (book_directory);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
for (l = possible_index_files; l != NULL; l = l->next) {
|
|
Packit |
116408 |
GFile *index_file = G_FILE (l->data);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (create_book_from_index_file (book_manager, index_file))
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_slist_free_full (possible_index_files, g_object_unref);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static gboolean
|
|
Packit |
116408 |
new_possible_book_timeout_cb (gpointer user_data)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
NewPossibleBookData *data = user_data;
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (data->book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
data->timeout_id = 0;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
create_book_from_directory (data->book_manager, data->book_directory);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv->new_possible_books_data = g_slist_remove (priv->new_possible_books_data, data);
|
|
Packit |
116408 |
new_possible_book_data_free (data);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return G_SOURCE_REMOVE;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
books_directory_changed_cb (GFileMonitor *directory_monitor,
|
|
Packit |
116408 |
GFile *file,
|
|
Packit |
116408 |
GFile *other_file,
|
|
Packit |
116408 |
GFileMonitorEvent event_type,
|
|
Packit |
116408 |
DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
NewPossibleBookData *data;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* With the GFileMonitor here we only handle events for new directories
|
|
Packit |
116408 |
* created. Book deletions and updates are handled by the GFileMonitor
|
|
Packit |
116408 |
* in each DhBook object.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
if (event_type != G_FILE_MONITOR_EVENT_CREATED)
|
|
Packit |
116408 |
return;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
data = new_possible_book_data_new (book_manager, file);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* We add a timeout of several seconds so that we give time to the whole
|
|
Packit |
116408 |
* documentation to get installed. If we don't do this, we may end up
|
|
Packit |
116408 |
* trying to add the new book when even the *.devhelp2 index file is not
|
|
Packit |
116408 |
* installed yet.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
data->timeout_id = g_timeout_add_seconds (NEW_POSSIBLE_BOOK_TIMEOUT_SECS,
|
|
Packit |
116408 |
new_possible_book_timeout_cb,
|
|
Packit |
116408 |
data);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv->new_possible_books_data = g_slist_prepend (priv->new_possible_books_data, data);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
monitor_books_directory (DhBookManager *book_manager,
|
|
Packit |
116408 |
GFile *books_directory)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
GFileMonitor *directory_monitor;
|
|
Packit |
116408 |
GError *error = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* If monitor already exists, do not re-create it. */
|
|
Packit |
116408 |
if (priv->monitors != NULL &&
|
|
Packit |
116408 |
g_hash_table_lookup (priv->monitors, books_directory) != NULL) {
|
|
Packit |
116408 |
return;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
directory_monitor = g_file_monitor_directory (books_directory,
|
|
Packit |
116408 |
G_FILE_MONITOR_NONE,
|
|
Packit |
116408 |
NULL,
|
|
Packit |
116408 |
&error);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (error != NULL) {
|
|
Packit |
116408 |
gchar *parse_name;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
parse_name = g_file_get_parse_name (books_directory);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_warning ("Failed to create file monitor on directory “%s”: %s",
|
|
Packit |
116408 |
parse_name,
|
|
Packit |
116408 |
error->message);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_free (parse_name);
|
|
Packit |
116408 |
g_clear_error (&error);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (directory_monitor != NULL) {
|
|
Packit |
116408 |
if (G_UNLIKELY (priv->monitors == NULL)) {
|
|
Packit |
116408 |
priv->monitors = g_hash_table_new_full (g_file_hash,
|
|
Packit |
116408 |
(GEqualFunc) g_file_equal,
|
|
Packit |
116408 |
g_object_unref,
|
|
Packit |
116408 |
g_object_unref);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_hash_table_insert (priv->monitors,
|
|
Packit |
116408 |
g_object_ref (books_directory),
|
|
Packit |
116408 |
directory_monitor);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_signal_connect_object (directory_monitor,
|
|
Packit |
116408 |
"changed",
|
|
Packit |
116408 |
G_CALLBACK (books_directory_changed_cb),
|
|
Packit |
116408 |
book_manager,
|
|
Packit |
116408 |
0);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
find_books_in_dir (DhBookManager *book_manager,
|
|
Packit |
116408 |
const gchar *dir_path)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
GFile *directory;
|
|
Packit |
116408 |
GFileEnumerator *enumerator;
|
|
Packit |
116408 |
GError *error = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_if_fail (dir_path != NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
directory = g_file_new_for_path (dir_path);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
enumerator = g_file_enumerate_children (directory,
|
|
Packit |
116408 |
G_FILE_ATTRIBUTE_STANDARD_NAME,
|
|
Packit |
116408 |
G_FILE_QUERY_INFO_NONE,
|
|
Packit |
116408 |
NULL,
|
|
Packit |
116408 |
&error);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND)) {
|
|
Packit |
116408 |
g_clear_error (&error);
|
|
Packit |
116408 |
goto out;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (error != NULL) {
|
|
Packit |
116408 |
g_warning ("Error when reading directory '%s': %s",
|
|
Packit |
116408 |
dir_path,
|
|
Packit |
116408 |
error->message);
|
|
Packit |
116408 |
g_clear_error (&error);
|
|
Packit |
116408 |
goto out;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
monitor_books_directory (book_manager, directory);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
while (TRUE) {
|
|
Packit |
116408 |
GFile *book_directory = NULL;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_file_enumerator_iterate (enumerator, NULL, &book_directory, NULL, &error);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (error != NULL) {
|
|
Packit |
116408 |
g_warning ("Error when enumerating directory '%s': %s",
|
|
Packit |
116408 |
dir_path,
|
|
Packit |
116408 |
error->message);
|
|
Packit |
116408 |
g_clear_error (&error);
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (book_directory == NULL)
|
|
Packit |
116408 |
break;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
create_book_from_directory (book_manager, book_directory);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
out:
|
|
Packit |
116408 |
g_object_unref (directory);
|
|
Packit |
116408 |
g_clear_object (&enumerator);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
find_books_in_data_dir (DhBookManager *book_manager,
|
|
Packit |
116408 |
const gchar *data_dir)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
gchar *dir;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_if_fail (data_dir != NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
dir = g_build_filename (data_dir, "gtk-doc", "html", NULL);
|
|
Packit |
116408 |
find_books_in_dir (book_manager, dir);
|
|
Packit |
116408 |
g_free (dir);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
dir = g_build_filename (data_dir, "devhelp", "books", NULL);
|
|
Packit |
116408 |
find_books_in_dir (book_manager, dir);
|
|
Packit |
116408 |
g_free (dir);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
populate (DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
const gchar * const *system_dirs;
|
|
Packit |
116408 |
gint i;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
find_books_in_data_dir (book_manager, g_get_user_data_dir ());
|
|
Packit |
116408 |
|
|
Packit |
116408 |
system_dirs = g_get_system_data_dirs ();
|
|
Packit |
116408 |
g_return_if_fail (system_dirs != NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
for (i = 0; system_dirs[i] != NULL; i++) {
|
|
Packit |
116408 |
find_books_in_data_dir (book_manager, system_dirs[i]);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* For Flatpak, to see the books installed on the host by traditional
|
|
Packit |
116408 |
* Linux distro packages.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* It is not a good idea to add the directory to XDG_DATA_DIRS, see:
|
|
Packit |
116408 |
* https://github.com/flatpak/flatpak/issues/1299
|
|
Packit |
116408 |
* "all sorts of things will break if we add all host config to each
|
|
Packit |
116408 |
* app, which is totally opposite to the entire point of flatpak."
|
|
Packit |
116408 |
* "i don't think XDG_DATA_DIRS is the right thing, because all sorts of
|
|
Packit |
116408 |
* libraries will start reading files from there, like dconf, dbus,
|
|
Packit |
116408 |
* service files, mimetypes, etc. It would be preferable to have
|
|
Packit |
116408 |
* something that targeted just gtk-doc files."
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* So instead of adapting XDG_DATA_DIRS, add the directory here, with
|
|
Packit |
116408 |
* the path hard-coded.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* https://bugzilla.gnome.org/show_bug.cgi?id=792068
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
#ifdef FLATPAK_BUILD
|
|
Packit |
116408 |
find_books_in_data_dir (book_manager, "/run/host/usr/share");
|
|
Packit |
116408 |
#endif
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
static void
|
|
Packit |
116408 |
dh_book_manager_init (DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhSettings *settings;
|
|
Packit |
116408 |
GSettings *contents_settings;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
load_books_disabled (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
settings = dh_settings_get_singleton ();
|
|
Packit |
116408 |
contents_settings = dh_settings_peek_contents_settings (settings);
|
|
Packit |
116408 |
g_settings_bind (contents_settings, "group-books-by-language",
|
|
Packit |
116408 |
book_manager, "group-by-language",
|
|
Packit |
116408 |
G_SETTINGS_BIND_DEFAULT);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
populate (book_manager);
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_book_manager_new:
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: (transfer full): the #DhBookManager singleton instance. You need to
|
|
Packit |
116408 |
* unref it when no longer needed.
|
|
Packit |
116408 |
* Deprecated: 3.26: Call dh_book_manager_get_singleton() instead.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
DhBookManager *
|
|
Packit |
116408 |
dh_book_manager_new (void)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
return g_object_ref (dh_book_manager_get_singleton ());
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_book_manager_get_singleton:
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: (transfer none): the #DhBookManager singleton instance.
|
|
Packit |
116408 |
* Since: 3.26
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
DhBookManager *
|
|
Packit |
116408 |
dh_book_manager_get_singleton (void)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
if (singleton == NULL)
|
|
Packit |
116408 |
singleton = g_object_new (DH_TYPE_BOOK_MANAGER, NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return singleton;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
void
|
|
Packit |
116408 |
_dh_book_manager_unref_singleton (void)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
if (singleton != NULL)
|
|
Packit |
116408 |
g_object_unref (singleton);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/* singleton is not set to NULL here, it is set to NULL in
|
|
Packit |
116408 |
* dh_book_manager_finalize() (i.e. when we are sure that the ref count
|
|
Packit |
116408 |
* reaches 0).
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_book_manager_populate:
|
|
Packit |
116408 |
* @book_manager: a #DhBookManager.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Populates the #DhBookManager with all books found on the system and user
|
|
Packit |
116408 |
* directories.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Deprecated: 3.26: The #DhBookManager is now automatically populated when the
|
|
Packit |
116408 |
* object is created, there is no need to call this function anymore.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
void
|
|
Packit |
116408 |
dh_book_manager_populate (DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_book_manager_get_books:
|
|
Packit |
116408 |
* @book_manager: a #DhBookManager.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: (element-type DhBook) (transfer none): the list of all #DhBook's
|
|
Packit |
116408 |
* found.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
GList *
|
|
Packit |
116408 |
dh_book_manager_get_books (DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_fail (DH_IS_BOOK_MANAGER (book_manager), NULL);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return priv->books;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_book_manager_get_group_by_language:
|
|
Packit |
116408 |
* @book_manager: a #DhBookManager.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Returns: whether the books should be grouped by programming language.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
gboolean
|
|
Packit |
116408 |
dh_book_manager_get_group_by_language (DhBookManager *book_manager)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_val_if_fail (DH_IS_BOOK_MANAGER (book_manager), FALSE);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
return priv->group_by_language;
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
|
|
Packit |
116408 |
/**
|
|
Packit |
116408 |
* dh_book_manager_set_group_by_language:
|
|
Packit |
116408 |
* @book_manager: a #DhBookManager.
|
|
Packit |
116408 |
* @group_by_language: the new value.
|
|
Packit |
116408 |
*
|
|
Packit |
116408 |
* Sets whether the books should be grouped by programming language.
|
|
Packit |
116408 |
*/
|
|
Packit |
116408 |
void
|
|
Packit |
116408 |
dh_book_manager_set_group_by_language (DhBookManager *book_manager,
|
|
Packit |
116408 |
gboolean group_by_language)
|
|
Packit |
116408 |
{
|
|
Packit |
116408 |
DhBookManagerPrivate *priv;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
g_return_if_fail (DH_IS_BOOK_MANAGER (book_manager));
|
|
Packit |
116408 |
|
|
Packit |
116408 |
priv = dh_book_manager_get_instance_private (book_manager);
|
|
Packit |
116408 |
|
|
Packit |
116408 |
group_by_language = group_by_language != FALSE;
|
|
Packit |
116408 |
|
|
Packit |
116408 |
if (priv->group_by_language != group_by_language) {
|
|
Packit |
116408 |
priv->group_by_language = group_by_language;
|
|
Packit |
116408 |
g_object_notify (G_OBJECT (book_manager), "group-by-language");
|
|
Packit |
116408 |
}
|
|
Packit |
116408 |
}
|