GnuCash  2.6.99
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
gnc-plugin.c
Go to the documentation of this file.
1 /*
2  * gnc-plugin.c --
3  *
4  * Copyright (C) 2003 Jan Arne Petersen <[email protected]>
5  * Copyright (C) 2003,2005 David Hampton <[email protected]>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, contact:
19  *
20  * Free Software Foundation Voice: +1-617-542-5942
21  * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652
22  * Boston, MA 02110-1301, USA [email protected]
23  */
24 
35 #include "config.h"
36 
37 #include <gtk/gtk.h>
38 #include <glib/gi18n.h>
39 
40 #include "gnc-plugin.h"
41 #include "gnc-engine.h"
42 #include "gnc-filepath-utils.h"
43 #include "gnc-gnome-utils.h"
44 #include "gnc-gobject-utils.h"
45 
47 static QofLogModule log_module = GNC_MOD_GUI;
49 static gpointer parent_class = NULL;
50 
51 static void gnc_plugin_class_init (GncPluginClass *klass);
52 static void gnc_plugin_init (GncPlugin *plugin_page,
53  GncPluginClass *klass);
54 static void gnc_plugin_finalize (GObject *object);
55 
56 
59 typedef struct GncPluginPrivate
60 {
61  gpointer dummy;
63 
64 #define GNC_PLUGIN_GET_PRIVATE(o) \
65  (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN, GncPluginPrivate))
66 
67 
70 GType
72 {
73  static GType gnc_plugin_type = 0;
74 
75  if (gnc_plugin_type == 0)
76  {
77  static const GTypeInfo our_info =
78  {
79  sizeof (GncPluginClass),
80  NULL, /* base_init */
81  NULL, /* base_finalize */
82  (GClassInitFunc) gnc_plugin_class_init,
83  NULL, /* class_finalize */
84  NULL, /* class_data */
85  sizeof (GncPlugin),
86  0, /* n_preallocs */
87  (GInstanceInitFunc) gnc_plugin_init,
88  };
89 
90  gnc_plugin_type = g_type_register_static (G_TYPE_OBJECT,
91  GNC_PLUGIN_NAME,
92  &our_info, 0);
93  }
94 
95  return gnc_plugin_type;
96 }
97 
98 
106 static void
107 gnc_plugin_class_init (GncPluginClass *klass)
108 {
109  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
110 
111  parent_class = g_type_class_peek_parent (klass);
112  gobject_class->finalize = gnc_plugin_finalize;
113 
114  g_type_class_add_private(klass, sizeof(GncPluginPrivate));
115 }
116 
117 
126 static void
127 gnc_plugin_init (GncPlugin *plugin_page, GncPluginClass *klass)
128 {
129  gnc_gobject_tracking_remember(G_OBJECT(plugin_page), \
130  G_OBJECT_CLASS(klass));
131 }
132 
133 
141 static void
142 gnc_plugin_finalize (GObject *object)
143 {
144  g_return_if_fail (GNC_IS_PLUGIN (object));
145 
147  G_OBJECT_CLASS (parent_class)->finalize (object);
148 }
149 
150 
156 void
158  GncMainWindow *window,
159  GQuark type)
160 {
161  GncPluginClass *klass;
162  GtkActionGroup *action_group;
163 
164  g_return_if_fail (GNC_IS_PLUGIN (plugin));
165  klass = GNC_PLUGIN_GET_CLASS (plugin);
166  ENTER (": plugin %s(%p), window %p", gnc_plugin_get_name(plugin),
167  plugin, window);
168 
169  /*
170  * Update window with additional UI items
171  */
172  if (klass->actions_name)
173  {
174  DEBUG ("%s: %d actions to merge with gui from %s",
175  klass->actions_name, (klass->n_actions + klass->n_toggle_actions), klass->ui_filename);
177  klass->actions, klass->n_actions,
178  klass->toggle_actions, klass->n_toggle_actions,
179  klass->ui_filename, plugin);
180 
181 
182  if (klass->important_actions)
183  {
184  action_group =
187  klass->important_actions);
188  }
189  }
190 
191  /*
192  * Do plugin specific actions.
193  */
194  if (GNC_PLUGIN_GET_CLASS (plugin)->add_to_window)
195  {
196  DEBUG ("Calling child class function %p", GNC_PLUGIN_GET_CLASS (plugin)->add_to_window);
197  GNC_PLUGIN_GET_CLASS (plugin)->add_to_window (plugin, window, type);
198  }
199  LEAVE ("");
200 }
201 
202 
203 /* Remove the specified plugin from the specified window. This
204  * function will call the plugin to perform any plugin specific
205  * actions and remove the page's user interface from the window.
206  *
207  * See gnc-plugin.h for documentation on the function arguments. */
208 void
210  GncMainWindow *window,
211  GQuark type)
212 {
213  GncPluginClass *klass;
214 
215  g_return_if_fail (GNC_IS_PLUGIN (plugin));
216  klass = GNC_PLUGIN_GET_CLASS (plugin);
217  ENTER (": plugin %s(%p), window %p", gnc_plugin_get_name(plugin),
218  plugin, window);
219 
220  /*
221  * Do plugin specific actions.
222  */
223  if (GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window)
224  {
225  DEBUG ("Calling child class function %p",
226  GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window);
227  GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window (plugin, window, type);
228  }
229 
230  /*
231  * Update window to remove UI items
232  */
233  if (klass->actions_name)
234  {
235  DEBUG ("%s: %d actions to unmerge",
236  klass->actions_name, (klass->n_actions + klass->n_toggle_actions));
238  }
239  LEAVE ("");
240 }
241 
242 
245 const gchar *
247 {
248  g_return_val_if_fail (GNC_IS_PLUGIN (plugin), NULL);
249  return (GNC_PLUGIN_GET_CLASS(plugin)->plugin_name);
250 }
251 
252 
253 /************************************************************
254  * Utility Functions *
255  ************************************************************/
256 
257 
262 void
263 gnc_plugin_init_short_names (GtkActionGroup *action_group,
264  action_toolbar_labels *toolbar_labels)
265 {
266  GtkAction *action;
267  GValue value = { 0, };
268  gint i;
269 
270  g_value_init (&value, G_TYPE_STRING);
271 
272  for (i = 0; toolbar_labels[i].action_name; i++)
273  {
274  /* Add a couple of short labels for the toolbar */
275  action = gtk_action_group_get_action (action_group,
276  toolbar_labels[i].action_name);
277  g_value_set_static_string (&value, gettext(toolbar_labels[i].label));
278  g_object_set_property (G_OBJECT(action), "short_label", &value);
279  }
280 }
281 
282 
288 void
289 gnc_plugin_set_important_actions (GtkActionGroup *action_group,
290  const gchar **name)
291 {
292  GtkAction *action;
293  gint i;
294 
295  for (i = 0; name[i]; i++)
296  {
297  action = gtk_action_group_get_action (action_group, name[i]);
298  g_object_set (G_OBJECT(action), "is_important", TRUE, NULL);
299  }
300 
301  /* If this trips, you've got too many "important" actions. That
302  * can't *all* be that important, can they? */
303  g_assert(i <= 3);
304 }
305 
306 
307 /* Update a property of existing UI actions. This function can
308  * modify actions making them visible, invisible, sensitive, or
309  * insensitive.
310  *
311  * See gnc-plugin.h for documentation on the function arguments. */
312 void
313 gnc_plugin_update_actions (GtkActionGroup *action_group,
314  const gchar **action_names,
315  const gchar *property_name,
316  gboolean value)
317 {
318  GtkAction *action;
319  GValue gvalue = { 0 };
320  gint i;
321 
322  g_value_init (&gvalue, G_TYPE_BOOLEAN);
323  g_value_set_boolean (&gvalue, value);
324 
325  for (i = 0; action_names[i]; i++)
326  {
327  action = gtk_action_group_get_action (action_group, action_names[i]);
328  if (action)
329  {
330  g_object_set_property (G_OBJECT(action), property_name, &gvalue);
331  }
332  else
333  {
334  g_warning("No such action with name '%s' in action group %s (size %d)",
335  action_names[i], gtk_action_group_get_name(action_group),
336  g_list_length(gtk_action_group_list_actions(action_group)));
337  }
338  }
339 }
340 
341 
345 gint
346 gnc_plugin_add_actions (GtkUIManager *ui_merge,
347  GtkActionGroup *action_group,
348  const gchar *filename)
349 {
350  GError *error = NULL;
351  gchar *pathname;
352  gint merge_id;
353 
354  g_return_val_if_fail (ui_merge, 0);
355  g_return_val_if_fail (action_group, 0);
356  g_return_val_if_fail (filename, 0);
357 
358  ENTER("ui_merge %p, action_group %p, filename %s",
359  ui_merge, action_group, filename);
360  gtk_ui_manager_insert_action_group (ui_merge, action_group, 0);
361 
362  pathname = gnc_filepath_locate_ui_file (filename);
363  if (pathname == NULL)
364  {
365  LEAVE("fail");
366  return 0;
367  }
368 
369  merge_id = gtk_ui_manager_add_ui_from_file (ui_merge, pathname, &error);
370  DEBUG("merge_id is %d", merge_id);
371 
372  g_assert(merge_id || error);
373  if (merge_id)
374  {
375  gtk_ui_manager_ensure_update (ui_merge);
376  }
377  else
378  {
379  g_critical("Failed to load ui file.\n Filename %s\n Error %s",
380  filename, error->message);
381  g_error_free(error);
382  }
383 
384  g_free(pathname);
385  LEAVE(" ");
386  return merge_id;
387 }
388 
389 #if 0
390 static void
391 gnc_plugin_base_init (gpointer klass)
392 {
393  static gboolean initialized = FALSE;
394 
395  if (!initialized)
396  {
397  initialized = TRUE;
398 
399  signals[MERGE_ACTIONS] = g_signal_new ("merge-actions",
400  G_OBJECT_CLASS_TYPE (klass),
401  G_SIGNAL_RUN_FIRST,
402  G_STRUCT_OFFSET (GncPluginClass, merge_actions),
403  NULL, NULL,
404  g_cclosure_marshal_VOID__POINTER,
405  G_TYPE_NONE,
406  1,
407  GTK_TYPE_MENU_MERGE);
408  signals[UNMERGE_ACTIONS] = g_signal_new ("unmerge-actions",
409  G_OBJECT_CLASS_TYPE (klass),
410  G_SIGNAL_RUN_FIRST,
411  G_STRUCT_OFFSET (GncPluginClass, unmerge_actions),
412  NULL, NULL,
413  g_cclosure_marshal_VOID__POINTER,
414  G_TYPE_NONE,
415  1,
416  GTK_TYPE_MENU_MERGE);
417  }
418 }
419 #endif
420 
void gnc_gobject_tracking_remember(GObject *object, GObjectClass *klass)
void gnc_gobject_tracking_forget(GObject *object)
struct GncPluginPrivate GncPluginPrivate
#define DEBUG(format, args...)
Definition: qoflog.h:255
void gnc_plugin_add_to_window(GncPlugin *plugin, GncMainWindow *window, GQuark type)
Definition: gnc-plugin.c:157
gchar * gnc_filepath_locate_ui_file(const gchar *name)
void gnc_main_window_unmerge_actions(GncMainWindow *window, const gchar *group_name)
#define ENTER(format, args...)
Definition: qoflog.h:261
guint n_toggle_actions
Definition: gnc-plugin.h:129
void gnc_main_window_merge_actions(GncMainWindow *window, const gchar *group_name, GtkActionEntry *actions, guint n_actions, GtkToggleActionEntry *toggle_actions, guint n_toggle_actions, const gchar *filename, gpointer user_data)
const gchar * ui_filename
Definition: gnc-plugin.h:137
GType gnc_plugin_get_type(void)
Definition: gnc-plugin.c:71
GtkActionEntry * actions
Definition: gnc-plugin.h:122
Gobject helper routines.
gint gnc_plugin_add_actions(GtkUIManager *ui_merge, GtkActionGroup *action_group, const gchar *filename)
Definition: gnc-plugin.c:346
void gnc_plugin_init_short_names(GtkActionGroup *action_group, action_toolbar_labels *toolbar_labels)
Definition: gnc-plugin.c:263
const gchar ** important_actions
Definition: gnc-plugin.h:134
Gnome specific utility functions.
void gnc_plugin_remove_from_window(GncPlugin *plugin, GncMainWindow *window, GQuark type)
Definition: gnc-plugin.c:209
const gchar * gnc_plugin_get_name(GncPlugin *plugin)
Definition: gnc-plugin.c:246
GtkToggleActionEntry * toggle_actions
Definition: gnc-plugin.h:127
All type declarations for the whole Gnucash engine.
const gchar * actions_name
Definition: gnc-plugin.h:119
GtkActionGroup * gnc_main_window_get_action_group(GncMainWindow *window, const gchar *group_name)
void gnc_plugin_update_actions(GtkActionGroup *action_group, const gchar **action_names, const gchar *property_name, gboolean value)
Definition: gnc-plugin.c:313
Functions for adding plugins to a GnuCash window.
#define LEAVE(format, args...)
Definition: qoflog.h:271
File path resolution utility functions.
void gnc_plugin_set_important_actions(GtkActionGroup *action_group, const gchar **name)
Definition: gnc-plugin.c:289
const gchar * QofLogModule
Definition: qofid.h:89
const char * action_name
Definition: gnc-plugin.h:231