[devhelp: 9/36] Do not fully rebuild trees and lists when books created, deleted, enabled or disabled
- From: Aleksander Morgado <aleksm src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [devhelp: 9/36] Do not fully rebuild trees and lists when books created, deleted, enabled or disabled
- Date: Mon, 20 Dec 2010 14:32:10 +0000 (UTC)
commit 370e25afcba0f9a8ceab67113f5c22843061ae84
Author: Aleksander Morgado <aleksander lanedo com>
Date: Thu Dec 2 20:38:52 2010 +0100
Do not fully rebuild trees and lists when books created, deleted, enabled or disabled
src/dh-book-manager.c | 224 ++++++++++++++++++++++++++++++------------------
src/dh-book-manager.h | 1 -
src/dh-book-tree.c | 93 +++++++++++++++++----
src/dh-book.c | 66 ++++++++++++---
src/dh-marshal.list | 1 +
src/dh-preferences.c | 72 ++++++++++++++--
src/dh-search.c | 207 ++++++++++++++++++++++++++++++++++++---------
src/dh-util.c | 4 +-
8 files changed, 505 insertions(+), 163 deletions(-)
---
diff --git a/src/dh-book-manager.c b/src/dh-book-manager.c
index 507e6f2..877fc8a 100644
--- a/src/dh-book-manager.c
+++ b/src/dh-book-manager.c
@@ -35,11 +35,15 @@ typedef struct {
GList *books;
/* HT with the monitors setup */
GHashTable *monitors;
+ /* List of book names currently disabled */
+ GSList *books_disabled;
} DhBookManagerPriv;
enum {
- BOOK_LIST_UPDATED,
- DISABLED_BOOK_LIST_UPDATED,
+ BOOK_CREATED,
+ BOOK_DELETED,
+ BOOK_ENABLED,
+ BOOK_DISABLED,
LAST_SIGNAL
};
@@ -68,6 +72,7 @@ book_manager_finalize (GObject *object)
{
DhBookManagerPriv *priv;
GList *l;
+ GSList *sl;
priv = GET_PRIVATE (object);
@@ -82,6 +87,12 @@ book_manager_finalize (GObject *object)
g_hash_table_destroy (priv->monitors);
}
+ /* Clean the list of books disabled */
+ for (sl = priv->books_disabled; sl; sl = g_slist_next (sl)) {
+ g_free (sl->data);
+ }
+ g_slist_free (priv->books_disabled);
+
G_OBJECT_CLASS (dh_book_manager_parent_class)->finalize (object);
}
@@ -92,24 +103,46 @@ dh_book_manager_class_init (DhBookManagerClass *klass)
object_class->finalize = book_manager_finalize;
- signals[BOOK_LIST_UPDATED] =
- g_signal_new ("book-list-updated",
+ signals[BOOK_CREATED] =
+ g_signal_new ("book-created",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _dh_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_OBJECT);
+ signals[BOOK_DELETED] =
+ g_signal_new ("book-deleted",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _dh_marshal_VOID__OBJECT,
+ G_TYPE_NONE,
+ 1,
+ G_TYPE_OBJECT);
+ signals[BOOK_ENABLED] =
+ g_signal_new ("book-enabled",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- _dh_marshal_VOID__VOID,
+ _dh_marshal_VOID__OBJECT,
G_TYPE_NONE,
- 0);
- signals[DISABLED_BOOK_LIST_UPDATED] =
- g_signal_new ("disabled-book-list-updated",
+ 1,
+ G_TYPE_OBJECT);
+ signals[BOOK_DISABLED] =
+ g_signal_new ("book-disabled",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
0,
NULL, NULL,
- _dh_marshal_VOID__VOID,
+ _dh_marshal_VOID__OBJECT,
G_TYPE_NONE,
- 0);
+ 1,
+ G_TYPE_OBJECT);
g_type_class_add_private (klass, sizeof (DhBookManagerPriv));
}
@@ -120,37 +153,26 @@ dh_book_manager_init (DhBookManager *book_manager)
DhBookManagerPriv *priv = GET_PRIVATE (book_manager);
priv->books = NULL;
-}
-
-static void
-book_manager_clean_list_of_books_disabled (GSList *books_disabled)
-{
- GSList *sl;
+ priv->monitors = NULL;
- for (sl = books_disabled; sl; sl = g_slist_next (sl)) {
- g_free (sl->data);
- }
- g_slist_free (sl);
+ priv->books_disabled = dh_util_state_load_books_disabled ();
}
-static void
-book_manager_check_status_from_conf (DhBookManager *book_manager)
+static gboolean
+book_manager_is_book_disabled_in_conf (DhBookManager *book_manager,
+ DhBook *book)
{
- GSList *books_disabled, *sl;
-
- books_disabled = dh_util_state_load_books_disabled ();
-
- for (sl = books_disabled; sl; sl = g_slist_next (sl)) {
- DhBook *book;
+ DhBookManagerPriv *priv = GET_PRIVATE (book_manager);
+ GSList *li;
- book = dh_book_manager_get_book_by_name (book_manager,
- (const gchar *)sl->data);
- if (book) {
- dh_book_set_enabled (book, FALSE);
+ for (li = priv->books_disabled; li; li = g_slist_next (li)) {
+ if (g_strcmp0 (dh_book_get_name (book),
+ (const gchar *)li->data) == 0) {
+ return TRUE;
}
}
- book_manager_clean_list_of_books_disabled (books_disabled);
+ return FALSE;
}
static void
@@ -188,9 +210,6 @@ dh_book_manager_populate (DhBookManager *book_manager)
book_manager,
"/Library/Developer/Shared/Documentation/DocSets");
#endif
-
- /* Once all books are loaded, check enabled status from conf */
- book_manager_check_status_from_conf (book_manager);
}
static gchar *
@@ -277,11 +296,6 @@ book_manager_booklist_monitor_event_cb (GFileMonitor *file_monitor,
book_manager_add_from_filepath (book_manager,
book_path);
g_free (book_path);
-
- /* Emit signal to notify others */
- g_signal_emit (book_manager,
- signals[BOOK_LIST_UPDATED],
- 0);
}
g_free (file_path);
@@ -467,14 +481,15 @@ book_manager_book_deleted_cb (DhBook *book,
g_debug ("Deleting book '%s' from the book manager list",
dh_book_get_title (book));
+ /* Emit signal to notify others */
+ g_signal_emit (book_manager,
+ signals[BOOK_DELETED],
+ 0,
+ book);
+
/* Remove the item and unref our reference */
priv->books = g_list_delete_link (priv->books, li);
g_object_unref (book);
-
- /* Emit signal to notify others */
- g_signal_emit (book_manager,
- signals[BOOK_LIST_UPDATED],
- 0);
}
}
@@ -482,15 +497,69 @@ static void
book_manager_book_updated_cb (DhBook *book,
gpointer user_data)
{
- DhBookManager *book_manager = user_data;
-
g_debug ("Updating book '%s' in the book manager list",
dh_book_get_title (book));
+ /* TODO */
+}
+
+static GSList *
+book_manager_find_book_in_disabled_list (GSList *books_disabled,
+ DhBook *book)
+{
+ GSList *li;
+
+ for (li = books_disabled; li; li = g_slist_next (li)) {
+ if (g_strcmp0 (dh_book_get_name (book),
+ (const gchar *)li->data) == 0) {
+ return li;
+ }
+ }
+ return NULL;
+}
+
+static void
+book_manager_book_enabled_cb (DhBook *book,
+ gpointer user_data)
+{
+ DhBookManager *book_manager = user_data;
+ DhBookManagerPriv *priv = GET_PRIVATE (book_manager);
+ GSList *li;
+
+ li = book_manager_find_book_in_disabled_list (priv->books_disabled,
+ book);
+ /* When setting as enabled a given book, we should have it in the
+ * disabled books list! */
+ g_assert (li != NULL);
+ priv->books_disabled = g_slist_delete_link (priv->books_disabled, li);
+ dh_util_state_store_books_disabled (priv->books_disabled);
+
+ g_signal_emit (book_manager,
+ signals[BOOK_ENABLED],
+ 0,
+ book);
+}
+
+static void
+book_manager_book_disabled_cb (DhBook *book,
+ gpointer user_data)
+{
+ DhBookManager *book_manager = user_data;
+ DhBookManagerPriv *priv = GET_PRIVATE (book_manager);
+ GSList *li;
+
+ li = book_manager_find_book_in_disabled_list (priv->books_disabled,
+ book);
+ /* When setting as disabled a given book, we shouldn't have it in the
+ * disabled books list! */
+ g_assert (li == NULL);
+ priv->books_disabled = g_slist_append (priv->books_disabled,
+ g_strdup (dh_book_get_name (book)));
+ dh_util_state_store_books_disabled (priv->books_disabled);
- /* Emit signal to notify others */
g_signal_emit (book_manager,
- signals[BOOK_LIST_UPDATED],
- 0);
+ signals[BOOK_DISABLED],
+ 0,
+ book);
}
static void
@@ -498,7 +567,7 @@ book_manager_add_from_filepath (DhBookManager *book_manager,
const gchar *book_path)
{
DhBookManagerPriv *priv;
- DhBook *book;
+ DhBook *book;
g_return_if_fail (book_manager);
g_return_if_fail (book_path);
@@ -533,6 +602,11 @@ book_manager_add_from_filepath (DhBookManager *book_manager,
g_debug ("Adding book '%s' to the book manager list",
dh_book_get_title (book));
+ /* Set the proper enabled/disabled state, depending on conf */
+ dh_book_set_enabled (book,
+ !book_manager_is_book_disabled_in_conf (book_manager,
+ book));
+
/* Get notifications of book being deleted or updated */
g_signal_connect (book,
"deleted",
@@ -542,6 +616,20 @@ book_manager_add_from_filepath (DhBookManager *book_manager,
"updated",
G_CALLBACK (book_manager_book_updated_cb),
book_manager);
+ g_signal_connect (book,
+ "enabled",
+ G_CALLBACK (book_manager_book_enabled_cb),
+ book_manager);
+ g_signal_connect (book,
+ "disabled",
+ G_CALLBACK (book_manager_book_disabled_cb),
+ book_manager);
+
+ /* Emit signal to notify others */
+ g_signal_emit (book_manager,
+ signals[BOOK_CREATED],
+ 0,
+ book);
}
GList *
@@ -582,38 +670,6 @@ dh_book_manager_get_book_by_path (DhBookManager *book_manager,
return l ? l->data : NULL;
}
-void
-dh_book_manager_update_disabled (DhBookManager *book_manager)
-{
- DhBookManagerPriv *priv;
- GSList *books_disabled = NULL;
- GList *l;
-
- g_return_if_fail (book_manager);
-
- priv = GET_PRIVATE (book_manager);
-
- /* Create list of disabled books */
- for (l = priv->books; l; l = g_list_next (l)) {
- DhBook *book = DH_BOOK (l->data);
-
- if (!dh_book_get_enabled (book)) {
- books_disabled = g_slist_append (books_disabled,
- g_strdup (dh_book_get_name (book)));
- }
- }
-
- /* Store in conf */
- dh_util_state_store_books_disabled (books_disabled);
-
- /* Emit signal to notify others */
- g_signal_emit (book_manager,
- signals[DISABLED_BOOK_LIST_UPDATED],
- 0);
-
- book_manager_clean_list_of_books_disabled (books_disabled);
-}
-
DhBookManager *
dh_book_manager_new (void)
{
diff --git a/src/dh-book-manager.h b/src/dh-book-manager.h
index 0f6499e..525bace 100644
--- a/src/dh-book-manager.h
+++ b/src/dh-book-manager.h
@@ -53,7 +53,6 @@ DhBook *dh_book_manager_get_book_by_name (DhBookManager *book_manager
const gchar *name);
DhBook *dh_book_manager_get_book_by_path (DhBookManager *book_manager,
const gchar *path);
-void dh_book_manager_update_disabled (DhBookManager *book_manager);
G_END_DECLS
diff --git a/src/dh-book-tree.c b/src/dh-book-tree.c
index 732e395..e544d56 100644
--- a/src/dh-book-tree.c
+++ b/src/dh-book-tree.c
@@ -46,10 +46,10 @@ static void dh_book_tree_class_init (DhBookTreeClass *klass);
static void dh_book_tree_init (DhBookTree *tree);
static void book_tree_add_columns (DhBookTree *tree);
static void book_tree_setup_selection (DhBookTree *tree);
-static void book_tree_populate_tree (DhBookTree *tree);
static void book_tree_insert_node (DhBookTree *tree,
GNode *node,
- GtkTreeIter *parent_iter);
+ GtkTreeIter *parent_iter,
+ DhBook *book);
static void book_tree_selection_changed_cb (GtkTreeSelection *selection,
DhBookTree *tree);
@@ -62,6 +62,7 @@ enum {
COL_TITLE,
COL_LINK,
COL_WEIGHT,
+ COL_BOOK,
N_COLUMNS
};
@@ -113,7 +114,8 @@ dh_book_tree_init (DhBookTree *tree)
priv->store = gtk_tree_store_new (N_COLUMNS,
G_TYPE_STRING,
G_TYPE_POINTER,
- PANGO_TYPE_WEIGHT);
+ PANGO_TYPE_WEIGHT,
+ G_TYPE_OBJECT);
priv->selected_link = NULL;
gtk_tree_view_set_model (GTK_TREE_VIEW (tree),
GTK_TREE_MODEL (priv->store));
@@ -168,6 +170,7 @@ book_tree_populate_tree (DhBookTree *tree)
gtk_tree_store_clear (priv->store);
+ /* This list comes in order */
for (l = dh_book_manager_get_books (priv->book_manager);
l;
l = g_list_next (l)) {
@@ -175,25 +178,75 @@ book_tree_populate_tree (DhBookTree *tree)
GNode *node;
node = dh_book_get_tree (book);
- while(node) {
- book_tree_insert_node (tree, node, NULL);
+ while (node) {
+ book_tree_insert_node (tree, node, NULL, book);
node = g_node_next_sibling (node);
}
}
}
static void
-book_manager_book_list_changed_cb (DhBookManager *book_manager,
- gpointer user_data)
+book_tree_book_created_or_enabled_cb (DhBookManager *book_manager,
+ GObject *book_object,
+ gpointer user_data)
{
DhBookTree *tree = user_data;
- book_tree_populate_tree (tree);
+ DhBook *book = DH_BOOK (book_object);
+ GNode *node;
+
+ /* TODO: insert ordered here! */
+
+ node = dh_book_get_tree (book);
+ while (node) {
+ book_tree_insert_node (tree, node, NULL, book);
+ node = g_node_next_sibling (node);
+ }
+}
+
+static void
+book_tree_book_deleted_or_disabled_cb (DhBookManager *book_manager,
+ GObject *book_object,
+ gpointer user_data)
+{
+ DhBookTree *tree = user_data;
+ DhBookTreePriv *priv = GET_PRIVATE (tree);
+ DhBook *book = DH_BOOK (book_object);
+ GtkTreeIter iter;
+ gboolean found;
+
+ /* Look for the specific book. */
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->store), &iter)) {
+ /* The model is empty now */
+ return;
+ }
+
+ /* Loop top-level elements looking for the book */
+ found = FALSE;
+ do {
+ DhBook *in_tree_book = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (priv->store),
+ &iter,
+ COL_BOOK, &in_tree_book,
+ -1);
+ if (in_tree_book == book) {
+ found = TRUE;
+ }
+ /* We should always have a DhBook in the top level tree elements */
+ g_object_unref (in_tree_book);
+ } while (!found && gtk_tree_model_iter_next (GTK_TREE_MODEL (priv->store), &iter));
+
+ /* If found, delete item from the store */
+ if (found) {
+ gtk_tree_store_remove (priv->store, &iter);
+ }
}
static void
book_tree_insert_node (DhBookTree *tree,
GNode *node,
- GtkTreeIter *parent_iter)
+ GtkTreeIter *parent_iter,
+ DhBook *book)
{
DhBookTreePriv *priv = GET_PRIVATE (tree);
@@ -216,12 +269,13 @@ book_tree_insert_node (DhBookTree *tree,
COL_TITLE, dh_link_get_name (link),
COL_LINK, link,
COL_WEIGHT, weight,
+ COL_BOOK, book,
-1);
for (child = g_node_first_child (node);
child;
child = g_node_next_sibling (child)) {
- book_tree_insert_node (tree, child, &iter);
+ book_tree_insert_node (tree, child, &iter, NULL);
}
}
@@ -259,13 +313,22 @@ dh_book_tree_new (DhBookManager *book_manager)
priv = GET_PRIVATE (tree);
priv->book_manager = g_object_ref (book_manager);
+
+ g_signal_connect (priv->book_manager,
+ "book-created",
+ G_CALLBACK (book_tree_book_created_or_enabled_cb),
+ tree);
+ g_signal_connect (priv->book_manager,
+ "book-deleted",
+ G_CALLBACK (book_tree_book_deleted_or_disabled_cb),
+ tree);
g_signal_connect (priv->book_manager,
- "disabled-book-list-updated",
- G_CALLBACK (book_manager_book_list_changed_cb),
+ "book-enabled",
+ G_CALLBACK (book_tree_book_created_or_enabled_cb),
tree);
g_signal_connect (priv->book_manager,
- "book-list-updated",
- G_CALLBACK (book_manager_book_list_changed_cb),
+ "book-disabled",
+ G_CALLBACK (book_tree_book_deleted_or_disabled_cb),
tree);
book_tree_populate_tree (tree);
@@ -283,7 +346,7 @@ dh_book_tree_new (DhBookManager *book_manager)
tree);
gtk_tree_model_get_iter_first ( GTK_TREE_MODEL (priv->store), &iter);
gtk_tree_model_get (GTK_TREE_MODEL (priv->store),
- &iter, COL_LINK, &link, -1);
+ &iter, COL_LINK, &link, -1);
priv->selected_link = link;
gtk_tree_selection_select_iter (selection, &iter);
g_signal_handlers_unblock_by_func (selection,
diff --git a/src/dh-book.c b/src/dh-book.c
index 4f4c33e..5ef6b25 100644
--- a/src/dh-book.c
+++ b/src/dh-book.c
@@ -35,11 +35,19 @@
/* Signals managed by the DhBook */
enum {
+ BOOK_ENABLED,
+ BOOK_DISABLED,
BOOK_UPDATED,
BOOK_DELETED,
BOOK_LAST_SIGNAL
};
+typedef enum {
+ BOOK_MONITOR_EVENT_NONE,
+ BOOK_MONITOR_EVENT_UPDATED,
+ BOOK_MONITOR_EVENT_DELETED
+} DhBookMonitorEvent;
+
/* Structure defining basic contents to store about every book */
typedef struct {
/* File path of the book */
@@ -57,9 +65,8 @@ typedef struct {
/* Monitor of this specific book */
GFileMonitor *monitor;
- /* Last received events */
- gboolean is_deleted;
- gboolean is_updated;
+ /* Last received event */
+ DhBookMonitorEvent monitor_event;
/* ID of the event source */
guint monitor_event_timeout_id;
} DhBookPriv;
@@ -121,6 +128,27 @@ dh_book_class_init (DhBookClass *klass)
object_class->finalize = book_finalize;
+ signals[BOOK_ENABLED] =
+ g_signal_new ("enabled",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _dh_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+ signals[BOOK_DISABLED] =
+ g_signal_new ("disabled",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ _dh_marshal_VOID__VOID,
+ G_TYPE_NONE,
+ 0);
+
+
signals[BOOK_UPDATED] =
g_signal_new ("updated",
G_TYPE_FROM_CLASS (klass),
@@ -156,8 +184,7 @@ dh_book_init (DhBook *book)
priv->tree = NULL;
priv->keywords = NULL;
priv->monitor = NULL;
- priv->is_deleted = FALSE;
- priv->is_updated = FALSE;
+ priv->monitor_event = BOOK_MONITOR_EVENT_NONE;
priv->monitor_event_timeout_id = 0;
}
@@ -236,18 +263,29 @@ book_monitor_event_timeout_cb (gpointer data)
/* We'll get either is_deleted OR is_updated,
* not possible to have both or none */
- if (priv->is_deleted) {
+ switch (priv->monitor_event)
+ {
+ case BOOK_MONITOR_EVENT_DELETED:
/* Emit the signal, but make sure we hold a reference
* while doing it */
g_object_ref (book);
g_signal_emit (book, signals[BOOK_DELETED], 0);
g_object_unref (book);
- } else if (priv->is_updated) {
+ break;
+ case BOOK_MONITOR_EVENT_UPDATED:
+ /* Emit the signal, but make sure we hold a reference
+ * while doing it */
+ g_object_ref (book);
g_signal_emit (book, signals[BOOK_UPDATED], 0);
- } else {
- g_warn_if_reached ();
+ g_object_unref (book);
+ break;
+ default:
+ break;
}
+ /* Reset event */
+ priv->monitor_event = BOOK_MONITOR_EVENT_NONE;
+
return FALSE;
}
@@ -271,13 +309,11 @@ book_monitor_event_cb (GFileMonitor *file_monitor,
* Treat in the same way as a CHANGES_DONE_HINT, so
* fall through the case. */
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
- priv->is_deleted = FALSE; /* Reset any previous one */
- priv->is_updated = TRUE;
+ priv->monitor_event = BOOK_MONITOR_EVENT_UPDATED;
reset_timer = TRUE;
break;
case G_FILE_MONITOR_EVENT_DELETED:
- priv->is_deleted = TRUE;
- priv->is_updated = FALSE; /* Reset any previous one */
+ priv->monitor_event = BOOK_MONITOR_EVENT_DELETED;
reset_timer = TRUE;
break;
default:
@@ -371,6 +407,10 @@ dh_book_set_enabled (DhBook *book,
g_return_if_fail (DH_IS_BOOK (book));
GET_PRIVATE (book)->enabled = enabled;
+
+ g_signal_emit (book,
+ enabled ? signals[BOOK_ENABLED] : signals[BOOK_DISABLED],
+ 0);
}
gint
diff --git a/src/dh-marshal.list b/src/dh-marshal.list
index 2023eaf..13f9cab 100644
--- a/src/dh-marshal.list
+++ b/src/dh-marshal.list
@@ -1,3 +1,4 @@
+VOID:OBJECT
VOID:BOOLEAN
VOID:POINTER
VOID:STRING
diff --git a/src/dh-preferences.c b/src/dh-preferences.c
index 445b227..2f1d607 100644
--- a/src/dh-preferences.c
+++ b/src/dh-preferences.c
@@ -73,7 +73,11 @@ static void preferences_bookshelf_tree_selection_toggled_cb (GtkCellRenderer
gchar *path,
gpointer user_data);
static void preferences_bookshelf_populate_store (void);
-static void preferences_bookshelf_book_list_changed_cb (DhBookManager *book_manager,
+static void preferences_bookshelf_book_created_cb (DhBookManager *book_manager,
+ GObject *book_object,
+ gpointer user_data);
+static void preferences_bookshelf_book_deleted_cb (DhBookManager *book_manager,
+ GObject *book_object,
gpointer user_data);
#define DH_CONF_PATH "/apps/devhelp"
@@ -97,8 +101,12 @@ preferences_init (void)
prefs = g_new0 (DhPreferences, 1);
prefs->book_manager = dh_base_get_book_manager (dh_base_get ());
g_signal_connect (prefs->book_manager,
- "book-list-updated",
- G_CALLBACK (preferences_bookshelf_book_list_changed_cb),
+ "book-created",
+ G_CALLBACK (preferences_bookshelf_book_created_cb),
+ NULL);
+ g_signal_connect (prefs->book_manager,
+ "book-deleted",
+ G_CALLBACK (preferences_bookshelf_book_deleted_cb),
NULL);
}
}
@@ -315,18 +323,63 @@ preferences_bookshelf_tree_selection_toggled_cb (GtkCellRendererToggle *cell_ren
gtk_list_store_set (prefs->booklist_store, &iter,
LTCOLUMN_ENABLED, !enabled,
-1);
-
- dh_book_manager_update_disabled (prefs->book_manager);
}
}
}
static void
-preferences_bookshelf_book_list_changed_cb (DhBookManager *book_manager,
- gpointer user_data)
+preferences_bookshelf_book_created_cb (DhBookManager *book_manager,
+ GObject *book_object,
+ gpointer user_data)
{
- gtk_list_store_clear (prefs->booklist_store);
- preferences_bookshelf_populate_store ();
+ DhBook *book = DH_BOOK (book_object);
+ GtkTreeIter iter;
+
+ /* TODO: Proper order AND make sure not already there. */
+ gtk_list_store_append (prefs->booklist_store, &iter);
+ gtk_list_store_set (prefs->booklist_store, &iter,
+ LTCOLUMN_ENABLED, dh_book_get_enabled (book),
+ LTCOLUMN_TITLE, dh_book_get_title (book),
+ LTCOLUMN_BOOK, book,
+ -1);
+}
+
+static void
+preferences_bookshelf_book_deleted_cb (DhBookManager *book_manager,
+ GObject *book_object,
+ gpointer user_data)
+{
+ DhBook *book = DH_BOOK (book_object);
+ GtkTreeIter iter;
+ gboolean found;
+
+ /* Look for the specific book. */
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (prefs->booklist_store), &iter)) {
+ /* The model is empty now */
+ return;
+ }
+
+ /* Loop elements looking for the book */
+ found = FALSE;
+ do {
+ DhBook *in_list_book = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (prefs->booklist_store),
+ &iter,
+ LTCOLUMN_BOOK, &in_list_book,
+ -1);
+ if (in_list_book == book) {
+ found = TRUE;
+ }
+
+ if (in_list_book)
+ g_object_unref (in_list_book);
+ } while (!found && gtk_tree_model_iter_next (GTK_TREE_MODEL (prefs->booklist_store), &iter));
+
+ /* If found, delete item from the store */
+ if (found) {
+ gtk_list_store_remove (prefs->booklist_store, &iter);
+ }
}
static void
@@ -334,6 +387,7 @@ preferences_bookshelf_populate_store (void)
{
GList *l;
+ /* This list already comes ordered */
for (l = dh_book_manager_get_books (prefs->book_manager);
l;
l = g_list_next (l)) {
diff --git a/src/dh-search.c b/src/dh-search.c
index 8bdb187..198458c 100644
--- a/src/dh-search.c
+++ b/src/dh-search.c
@@ -82,6 +82,13 @@ enum {
LAST_SIGNAL
};
+enum {
+ COL_TITLE,
+ COL_LINK,
+ COL_BOOK,
+ N_COLUMNS
+};
+
G_DEFINE_TYPE (DhSearch, dh_search, GTK_TYPE_VBOX);
#define GET_PRIVATE(instance) G_TYPE_INSTANCE_GET_PRIVATE \
@@ -280,7 +287,7 @@ search_combo_set_active_id (DhSearch *search,
gchar *id;
gtk_tree_model_get (model, &iter,
- 1, &id,
+ COL_LINK, &id,
-1);
if (id && strcmp (book_id, id) == 0) {
@@ -320,7 +327,7 @@ search_combo_get_active_id (DhSearch *search)
model = gtk_combo_box_get_model (GTK_COMBO_BOX (priv->book_combo));
gtk_tree_model_get (model, &iter,
- 1, &id,
+ COL_LINK, &id,
-1);
return id;
@@ -477,13 +484,21 @@ search_combo_row_separator_func (GtkTreeModel *model,
{
char *label;
char *link;
+ GObject *book;
gboolean result;
- gtk_tree_model_get (model, iter, 0, &label, 1, &link, -1);
+ gtk_tree_model_get (model, iter,
+ COL_TITLE, &label,
+ COL_LINK, &link,
+ COL_BOOK, &book,
+ -1);
- result = (link == NULL && label == NULL);
+ result = (link == NULL && label == NULL && book == NULL);
g_free (label);
g_free (link);
+ if (book) {
+ g_object_unref (book);
+ }
return result;
}
@@ -502,17 +517,20 @@ search_combo_populate (DhSearch *search)
gtk_list_store_clear (store);
+ /* Add main title */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
- 0, _("All books"),
- 1, NULL,
+ COL_TITLE, _("All books"),
+ COL_LINK, NULL,
+ COL_BOOK, NULL,
-1);
/* Add a separator */
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
- 0, NULL,
- 1, NULL,
+ COL_TITLE, NULL,
+ COL_LINK, NULL,
+ COL_BOOK, NULL,
-1);
for (l = dh_book_manager_get_books (priv->book_manager);
@@ -529,8 +547,9 @@ search_combo_populate (DhSearch *search)
gtk_list_store_append (store, &iter);
gtk_list_store_set (store, &iter,
- 0, dh_link_get_name (link),
- 1, dh_link_get_book_id (link),
+ COL_TITLE, dh_link_get_name (link),
+ COL_LINK, dh_link_get_book_id (link),
+ COL_BOOK, book,
-1);
}
}
@@ -538,6 +557,73 @@ search_combo_populate (DhSearch *search)
gtk_combo_box_set_active (GTK_COMBO_BOX (priv->book_combo), 0);
}
+static void
+search_combo_add_book (DhSearch *search,
+ DhBook *book)
+{
+ DhSearchPriv *priv;
+ GtkListStore *store;
+ GNode *node;
+ GtkTreeIter iter;
+
+ priv = GET_PRIVATE (search);
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (priv->book_combo)));
+
+ node = dh_book_get_tree (book);
+ if (node) {
+ DhLink *link;
+
+ link = node->data;
+ /* TODO: Proper order AND make sure not already there */
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COL_TITLE, dh_link_get_name (link),
+ COL_LINK, dh_link_get_book_id (link),
+ COL_BOOK, book,
+ -1);
+ }
+}
+
+static void
+search_combo_delete_book (DhSearch *search,
+ DhBook *book)
+{
+ DhSearchPriv *priv;
+ GtkListStore *store;
+ GtkTreeIter iter;
+ gboolean found;
+
+ priv = GET_PRIVATE (search);
+ store = GTK_LIST_STORE (gtk_combo_box_get_model (GTK_COMBO_BOX (priv->book_combo)));
+
+ /* Look for the specific book. */
+ if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter)) {
+ /* The model is empty now */
+ return;
+ }
+
+ /* Loop elements looking for the book */
+ found = FALSE;
+ do {
+ DhBook *in_list_book = NULL;
+
+ gtk_tree_model_get (GTK_TREE_MODEL (store),
+ &iter,
+ COL_BOOK, &in_list_book,
+ -1);
+ if (in_list_book == book) {
+ found = TRUE;
+ }
+
+ if (in_list_book)
+ g_object_unref (in_list_book);
+ } while (!found && gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter));
+
+ /* If found, delete item from the store */
+ if (found) {
+ gtk_list_store_remove (store, &iter);
+ }
+}
static void
search_combo_create (DhSearch *search)
@@ -548,12 +634,10 @@ search_combo_create (DhSearch *search)
priv = GET_PRIVATE (search);
- store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
+ store = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_OBJECT);
priv->book_combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
g_object_unref (store);
- search_combo_populate (search);
-
gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (priv->book_combo),
search_combo_row_separator_func,
NULL, NULL);
@@ -565,47 +649,82 @@ search_combo_create (DhSearch *search)
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (priv->book_combo),
cell,
"text", 0);
+
+ search_combo_populate (search);
}
static void
-search_completion_populate (DhSearch *search)
+search_completion_add_book (DhSearch *search,
+ DhBook *book)
{
- DhSearchPriv *priv;
- GList *l;
-
- priv = GET_PRIVATE (search);
+ DhSearchPriv *priv = GET_PRIVATE (search);
+ GList *keywords;
- if (priv->completion) {
- g_completion_free (priv->completion);
+ if (G_UNLIKELY (!priv->completion)) {
+ priv->completion = g_completion_new ((GCompletionFunc) search_complete_func);
}
- priv->completion = g_completion_new ((GCompletionFunc) search_complete_func);
+ keywords = dh_book_get_keywords (book);
+ if (keywords) {
+ g_completion_add_items (priv->completion, keywords);
+ }
+}
- for (l = dh_book_manager_get_books (priv->book_manager);
- l;
- l = g_list_next (l)) {
- DhBook *book = DH_BOOK (l->data);
- GList *keywords;
+static void
+search_completion_delete_book (DhSearch *search,
+ DhBook *book)
+{
+ DhSearchPriv *priv = GET_PRIVATE (search);
+ GList *keywords;
- keywords = dh_book_get_keywords (book);
+ if (G_UNLIKELY (!priv->completion)) {
+ return;
+ }
- if (keywords) {
- g_completion_add_items (priv->completion,
- keywords);
- }
+ keywords = dh_book_get_keywords (book);
+ if (keywords) {
+ g_completion_remove_items (priv->completion, keywords);
}
}
static void
-book_manager_book_list_changed_cb (DhBookManager *book_manager,
+search_book_created_or_enabled_cb (DhBookManager *book_manager,
+ DhBook *book,
gpointer user_data)
{
- DhSearch *search = user_data;
+ DhSearch *search = DH_SEARCH (user_data);
- search_completion_populate (search);
- search_combo_populate (search);
+ search_completion_add_book (search, book);
+ search_combo_add_book (search, book);
+}
+
+static void
+search_book_deleted_or_disabled_cb (DhBookManager *book_manager,
+ DhBook *book,
+ gpointer user_data)
+{
+ DhSearch *search = DH_SEARCH (user_data);
+
+ search_completion_delete_book (search, book);
+ search_combo_delete_book (search, book);
}
+static void
+search_completion_populate (DhSearch *search)
+{
+ DhSearchPriv *priv;
+ GList *l;
+
+ priv = GET_PRIVATE (search);
+
+ for (l = dh_book_manager_get_books (priv->book_manager);
+ l;
+ l = g_list_next (l)) {
+ search_completion_add_book (search, DH_BOOK (l->data));
+ }
+}
+
+
GtkWidget *
dh_search_new (DhBookManager *book_manager)
{
@@ -622,13 +741,22 @@ dh_search_new (DhBookManager *book_manager)
priv = GET_PRIVATE (search);
priv->book_manager = g_object_ref (book_manager);
+
g_signal_connect (priv->book_manager,
- "disabled-book-list-updated",
- G_CALLBACK (book_manager_book_list_changed_cb),
+ "book-created",
+ G_CALLBACK (search_book_created_or_enabled_cb),
search);
g_signal_connect (priv->book_manager,
- "book-list-updated",
- G_CALLBACK (book_manager_book_list_changed_cb),
+ "book-deleted",
+ G_CALLBACK (search_book_deleted_or_disabled_cb),
+ search);
+ g_signal_connect (priv->book_manager,
+ "book-enabled",
+ G_CALLBACK (search_book_created_or_enabled_cb),
+ search);
+ g_signal_connect (priv->book_manager,
+ "book-disabled",
+ G_CALLBACK (search_book_deleted_or_disabled_cb),
search);
gtk_container_set_border_width (GTK_CONTAINER (search), 2);
@@ -706,6 +834,7 @@ dh_search_new (DhBookManager *book_manager)
gtk_box_pack_end (GTK_BOX (search), list_sw, TRUE, TRUE, 0);
search_completion_populate (search);
+
dh_keyword_model_set_words (priv->model, book_manager);
gtk_widget_show_all (GTK_WIDGET (search));
diff --git a/src/dh-util.c b/src/dh-util.c
index 2453c9b..c9ce206 100644
--- a/src/dh-util.c
+++ b/src/dh-util.c
@@ -472,7 +472,7 @@ dh_util_state_load_books_disabled (void)
key = util_state_get_key ("main/contents", "books_disabled");
ige_conf_get_string_list (ige_conf_get (), key, &books_disabled);
- g_free(key);
+ g_free (key);
return books_disabled;
}
@@ -484,7 +484,7 @@ dh_util_state_store_books_disabled (GSList *books_disabled)
key = util_state_get_key ("main/contents", "books_disabled");
ige_conf_set_string_list (ige_conf_get (), key, books_disabled);
- g_free(key);
+ g_free (key);
}
static gboolean
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]