GnuCash  4.12-399-g11d395185c
gnc-plugin.c
Go to the documentation of this file.
1 /*
2  * gnc-plugin.c --
3  *
4  * Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de>
5  * Copyright (C) 2003,2005 David Hampton <hampton@employees.org>
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 gnu@gnu.org
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  void *data);
54 static void gnc_plugin_finalize (GObject *object);
55 
56 
59 typedef struct GncPluginPrivate
60 {
61  gpointer dummy;
63 
64 GNC_DEFINE_TYPE_WITH_CODE(GncPlugin, gnc_plugin, G_TYPE_OBJECT,
65  G_ADD_PRIVATE(GncPlugin))
66 
67 #define GNC_PLUGIN_GET_PRIVATE(o) \
68  ((GncPluginPrivate*)gnc_plugin_get_instance_private((GncPlugin*)o))
69 
77 static void
78 gnc_plugin_class_init (GncPluginClass *klass)
79 {
80  GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
81 
82  parent_class = g_type_class_peek_parent (klass);
83  gobject_class->finalize = gnc_plugin_finalize;
84 }
85 
86 
95 static void
96 gnc_plugin_init (GncPlugin *plugin_page, void *data)
97 {
98  GncPluginClass *klass = (GncPluginClass*)data;
99 
100  gnc_gobject_tracking_remember(G_OBJECT(plugin_page), \
101  G_OBJECT_CLASS(klass));
102 }
103 
104 
112 static void
113 gnc_plugin_finalize (GObject *object)
114 {
115  g_return_if_fail (GNC_IS_PLUGIN (object));
116 
118  G_OBJECT_CLASS (parent_class)->finalize (object);
119 }
120 
121 
127 void
129  GncMainWindow *window,
130  GQuark type)
131 {
132  GncPluginClass *klass;
133  GtkActionGroup *action_group;
134 
135  g_return_if_fail (GNC_IS_PLUGIN (plugin));
136  klass = GNC_PLUGIN_GET_CLASS (plugin);
137  ENTER (": plugin %s(%p), window %p", gnc_plugin_get_name(plugin),
138  plugin, window);
139 
140  /*
141  * Update window with additional UI items
142  */
143  if (klass->actions_name)
144  {
145  DEBUG ("%s: %d actions to merge with gui from %s",
146  klass->actions_name, (klass->n_actions + klass->n_toggle_actions), klass->ui_filename);
148  klass->actions, klass->n_actions,
149  klass->toggle_actions, klass->n_toggle_actions,
150  klass->ui_filename, plugin);
151 
152 
153  if (klass->important_actions)
154  {
155  action_group =
158  klass->important_actions);
159  }
160  }
161 
162  /*
163  * Do plugin specific actions.
164  */
165  if (GNC_PLUGIN_GET_CLASS (plugin)->add_to_window)
166  {
167  DEBUG ("Calling child class function %p", GNC_PLUGIN_GET_CLASS (plugin)->add_to_window);
168  GNC_PLUGIN_GET_CLASS (plugin)->add_to_window (plugin, window, type);
169  }
170  LEAVE ("");
171 }
172 
173 
174 /* Remove the specified plugin from the specified window. This
175  * function will call the plugin to perform any plugin specific
176  * actions and remove the page's user interface from the window.
177  *
178  * See gnc-plugin.h for documentation on the function arguments. */
179 void
181  GncMainWindow *window,
182  GQuark type)
183 {
184  GncPluginClass *klass;
185 
186  g_return_if_fail (GNC_IS_PLUGIN (plugin));
187  klass = GNC_PLUGIN_GET_CLASS (plugin);
188  ENTER (": plugin %s(%p), window %p", gnc_plugin_get_name(plugin),
189  plugin, window);
190 
191  /*
192  * Do plugin specific actions.
193  */
194  if (GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window)
195  {
196  DEBUG ("Calling child class function %p",
197  GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window);
198  GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window (plugin, window, type);
199  }
200 
201  /*
202  * Update window to remove UI items
203  */
204  if (klass->actions_name && !window->just_plugin_prefs)
205  {
206  DEBUG ("%s: %d actions to unmerge",
207  klass->actions_name, (klass->n_actions + klass->n_toggle_actions));
209  }
210  LEAVE ("");
211 }
212 
213 
216 const gchar *
218 {
219  g_return_val_if_fail (GNC_IS_PLUGIN (plugin), NULL);
220  return (GNC_PLUGIN_GET_CLASS(plugin)->plugin_name);
221 }
222 
223 
224 /************************************************************
225  * Utility Functions *
226  ************************************************************/
227 
228 
233 void
234 gnc_plugin_init_short_names (GtkActionGroup *action_group,
235  action_toolbar_labels *toolbar_labels)
236 {
237  GtkAction *action;
238  gint i;
239 
240  for (i = 0; toolbar_labels[i].action_name; i++)
241  {
242  /* Add a couple of short labels for the toolbar */
243  action = gtk_action_group_get_action (action_group,
244  toolbar_labels[i].action_name);
245  gtk_action_set_short_label (action, _(toolbar_labels[i].label));
246  }
247 }
248 
249 
255 void
256 gnc_plugin_set_important_actions (GtkActionGroup *action_group,
257  const gchar **name)
258 {
259  GtkAction *action;
260  gint i;
261 
262  for (i = 0; name[i]; i++)
263  {
264  action = gtk_action_group_get_action (action_group, name[i]);
265  g_object_set (G_OBJECT(action), "is_important", TRUE, NULL);
266  }
267 
268  /* If this trips, you've got too many "important" actions. That
269  * can't *all* be that important, can they? */
270  g_assert(i <= 3);
271 }
272 
273 
274 /* Update a property of existing UI actions. This function can
275  * modify actions making them visible, invisible, sensitive, or
276  * insensitive.
277  *
278  * See gnc-plugin.h for documentation on the function arguments. */
279 void
280 gnc_plugin_update_actions (GtkActionGroup *action_group,
281  const gchar **action_names,
282  const gchar *property_name,
283  gboolean value)
284 {
285  GtkAction *action;
286  gint i;
287 
288  for (i = 0; action_names[i]; i++)
289  {
290  action = gtk_action_group_get_action (action_group, action_names[i]);
291  if (action)
292  {
293  g_object_set (G_OBJECT(action), property_name, value, NULL);
294  }
295  else
296  {
297  g_warning("No such action with name '%s' in action group %s (size %d)",
298  action_names[i], gtk_action_group_get_name(action_group),
299  g_list_length(gtk_action_group_list_actions(action_group)));
300  }
301  }
302 }
303 
304 
308 gint
309 gnc_plugin_add_actions (GtkUIManager *ui_merge,
310  GtkActionGroup *action_group,
311  const gchar *filename)
312 {
313  GError *error = NULL;
314  gchar *pathname;
315  gint merge_id;
316 
317  g_return_val_if_fail (ui_merge, 0);
318  g_return_val_if_fail (action_group, 0);
319  g_return_val_if_fail (filename, 0);
320 
321  ENTER("ui_merge %p, action_group %p, filename %s",
322  ui_merge, action_group, filename);
323  gtk_ui_manager_insert_action_group (ui_merge, action_group, 0);
324 
325  pathname = gnc_filepath_locate_ui_file (filename);
326  if (pathname == NULL)
327  {
328  LEAVE("fail");
329  return 0;
330  }
331 
332  merge_id = gtk_ui_manager_add_ui_from_file (ui_merge, pathname, &error);
333  DEBUG("merge_id is %d", merge_id);
334 
335  g_assert(merge_id || error);
336  if (merge_id)
337  {
338  gtk_ui_manager_ensure_update (ui_merge);
339  }
340  else
341  {
342  g_critical("Failed to load ui file.\n Filename %s\n Error %s",
343  filename, error->message);
344  g_error_free(error);
345  }
346 
347  g_free(pathname);
348  LEAVE(" ");
349  return merge_id;
350 }
351 
352 #if 0
353 static void
354 gnc_plugin_base_init (gpointer klass)
355 {
356  static gboolean initialized = FALSE;
357 
358  if (!initialized)
359  {
360  initialized = TRUE;
361 
362  signals[MERGE_ACTIONS] = g_signal_new ("merge-actions",
363  G_OBJECT_CLASS_TYPE (klass),
364  G_SIGNAL_RUN_FIRST,
365  G_STRUCT_OFFSET (GncPluginClass, merge_actions),
366  NULL, NULL,
367  g_cclosure_marshal_VOID__POINTER,
368  G_TYPE_NONE,
369  1,
370  GTK_TYPE_MENU_MERGE);
371  signals[UNMERGE_ACTIONS] = g_signal_new ("unmerge-actions",
372  G_OBJECT_CLASS_TYPE (klass),
373  G_SIGNAL_RUN_FIRST,
374  G_STRUCT_OFFSET (GncPluginClass, unmerge_actions),
375  NULL, NULL,
376  g_cclosure_marshal_VOID__POINTER,
377  G_TYPE_NONE,
378  1,
379  GTK_TYPE_MENU_MERGE);
380  }
381 }
382 #endif
383 
guint n_actions
The number of actions in the actions array.
Definition: gnc-plugin.h:124
void gnc_gobject_tracking_remember(GObject *object, GObjectClass *klass)
Tell gnucash to remember this object in the database.
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)
Add a set of actions to the specified window.
void gnc_gobject_tracking_forget(GObject *object)
Tell gnucash to remember this object in the database.
#define DEBUG(format, args...)
Print a debugging message.
Definition: qoflog.h:264
A structure for defining alternate action names for use in the toolbar.
Definition: gnc-plugin.h:228
void gnc_plugin_add_to_window(GncPlugin *plugin, GncMainWindow *window, GQuark type)
Add the specified plugin from the specified window.
Definition: gnc-plugin.c:128
gchar * gnc_filepath_locate_ui_file(const gchar *name)
Given a ui file name, find the file in the ui directory associated with this application.
The class data structure for a menu-only plugin.
Definition: gnc-plugin.h:107
void gnc_main_window_unmerge_actions(GncMainWindow *window, const gchar *group_name)
Remove a set of actions from the specified window.
#define ENTER(format, args...)
Print a function entry debugging message.
Definition: qoflog.h:272
guint n_toggle_actions
The number of toggle actions in the toggle actions array.
Definition: gnc-plugin.h:129
const gchar * ui_filename
The relative name of the XML file describing the menu/toolbar action items.
Definition: gnc-plugin.h:137
GtkActionEntry * actions
An array of actions that should automatically be added to any GnuCash "main" content window that is o...
Definition: gnc-plugin.h:122
Gobject helper routines.
gint gnc_plugin_add_actions(GtkUIManager *ui_merge, GtkActionGroup *action_group, const gchar *filename)
Load a new set of actions into an existing UI.
Definition: gnc-plugin.c:309
void gnc_plugin_init_short_names(GtkActionGroup *action_group, action_toolbar_labels *toolbar_labels)
Add "short" labels to existing actions.
Definition: gnc-plugin.c:234
GNC_DEFINE_TYPE_WITH_CODE(GncPlugin, gnc_plugin, G_TYPE_OBJECT, G_ADD_PRIVATE(GncPlugin))
Initialize the class for the new gnucash plugin object.
Definition: gnc-plugin.c:64
const gchar ** important_actions
A NULL terminated list of actions that should be considered important.
Definition: gnc-plugin.h:134
Gnome specific utility functions.
void gnc_plugin_remove_from_window(GncPlugin *plugin, GncMainWindow *window, GQuark type)
Remove the specified plugin from the specified window.
Definition: gnc-plugin.c:180
const gchar * gnc_plugin_get_name(GncPlugin *plugin)
Retrieve the textual name of a plugin.
Definition: gnc-plugin.c:217
GtkToggleActionEntry * toggle_actions
An array of toggle actions that should automatically be added to any GnuCash "main" content window th...
Definition: gnc-plugin.h:127
All type declarations for the whole Gnucash engine.
const gchar * actions_name
A name for the set of actions that will be added by this plugin.
Definition: gnc-plugin.h:119
GtkActionGroup * gnc_main_window_get_action_group(GncMainWindow *window, const gchar *group_name)
Retrieve a specific set of user interface actions from a window.
void gnc_plugin_update_actions(GtkActionGroup *action_group, const gchar **action_names, const gchar *property_name, gboolean value)
Update a property on a set of existing GtkActions.
Definition: gnc-plugin.c:280
The instance data structure for a menu-only plugin.
Definition: gnc-plugin.h:100
Functions for adding plugins to a GnuCash window.
#define LEAVE(format, args...)
Print a function exit debugging message.
Definition: qoflog.h:282
The instance data structure for a main window object.
File path resolution utility functions.
void gnc_plugin_set_important_actions(GtkActionGroup *action_group, const gchar **name)
Mark certain actions as "important".
Definition: gnc-plugin.c:256
The instance private data for a menu-only plugin.
Definition: gnc-plugin.c:59
const char * action_name
The name of the action.
Definition: gnc-plugin.h:231