1 /********************************************************************\ 2 * gnc-component-manager.h - GUI component manager interface * 3 * Copyright (C) 2000 Dave Peticolas <dave@krondo.com> * 4 * * 5 * This program is free software; you can redistribute it and/or * 6 * modify it under the terms of the GNU General Public License as * 7 * published by the Free Software Foundation; either version 2 of * 8 * the License, or (at your option) any later version. * 9 * * 10 * This program is distributed in the hope that it will be useful, * 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 13 * GNU General Public License for more details. * 14 * * 15 * You should have received a copy of the GNU General Public License* 16 * along with this program; if not, write to the Free Software * 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * 18 \********************************************************************/ 19 20 #ifndef GNC_COMPONENT_MANAGER_H 21 #define GNC_COMPONENT_MANAGER_H 22 23 #include <glib.h> 24 25 #include "qof.h" 26 27 28 #define NO_COMPONENT (-1) 29 30 typedef struct 31 { 32 QofEventId event_mask; 33 } EventInfo; 34 35 36 /* GNCComponentRefreshHandler 37 * Handler invoked to inform the component that a refresh 38 * may be needed. 39 * 40 * changes: if NULL, the component should perform a refresh. 41 * 42 * if non-NULL, changes is a GncGUID hash that maps 43 * GUIDs to EventInfo structs describing which 44 * events have been received. Entities not in 45 * the hash have not generated any events. 46 * Entities which have been destroyed will be in 47 * the hash, but may not exist anymore. 48 * 49 * Note since refreshes may not occur with every change, 50 * an entity may have all three change values. 51 * 52 * The component should use 'changes' to determine whether 53 * or not a refresh is needed. The hash table must not be 54 * changed. 55 * 56 * Notes on refreshing: when the handler is invoked any engine 57 * entities used by the component may have 58 * already been deleted. 'Refreshing' the 59 * component may require closing the component. 60 * 61 * Notes on dealing with destroyed entities: As stated above, entities 62 * in the changes GHashTable may no longer exist. So how can you 63 * determine if this has happened? Well, it's a good idea to check 64 * for the QOF_EVENT_DESTROY bit in the EventInfo structure. Of 65 * course, that means you need the hash key (GncGUID) for the destroyed 66 * entity. How are you going to get the GncGUID from the entity if the 67 * entity has already been destroyed? You're not. So, you have to 68 * save a COPY of the key (GncGUID) away beforehand. 69 * 70 * user_data: user_data supplied when component was registered. 71 */ 72 typedef void (*GNCComponentRefreshHandler) (GHashTable *changes, 73 gpointer user_data); 74 75 /* GNCComponentCloseHandler 76 * Handler invoked to close the component. 77 * 78 * user_data: user_data supplied when component was registered. 79 * 80 * Notes on closing: components are not automatically unregistered 81 * when the close handler is invoked. Components 82 * may not ignore the handler. 83 */ 84 typedef void (*GNCComponentCloseHandler) (gpointer user_data); 85 86 87 /* GNCComponentFindHandler 88 * Handler invoked when searching for a component. 89 * 90 * find_data: find_data supplied when search was started. 91 * user_data: user_data supplied when component was registered. 92 * 93 * Return: TRUE if the component matches the search criteria. 94 */ 95 typedef gboolean (*GNCComponentFindHandler) (gpointer find_data, 96 gpointer user_data); 97 98 /* GNCComponentHandler 99 * Generic handler used in iterating over components. 100 * 101 * component_class: class of component 102 * component_id: id of component 103 * iter_data: user_data supplied by caller 104 * 105 * Return: TRUE if the callback did something 106 */ 107 typedef gboolean (*GNCComponentHandler) (const char *component_class, 108 gint component_id, 109 gpointer user_data, 110 gpointer iter_data); 111 112 /* gnc_component_manager_init 113 * Initialize the component manager. 114 */ 115 void gnc_component_manager_init (void); 116 117 /* gnc_component_manager_shutdown 118 * Shutdown the component manager. 119 */ 120 void gnc_component_manager_shutdown (void); 121 122 /* gnc_register_gui_component 123 * Register a GUI component with the manager. 124 * 125 * component_class: a string defining a class of components 126 * certain component functions can be performed 127 * on all components in a class. For that reason, 128 * components in the same class should all use 129 * the same type for user_data. 130 * 131 * refresh_cb: refresh handler, may be NULL 132 * close_cb: close handler, may be NULL 133 * user_data: user_data argument for handlers 134 * 135 * 136 * Notes: After a refresh handler is registered, the 137 * component must use the API calls below to 138 * inform the component manager which engine 139 * entities are being 'watched', i.e., which 140 * engine entities may cause the component 141 * to need refreshing. 142 * 143 * When a component is first registered, it 144 * is not watching anything, and thus will 145 * not receive refresh events. 146 * 147 * Return: id of component, or NO_COMPONENT, if error 148 */ 149 gint gnc_register_gui_component (const char *component_class, 150 GNCComponentRefreshHandler refresh_handler, 151 GNCComponentCloseHandler close_handler, 152 gpointer user_data); 153 154 /* gnc_gui_component_set_session 155 * Set the associated session of this component 156 * 157 * component_id: id of component which is watching the entity 158 * session: the session this component is associated with 159 */ 160 void gnc_gui_component_set_session (gint component_id, gpointer session); 161 162 /* gnc_gui_component_watch_entity 163 * Add an entity to the list of those being watched by the component. 164 * Only entities with refresh handlers should add watches. 165 * 166 * component_id: id of component which is watching the entity 167 * entity: id of entity to watch 168 * event_mask: mask which determines which kinds of events are watched 169 * setting the mask to 0 turns off watching for the entity. 170 */ 171 void gnc_gui_component_watch_entity (gint component_id, 172 const GncGUID *entity, 173 QofEventId event_mask); 174 175 /* gnc_gui_component_watch_entity_type 176 * Watch all entities of a particular type. 177 * 178 * component_id: id of component which is watching the entity type 179 * entity_type: type of entity to watch, either GNC_ID_TRANS or 180 * GNC_ID_ACCOUNT 181 * event_mask: mask which determines which kinds of events are watched 182 * setting the mask to 0 turns off watching for the entity type 183 */ 184 void gnc_gui_component_watch_entity_type (gint component_id, 185 QofIdTypeConst entity_type, 186 QofEventId event_mask); 187 188 /* gnc_gui_get_entity_events 189 * Return the event info of the events which have been generated by 190 * the given entity. 191 * 192 * changes: a hash of changes as in the refresh handler 193 * entity: the GncGUID of the entity to get the event mask for 194 * 195 * Returns: the event info of the entity, or NULL 196 * if it is not found. 197 */ 198 const EventInfo * gnc_gui_get_entity_events (GHashTable *changes, 199 const GncGUID *entity); 200 201 /* gnc_gui_component_clear_watches 202 * Clear all watches for the component. 203 * 204 * component_id: id of component to clear watches for. 205 */ 206 void gnc_gui_component_clear_watches (gint component_id); 207 208 /* gnc_unregister_gui_component 209 * Unregister a gui component from the manager. 210 * 211 * component_id: id of component to unregister 212 */ 213 void gnc_unregister_gui_component (gint component_id); 214 215 /* gnc_unregister_gui_component_by_data 216 * Unregister a gui component using the user_data pointer. 217 * 218 * component_class: class component is in 219 * user_data: user_data pointer of component to unregister 220 * all components with that user_data in the 221 * class are unregistered. 222 */ 223 void gnc_unregister_gui_component_by_data (const char *component_class, 224 gpointer user_data); 225 226 /* gnc_suspend_gui_refresh 227 * Suspend refresh handlers by the component manager. 228 * This routine may be called multiple times. Each call 229 * increases the suspend counter (starts at zero). 230 */ 231 void gnc_suspend_gui_refresh (void); 232 233 /* gnc_resume_gui_refresh 234 * Resume refresh handlers by the component manager. 235 * Each call reduces the suspend counter by one. When 236 * the counter reaches zero, all changes which have 237 * occurred since the last refresh are collected and 238 * passed to the components in refresh handlers. 239 */ 240 void gnc_resume_gui_refresh (void); 241 242 /* gnc_gui_refresh_all 243 * Force all components to refresh. 244 * 245 * This routine may only be invoked when the suspend counter 246 * is zero. It should never be mixed with the suspend/resume 247 * refresh routines. 248 */ 249 void gnc_gui_refresh_all (void); 250 251 /* gnc_gui_refresh_suspended 252 * Return TRUE if gui refreshes are suspended. 253 */ 254 gboolean gnc_gui_refresh_suspended (void); 255 256 /* gnc_close_gui_component 257 * Invoke the close handler for the indicated component. 258 * 259 * component_id: id of component to close 260 */ 261 void gnc_close_gui_component (gint component_id); 262 263 /* gnc_close_gui_component_by_data 264 * Invoke the close handler for components in the given 265 * class with the given user_data. 266 * 267 * component_class: class to close components in 268 * user_data: user_data of component to close 269 * all components with that user_data 270 * are closed. 271 */ 272 void gnc_close_gui_component_by_data (const char *component_class, 273 gpointer user_data); 274 275 /* gnc_close_gui_component_by_session 276 * Invoke the close handler for components with the given session 277 * 278 * session: session to close 279 * all components with that session 280 * are closed. 281 */ 282 void gnc_close_gui_component_by_session (gpointer session); 283 284 /* gnc_find_gui_components 285 * Search for components in the specified class. 286 * 287 * component_class: the class to search for components in 288 * must be non-NULL 289 * find_cb: the handler used to search for the component 290 * if NULL, all components in class are returned 291 * find_data: find_data passed to find_cb 292 * 293 * Returns: GList of user_data of found components, or NULL if none found 294 * The list should be freed with g_list_free(). 295 * 296 * Notes on finding: components should not be registered or unregistered 297 * by the find callback. 298 */ 299 GList * gnc_find_gui_components (const char *component_class, 300 GNCComponentFindHandler find_handler, 301 gpointer find_data); 302 303 /* gnc_find_first_gui_component 304 * Search for the first matching component in the specified class. 305 * 306 * component_class: the class to search for components in 307 * must be non-NULL 308 * find_cb: the handler used to search for the component 309 * must be non-null 310 * find_data: find_data passed to find_cb 311 * 312 * Returns: user_data of first found component, or NULL if none found 313 * 314 * Notes on finding: components should not be registered or unregistered 315 * by the find callback. 316 */ 317 gpointer gnc_find_first_gui_component (const char *component_class, 318 GNCComponentFindHandler find_handler, 319 gpointer find_data); 320 321 /* gnc_forall_gui_components 322 * Invoke 'handler' for components in the database. 323 * 324 * component_class: class to iterate over, if NULL then 325 * all classes are iterated over 326 * handler: handler to invoke 327 * iter_data: data passed to handler 328 * 329 * Notes on forall: components may be unregistered by the handler, 330 * but no components should be registered. 331 */ 332 gint gnc_forall_gui_components (const char *component_class, 333 GNCComponentHandler handler, 334 gpointer iter_data); 335 336 #endif 337