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: 2025-02-07 16:25:45 Functions: 75.0 % 8 6
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: - 0 0

             Branch data     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                 :         429 : gnc_hook_create (const gchar *name, gint num_args, const gchar *desc)
      46                 :             : {
      47                 :             :     GncHook *hook_list;
      48                 :             : 
      49                 :         429 :     g_return_val_if_fail(name != NULL, NULL);
      50                 :         429 :     g_return_val_if_fail(num_args <= 1, NULL);
      51                 :         429 :     g_return_val_if_fail(desc != NULL, NULL);
      52                 :             : 
      53                 :         429 :     ENTER("name %s", name);
      54                 :         429 :     if (gnc_hooks_list == NULL)
      55                 :             :     {
      56                 :          33 :         gnc_hooks_list = g_hash_table_new(g_str_hash, g_str_equal);
      57                 :             : 
      58                 :             :         /* If we're not initialized then initialize now */
      59                 :          33 :         if (!gnc_hooks_initialized)
      60                 :           0 :             gnc_hooks_init();
      61                 :             :     }
      62                 :             : 
      63                 :         429 :     hook_list = g_hash_table_lookup(gnc_hooks_list, name);
      64                 :         429 :     if (hook_list)
      65                 :             :     {
      66                 :           0 :         LEAVE("List %s(%p) already exists", name, hook_list);
      67                 :           0 :         return((gchar*)name);
      68                 :             :     }
      69                 :             : 
      70                 :         429 :     hook_list = g_new0(GncHook, 1);
      71                 :         429 :     hook_list->desc = g_strdup(desc);
      72                 :         429 :     hook_list->danglers = g_malloc(sizeof(GHookList));
      73                 :         429 :     g_hook_list_init(hook_list->danglers, sizeof(GHook));
      74                 :         429 :     hook_list->num_args = num_args;
      75                 :         429 :     g_hash_table_insert(gnc_hooks_list, (gchar *)name, hook_list);
      76                 :             : 
      77                 :         429 :     LEAVE("created list %s(%p)", name, hook_list);
      78                 :         429 :     return (gchar *)name;
      79                 :             : }
      80                 :             : 
      81                 :             : static GncHook *
      82                 :          36 : gnc_hook_lookup (const gchar *name)
      83                 :             : {
      84                 :             :     GncHook *hook;
      85                 :             : 
      86                 :          36 :     ENTER("name %s", name);
      87                 :          36 :     if (gnc_hooks_list == NULL)
      88                 :             :     {
      89                 :           3 :         PINFO("no hook lists");
      90                 :           3 :         gnc_hooks_init();
      91                 :             :     }
      92                 :             : 
      93                 :          36 :     hook = g_hash_table_lookup(gnc_hooks_list, name);
      94                 :          36 :     LEAVE("hook list %p", hook);
      95                 :          36 :     return(hook);
      96                 :             : }
      97                 :             : 
      98                 :             : int
      99                 :          30 : gnc_hook_num_args (const gchar *name)
     100                 :             : {
     101                 :             :     GncHook *hook;
     102                 :          30 :     int num_args = -1;
     103                 :             : 
     104                 :          30 :     ENTER("name %s", name);
     105                 :          30 :     if (gnc_hooks_list == NULL)
     106                 :             :     {
     107                 :          30 :         PINFO("no hook lists");
     108                 :          30 :         gnc_hooks_init();
     109                 :             :     }
     110                 :             : 
     111                 :          30 :     hook = g_hash_table_lookup(gnc_hooks_list, name);
     112                 :          30 :     if (hook)
     113                 :          30 :         num_args = hook->num_args;
     114                 :          30 :     LEAVE("hook list %p, num_args %i", hook, num_args);
     115                 :          30 :     return(num_args);
     116                 :             : }
     117                 :             : 
     118                 :             : void
     119                 :          33 : 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                 :          33 :     ENTER("list %s, function %p, cbarg %p", name, callback, cb_arg);
     126                 :          33 :     gnc_hook = gnc_hook_lookup(name);
     127                 :          33 :     g_return_if_fail(gnc_hook != NULL);
     128                 :          33 :     hook = g_hook_alloc(gnc_hook->danglers);
     129                 :          33 :     hook->func = callback;
     130                 :          33 :     hook->data = cb_arg;
     131                 :          33 :     hook->destroy = destroy;
     132                 :          33 :     g_hook_append(gnc_hook->danglers, hook);
     133                 :          33 :     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                 :          33 : gnc_hooks_init(void)
     188                 :             : {
     189                 :          33 :     ENTER("");
     190                 :             : 
     191                 :          33 :     if (gnc_hooks_initialized)
     192                 :             :     {
     193                 :           0 :         LEAVE("Hooks already initialized");
     194                 :           0 :         return;
     195                 :             :     }
     196                 :             : 
     197                 :          33 :     gnc_hooks_initialized = TRUE;
     198                 :             : 
     199                 :          33 :     gnc_hook_create(HOOK_STARTUP, 0,
     200                 :             :                     "Functions to run at startup.  Hook args: ()");
     201                 :          33 :     gnc_hook_create(HOOK_SHUTDOWN, 0,
     202                 :             :                     "Functions to run at guile shutdown.  Hook args: ()");
     203                 :          33 :     gnc_hook_create(HOOK_UI_STARTUP, 0,
     204                 :             :                     "Functions to run when the ui comes up.  Hook args: ()");
     205                 :          33 :     gnc_hook_create(HOOK_UI_POST_STARTUP, 0,
     206                 :             :                     "Functions to run after the ui comes up.  Hook args: ()");
     207                 :          33 :     gnc_hook_create(HOOK_UI_SHUTDOWN, 0,
     208                 :             :                     "Functions to run at ui shutdown.  Hook args: ()");
     209                 :          33 :     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                 :          33 :     gnc_hook_create(HOOK_REPORT, 0,
     213                 :             :                     "Run just before the reports are pushed into the menus."
     214                 :             :                     "  Hook args: ()");
     215                 :          33 :     gnc_hook_create(HOOK_CURRENCY_CHANGED, 0,
     216                 :             :                     "Functions to run when the user changes currency settings.  Hook args: ()");
     217                 :          33 :     gnc_hook_create(HOOK_SAVE_OPTIONS, 0,
     218                 :             :                     "Functions to run when saving options.  Hook args: ()");
     219                 :          33 :     gnc_hook_create(HOOK_ADD_EXTENSION, 0,
     220                 :             :                     "Functions to run when the extensions menu is created."
     221                 :             :                     "  Hook args: ()");
     222                 :             : 
     223                 :          33 :     gnc_hook_create(HOOK_BOOK_OPENED, 1,
     224                 :             :                     "Run after book open.  Hook args: <gnc:Session*>.");
     225                 :          33 :     gnc_hook_create(HOOK_BOOK_CLOSED, 1,
     226                 :             :                     "Run before file close.  Hook args: <gnc:Session*>");
     227                 :          33 :     gnc_hook_create(HOOK_BOOK_SAVED, 1,
     228                 :             :                     "Run after file saved.  Hook args: <gnc:Session*>");
     229                 :             : 
     230                 :          33 :     LEAVE("");
     231                 :             : }
        

Generated by: LCOV version 2.0-1