GnuCash c935c2f+
Loading...
Searching...
No Matches
gnc-hooks.c
1/*
2 * gnc-hooks.c -- helpers for using Glib hook functions
3 * Copyright (C) 2005 David Hampton <hampton@employees.org>
4 * Derek Atkins <derek@ihtfp.com>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, contact:
18 *
19 * Free Software Foundation Voice: +1-617-542-5942
20 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
21 * Boston, MA 02110-1301, USA gnu@gnu.org
22 */
23
24#include <config.h>
25
26#include <glib.h>
27#include <stdio.h>
28#include "gnc-hooks.h"
29#include "gnc-engine.h"
30
31static QofLogModule log_module = GNC_MOD_ENGINE;
32
33static GHashTable* gnc_hooks_list = NULL;
34static gboolean gnc_hooks_initialized = FALSE;
35
36typedef struct
37{
38 gchar *desc;
39 GHookList *danglers;
40 gint num_args;
41} GncHook;
42
43
44gchar *
45gnc_hook_create (const gchar *name, gint num_args, const gchar *desc)
46{
47 GncHook *hook_list;
48
49 g_return_val_if_fail(name != NULL, NULL);
50 g_return_val_if_fail(num_args <= 1, NULL);
51 g_return_val_if_fail(desc != NULL, NULL);
52
53 ENTER("name %s", name);
54 if (gnc_hooks_list == NULL)
55 {
56 gnc_hooks_list = g_hash_table_new(g_str_hash, g_str_equal);
57
58 /* If we're not initialized then initialize now */
59 if (!gnc_hooks_initialized)
60 gnc_hooks_init();
61 }
62
63 hook_list = g_hash_table_lookup(gnc_hooks_list, name);
64 if (hook_list)
65 {
66 LEAVE("List %s(%p) already exists", name, hook_list);
67 return((gchar*)name);
68 }
69
70 hook_list = g_new0(GncHook, 1);
71 hook_list->desc = g_strdup(desc);
72 hook_list->danglers = g_malloc(sizeof(GHookList));
73 g_hook_list_init(hook_list->danglers, sizeof(GHook));
74 hook_list->num_args = num_args;
75 g_hash_table_insert(gnc_hooks_list, (gchar *)name, hook_list);
76
77 LEAVE("created list %s(%p)", name, hook_list);
78 return (gchar *)name;
79}
80
81static GncHook *
82gnc_hook_lookup (const gchar *name)
83{
84 GncHook *hook;
85
86 ENTER("name %s", name);
87 if (gnc_hooks_list == NULL)
88 {
89 PINFO("no hook lists");
90 gnc_hooks_init();
91 }
92
93 hook = g_hash_table_lookup(gnc_hooks_list, name);
94 LEAVE("hook list %p", hook);
95 return(hook);
96}
97
98int
99gnc_hook_num_args (const gchar *name)
100{
101 GncHook *hook;
102 int num_args = -1;
103
104 ENTER("name %s", name);
105 if (gnc_hooks_list == NULL)
106 {
107 PINFO("no hook lists");
108 gnc_hooks_init();
109 }
110
111 hook = g_hash_table_lookup(gnc_hooks_list, name);
112 if (hook)
113 num_args = hook->num_args;
114 LEAVE("hook list %p, num_args %i", hook, num_args);
115 return(num_args);
116}
117
118void
119gnc_hook_add_dangler (const gchar *name, GFunc callback,
120 GDestroyNotify destroy, gpointer cb_arg)
121{
122 GncHook *gnc_hook;
123 GHook *hook;
124
125 ENTER("list %s, function %p, cbarg %p", name, callback, cb_arg);
126 gnc_hook = gnc_hook_lookup(name);
127 g_return_if_fail(gnc_hook != NULL);
128 hook = g_hook_alloc(gnc_hook->danglers);
129 hook->func = callback;
130 hook->data = cb_arg;
131 hook->destroy = destroy;
132 g_hook_append(gnc_hook->danglers, hook);
133 LEAVE("");
134}
135
136void
137gnc_hook_remove_dangler (const gchar *name, GFunc callback)
138{
139 GncHook *gnc_hook;
140 GHook *hook;
141
142 ENTER("name %s, function %p", name, callback);
143 gnc_hook = gnc_hook_lookup(name);
144 if (gnc_hook == NULL)
145 {
146 LEAVE("Unknown hook list %s", name);
147 return;
148 }
149
150 hook = g_hook_find_func(gnc_hook->danglers, TRUE, callback);
151 if (hook == NULL)
152 {
153 LEAVE("Hook %p not found in %s", callback, name);
154 return;
155 }
156
157 g_hook_destroy_link(gnc_hook->danglers, hook);
158 LEAVE("Removed %p from %s", hook, name);
159}
160
161static void
162call_hook (GHook *hook, gpointer data)
163{
164 ENTER("hook %p (func %p), data %p, cbarg %p", hook, hook->func, data,
165 hook->data);
166 ((GFunc)hook->func)(data, hook->data);
167 LEAVE("");
168}
169
170void
171gnc_hook_run (const gchar *name, gpointer data)
172{
173 GncHook *hook;
174
175 ENTER("list %s, data %p", (name == NULL ? "(null)" : name), data);
176 hook = gnc_hook_lookup(name);
177 if (!hook)
178 {
179 LEAVE("No such hook list");
180 return;
181 }
182 g_hook_list_marshal(hook->danglers, TRUE, call_hook, data);
183 LEAVE("");
184}
185
186void
187gnc_hooks_init(void)
188{
189 ENTER("");
190
191 if (gnc_hooks_initialized)
192 {
193 LEAVE("Hooks already initialized");
194 return;
195 }
196
197 gnc_hooks_initialized = TRUE;
198
199 gnc_hook_create(HOOK_STARTUP, 0,
200 "Functions to run at startup. Hook args: ()");
201 gnc_hook_create(HOOK_SHUTDOWN, 0,
202 "Functions to run at guile shutdown. Hook args: ()");
203 gnc_hook_create(HOOK_UI_STARTUP, 0,
204 "Functions to run when the ui comes up. Hook args: ()");
205 gnc_hook_create(HOOK_UI_POST_STARTUP, 0,
206 "Functions to run after the ui comes up. Hook args: ()");
207 gnc_hook_create(HOOK_UI_SHUTDOWN, 0,
208 "Functions to run at ui shutdown. Hook args: ()");
209 gnc_hook_create(HOOK_NEW_BOOK, 0,
210 "Run after a new (empty) book is opened, before the"
211 " book-opened-hook. Hook args: ()");
212 gnc_hook_create(HOOK_REPORT, 0,
213 "Run just before the reports are pushed into the menus."
214 " Hook args: ()");
215 gnc_hook_create(HOOK_CURRENCY_CHANGED, 0,
216 "Functions to run when the user changes currency settings. Hook args: ()");
217 gnc_hook_create(HOOK_SAVE_OPTIONS, 0,
218 "Functions to run when saving options. Hook args: ()");
219 gnc_hook_create(HOOK_ADD_EXTENSION, 0,
220 "Functions to run when the extensions menu is created."
221 " Hook args: ()");
222
223 gnc_hook_create(HOOK_BOOK_OPENED, 1,
224 "Run after book open. Hook args: <gnc:Session*>.");
225 gnc_hook_create(HOOK_BOOK_CLOSED, 1,
226 "Run before file close. Hook args: <gnc:Session*>");
227 gnc_hook_create(HOOK_BOOK_SAVED, 1,
228 "Run after file saved. Hook args: <gnc:Session*>");
229
230 LEAVE("");
231}
All type declarations for the whole Gnucash engine.
#define PINFO(format, args...)
Print an informational note.
Definition qoflog.h:256
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition qoflog.h:282
#define ENTER(format, args...)
Print a function entry debugging message.
Definition qoflog.h:272