LCOV - code coverage report
Current view: top level - libgnucash/engine - gnc-hooks.c (source / functions) Coverage Total Hit
Test: gnucash.info Lines: 74.7 % 95 71
Test Date: 2026-11-02 18:19:43 Functions: 75.0 % 8 6
Legend: Lines:     hit not hit

            Line data    Source code
       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              : 
      31              : static QofLogModule log_module = GNC_MOD_ENGINE;
      32              : 
      33              : static GHashTable* gnc_hooks_list = NULL;
      34              : static gboolean gnc_hooks_initialized = FALSE;
      35              : 
      36              : typedef struct
      37              : {
      38              :     gchar     *desc;
      39              :     GHookList *danglers;
      40              :     gint       num_args;
      41              : } GncHook;
      42              : 
      43              : 
      44              : gchar *
      45          442 : gnc_hook_create (const gchar *name, gint num_args, const gchar *desc)
      46              : {
      47              :     GncHook *hook_list;
      48              : 
      49          442 :     g_return_val_if_fail(name != NULL, NULL);
      50          442 :     g_return_val_if_fail(num_args <= 1, NULL);
      51          442 :     g_return_val_if_fail(desc != NULL, NULL);
      52              : 
      53          442 :     ENTER("name %s", name);
      54          442 :     if (gnc_hooks_list == NULL)
      55              :     {
      56           34 :         gnc_hooks_list = g_hash_table_new(g_str_hash, g_str_equal);
      57              : 
      58              :         /* If we're not initialized then initialize now */
      59           34 :         if (!gnc_hooks_initialized)
      60            0 :             gnc_hooks_init();
      61              :     }
      62              : 
      63          442 :     hook_list = g_hash_table_lookup(gnc_hooks_list, name);
      64          442 :     if (hook_list)
      65              :     {
      66            0 :         LEAVE("List %s(%p) already exists", name, hook_list);
      67            0 :         return((gchar*)name);
      68              :     }
      69              : 
      70          442 :     hook_list = g_new0(GncHook, 1);
      71          442 :     hook_list->desc = g_strdup(desc);
      72          442 :     hook_list->danglers = g_malloc(sizeof(GHookList));
      73          442 :     g_hook_list_init(hook_list->danglers, sizeof(GHook));
      74          442 :     hook_list->num_args = num_args;
      75          442 :     g_hash_table_insert(gnc_hooks_list, (gchar *)name, hook_list);
      76              : 
      77          442 :     LEAVE("created list %s(%p)", name, hook_list);
      78          442 :     return (gchar *)name;
      79              : }
      80              : 
      81              : static GncHook *
      82           37 : gnc_hook_lookup (const gchar *name)
      83              : {
      84              :     GncHook *hook;
      85              : 
      86           37 :     ENTER("name %s", name);
      87           37 :     if (gnc_hooks_list == NULL)
      88              :     {
      89            3 :         PINFO("no hook lists");
      90            3 :         gnc_hooks_init();
      91              :     }
      92              : 
      93           37 :     hook = g_hash_table_lookup(gnc_hooks_list, name);
      94           37 :     LEAVE("hook list %p", hook);
      95           37 :     return(hook);
      96              : }
      97              : 
      98              : int
      99           31 : gnc_hook_num_args (const gchar *name)
     100              : {
     101              :     GncHook *hook;
     102           31 :     int num_args = -1;
     103              : 
     104           31 :     ENTER("name %s", name);
     105           31 :     if (gnc_hooks_list == NULL)
     106              :     {
     107           31 :         PINFO("no hook lists");
     108           31 :         gnc_hooks_init();
     109              :     }
     110              : 
     111           31 :     hook = g_hash_table_lookup(gnc_hooks_list, name);
     112           31 :     if (hook)
     113           31 :         num_args = hook->num_args;
     114           31 :     LEAVE("hook list %p, num_args %i", hook, num_args);
     115           31 :     return(num_args);
     116              : }
     117              : 
     118              : void
     119           34 : gnc_hook_add_dangler (const gchar *name, GFunc callback,
     120              :                       GDestroyNotify destroy, gpointer cb_arg)
     121              : {
     122              :     GncHook *gnc_hook;
     123              :     GHook *hook;
     124              : 
     125           34 :     ENTER("list %s, function %p, cbarg %p", name, callback, cb_arg);
     126           34 :     gnc_hook = gnc_hook_lookup(name);
     127           34 :     g_return_if_fail(gnc_hook != NULL);
     128           34 :     hook = g_hook_alloc(gnc_hook->danglers);
     129           34 :     hook->func = callback;
     130           34 :     hook->data = cb_arg;
     131           34 :     hook->destroy = destroy;
     132           34 :     g_hook_append(gnc_hook->danglers, hook);
     133           34 :     LEAVE("");
     134              : }
     135              : 
     136              : void
     137            0 : gnc_hook_remove_dangler (const gchar *name, GFunc callback)
     138              : {
     139              :     GncHook *gnc_hook;
     140              :     GHook *hook;
     141              : 
     142            0 :     ENTER("name %s, function %p", name, callback);
     143            0 :     gnc_hook = gnc_hook_lookup(name);
     144            0 :     if (gnc_hook == NULL)
     145              :     {
     146            0 :         LEAVE("Unknown hook list %s", name);
     147            0 :         return;
     148              :     }
     149              : 
     150            0 :     hook = g_hook_find_func(gnc_hook->danglers, TRUE, callback);
     151            0 :     if (hook == NULL)
     152              :     {
     153            0 :         LEAVE("Hook %p not found in %s", callback, name);
     154            0 :         return;
     155              :     }
     156              : 
     157            0 :     g_hook_destroy_link(gnc_hook->danglers, hook);
     158            0 :     LEAVE("Removed %p from %s", hook, name);
     159              : }
     160              : 
     161              : static void
     162            0 : call_hook (GHook *hook, gpointer data)
     163              : {
     164            0 :     ENTER("hook %p (func %p), data %p, cbarg %p", hook, hook->func, data,
     165              :           hook->data);
     166            0 :     ((GFunc)hook->func)(data, hook->data);
     167            0 :     LEAVE("");
     168            0 : }
     169              : 
     170              : void
     171            3 : gnc_hook_run (const gchar *name, gpointer data)
     172              : {
     173              :     GncHook *hook;
     174              : 
     175            3 :     ENTER("list %s, data %p", (name == NULL ? "(null)" : name), data);
     176            3 :     hook = gnc_hook_lookup(name);
     177            3 :     if (!hook)
     178              :     {
     179            0 :         LEAVE("No such hook list");
     180            0 :         return;
     181              :     }
     182            3 :     g_hook_list_marshal(hook->danglers, TRUE, call_hook, data);
     183            3 :     LEAVE("");
     184              : }
     185              : 
     186              : void
     187           34 : gnc_hooks_init(void)
     188              : {
     189           34 :     ENTER("");
     190              : 
     191           34 :     if (gnc_hooks_initialized)
     192              :     {
     193            0 :         LEAVE("Hooks already initialized");
     194            0 :         return;
     195              :     }
     196              : 
     197           34 :     gnc_hooks_initialized = TRUE;
     198              : 
     199           34 :     gnc_hook_create(HOOK_STARTUP, 0,
     200              :                     "Functions to run at startup.  Hook args: ()");
     201           34 :     gnc_hook_create(HOOK_SHUTDOWN, 0,
     202              :                     "Functions to run at guile shutdown.  Hook args: ()");
     203           34 :     gnc_hook_create(HOOK_UI_STARTUP, 0,
     204              :                     "Functions to run when the ui comes up.  Hook args: ()");
     205           34 :     gnc_hook_create(HOOK_UI_POST_STARTUP, 0,
     206              :                     "Functions to run after the ui comes up.  Hook args: ()");
     207           34 :     gnc_hook_create(HOOK_UI_SHUTDOWN, 0,
     208              :                     "Functions to run at ui shutdown.  Hook args: ()");
     209           34 :     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           34 :     gnc_hook_create(HOOK_REPORT, 0,
     213              :                     "Run just before the reports are pushed into the menus."
     214              :                     "  Hook args: ()");
     215           34 :     gnc_hook_create(HOOK_CURRENCY_CHANGED, 0,
     216              :                     "Functions to run when the user changes currency settings.  Hook args: ()");
     217           34 :     gnc_hook_create(HOOK_SAVE_OPTIONS, 0,
     218              :                     "Functions to run when saving options.  Hook args: ()");
     219           34 :     gnc_hook_create(HOOK_ADD_EXTENSION, 0,
     220              :                     "Functions to run when the extensions menu is created."
     221              :                     "  Hook args: ()");
     222              : 
     223           34 :     gnc_hook_create(HOOK_BOOK_OPENED, 1,
     224              :                     "Run after book open.  Hook args: <gnc:Session*>.");
     225           34 :     gnc_hook_create(HOOK_BOOK_CLOSED, 1,
     226              :                     "Run before file close.  Hook args: <gnc:Session*>");
     227           34 :     gnc_hook_create(HOOK_BOOK_SAVED, 1,
     228              :                     "Run after file saved.  Hook args: <gnc:Session*>");
     229              : 
     230           34 :     LEAVE("");
     231              : }
        

Generated by: LCOV version 2.0-1