|
GnuCash 2.4.99
|
00001 /* 00002 * gnc-plugin.c -- 00003 * 00004 * Copyright (C) 2003 Jan Arne Petersen <jpetersen@uni-bonn.de> 00005 * Copyright (C) 2003,2005 David Hampton <hampton@employees.org> 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License as 00009 * published by the Free Software Foundation; either version 2 of 00010 * the License, or (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, contact: 00019 * 00020 * Free Software Foundation Voice: +1-617-542-5942 00021 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 00022 * Boston, MA 02110-1301, USA gnu@gnu.org 00023 */ 00024 00035 #include "config.h" 00036 00037 #include <gtk/gtk.h> 00038 #include <glib/gi18n.h> 00039 00040 #include "gnc-plugin.h" 00041 #include "gnc-engine.h" 00042 #include "gnc-gconf-utils.h" 00043 #include "gnc-gnome-utils.h" 00044 #include "gnc-gobject-utils.h" 00045 00047 static QofLogModule log_module = GNC_MOD_GUI; 00049 static gpointer parent_class = NULL; 00050 00051 static void gnc_plugin_class_init (GncPluginClass *klass); 00052 static void gnc_plugin_init (GncPlugin *plugin_page, 00053 GncPluginClass *klass); 00054 static void gnc_plugin_finalize (GObject *object); 00055 00056 00059 typedef struct GncPluginPrivate 00060 { 00061 gpointer dummy; 00062 } GncPluginPrivate; 00063 00064 #define GNC_PLUGIN_GET_PRIVATE(o) \ 00065 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_PLUGIN, GncPluginPrivate)) 00066 00067 00070 GType 00071 gnc_plugin_get_type (void) 00072 { 00073 static GType gnc_plugin_type = 0; 00074 00075 if (gnc_plugin_type == 0) 00076 { 00077 static const GTypeInfo our_info = 00078 { 00079 sizeof (GncPluginClass), 00080 NULL, /* base_init */ 00081 NULL, /* base_finalize */ 00082 (GClassInitFunc) gnc_plugin_class_init, 00083 NULL, /* class_finalize */ 00084 NULL, /* class_data */ 00085 sizeof (GncPlugin), 00086 0, /* n_preallocs */ 00087 (GInstanceInitFunc) gnc_plugin_init, 00088 }; 00089 00090 gnc_plugin_type = g_type_register_static (G_TYPE_OBJECT, 00091 GNC_PLUGIN_NAME, 00092 &our_info, 0); 00093 } 00094 00095 return gnc_plugin_type; 00096 } 00097 00098 00106 static void 00107 gnc_plugin_class_init (GncPluginClass *klass) 00108 { 00109 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 00110 00111 parent_class = g_type_class_peek_parent (klass); 00112 gobject_class->finalize = gnc_plugin_finalize; 00113 00114 g_type_class_add_private(klass, sizeof(GncPluginPrivate)); 00115 } 00116 00117 00126 static void 00127 gnc_plugin_init (GncPlugin *plugin_page, GncPluginClass *klass) 00128 { 00129 gnc_gobject_tracking_remember(G_OBJECT(plugin_page), \ 00130 G_OBJECT_CLASS(klass)); 00131 } 00132 00133 00141 static void 00142 gnc_plugin_finalize (GObject *object) 00143 { 00144 GncPlugin *plugin; 00145 GncPluginPrivate *priv; 00146 00147 g_return_if_fail (GNC_IS_PLUGIN (object)); 00148 00149 plugin = GNC_PLUGIN (object); 00150 priv = GNC_PLUGIN_GET_PRIVATE (plugin); 00151 00152 gnc_gobject_tracking_forget(object); 00153 G_OBJECT_CLASS (parent_class)->finalize (object); 00154 } 00155 00156 00163 void 00164 gnc_plugin_add_to_window (GncPlugin *plugin, 00165 GncMainWindow *window, 00166 GQuark type) 00167 { 00168 GncPluginClass *class; 00169 GtkActionGroup *action_group; 00170 00171 g_return_if_fail (GNC_IS_PLUGIN (plugin)); 00172 class = GNC_PLUGIN_GET_CLASS (plugin); 00173 ENTER (": plugin %s(%p), window %p", gnc_plugin_get_name(plugin), 00174 plugin, window); 00175 00176 /* 00177 * Update window with additional UI items 00178 */ 00179 if (class->actions_name) 00180 { 00181 DEBUG ("%s: %d actions to merge with gui from %s", 00182 class->actions_name, (class->n_actions + class->n_toggle_actions), class->ui_filename); 00183 gnc_main_window_merge_actions (window, class->actions_name, 00184 class->actions, class->n_actions, 00185 class->toggle_actions, class->n_toggle_actions, 00186 class->ui_filename, plugin); 00187 00188 00189 if (class->important_actions) 00190 { 00191 action_group = 00192 gnc_main_window_get_action_group(window, class->actions_name); 00193 gnc_plugin_set_important_actions(action_group, 00194 class->important_actions); 00195 } 00196 } 00197 00198 /* 00199 * Setup gconf notifications if requested 00200 */ 00201 if (class->gconf_section && class->gconf_notifications) 00202 { 00203 DEBUG ("Requesting notification for section %s", class->gconf_section); 00204 gnc_gconf_add_notification(G_OBJECT(window), class->gconf_section, 00205 class->gconf_notifications, GNC_PLUGIN_NAME); 00206 } 00207 00208 /* 00209 * Do plugin specific actions. 00210 */ 00211 if (GNC_PLUGIN_GET_CLASS (plugin)->add_to_window) 00212 { 00213 DEBUG ("Calling child class function %p", GNC_PLUGIN_GET_CLASS (plugin)->add_to_window); 00214 GNC_PLUGIN_GET_CLASS (plugin)->add_to_window (plugin, window, type); 00215 } 00216 LEAVE (""); 00217 } 00218 00219 00220 /* Remove the specified plugin from the specified window. This 00221 * function will call the plugin to perform any plugin specific 00222 * actions, remove any gconf notifications that were set up for the 00223 * page, and remove the page's user interface from the window. 00224 * 00225 * See gnc-plugin.h for documentation on the function arguments. */ 00226 void 00227 gnc_plugin_remove_from_window (GncPlugin *plugin, 00228 GncMainWindow *window, 00229 GQuark type) 00230 { 00231 GncPluginClass *class; 00232 00233 g_return_if_fail (GNC_IS_PLUGIN (plugin)); 00234 class = GNC_PLUGIN_GET_CLASS (plugin); 00235 ENTER (": plugin %s(%p), window %p", gnc_plugin_get_name(plugin), 00236 plugin, window); 00237 00238 /* 00239 * Do plugin specific actions. 00240 */ 00241 if (GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window) 00242 { 00243 DEBUG ("Calling child class function %p", 00244 GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window); 00245 GNC_PLUGIN_GET_CLASS (plugin)->remove_from_window (plugin, window, type); 00246 } 00247 00248 /* 00249 * Remove any gconf notifications 00250 */ 00251 if (class->gconf_section && class->gconf_notifications) 00252 { 00253 DEBUG ("Remove notification for section %s", class->gconf_section); 00254 gnc_gconf_remove_notification (G_OBJECT(window), class->gconf_section, 00255 GNC_PLUGIN_NAME); 00256 } 00257 00258 /* 00259 * Update window to remove UI items 00260 */ 00261 if (class->actions_name) 00262 { 00263 DEBUG ("%s: %d actions to unmerge", 00264 class->actions_name, (class->n_actions + class->n_toggle_actions)); 00265 gnc_main_window_unmerge_actions (window, class->actions_name); 00266 } 00267 LEAVE (""); 00268 } 00269 00270 00273 const gchar * 00274 gnc_plugin_get_name (GncPlugin *plugin) 00275 { 00276 g_return_val_if_fail (GNC_IS_PLUGIN (plugin), NULL); 00277 return (GNC_PLUGIN_GET_CLASS(plugin)->plugin_name); 00278 } 00279 00280 00281 /************************************************************ 00282 * Utility Functions * 00283 ************************************************************/ 00284 00285 00290 void 00291 gnc_plugin_init_short_names (GtkActionGroup *action_group, 00292 action_toolbar_labels *toolbar_labels) 00293 { 00294 GtkAction *action; 00295 GValue value = { 0, }; 00296 gint i; 00297 00298 g_value_init (&value, G_TYPE_STRING); 00299 00300 for (i = 0; toolbar_labels[i].action_name; i++) 00301 { 00302 /* Add a couple of short labels for the toolbar */ 00303 action = gtk_action_group_get_action (action_group, 00304 toolbar_labels[i].action_name); 00305 g_value_set_static_string (&value, gettext(toolbar_labels[i].label)); 00306 g_object_set_property (G_OBJECT(action), "short_label", &value); 00307 } 00308 } 00309 00310 00316 void 00317 gnc_plugin_set_important_actions (GtkActionGroup *action_group, 00318 const gchar **name) 00319 { 00320 GtkAction *action; 00321 gint i; 00322 00323 for (i = 0; name[i]; i++) 00324 { 00325 action = gtk_action_group_get_action (action_group, name[i]); 00326 g_object_set (G_OBJECT(action), "is_important", TRUE, NULL); 00327 } 00328 00329 /* If this trips, you've got too many "important" actions. That 00330 * can't *all* be that important, can they? */ 00331 g_assert(i <= 3); 00332 } 00333 00334 00335 /* Update a property of existing UI actions. This function can 00336 * modify actions making them visible, invisible, sensitive, or 00337 * insensitive. 00338 * 00339 * See gnc-plugin.h for documentation on the function arguments. */ 00340 void 00341 gnc_plugin_update_actions (GtkActionGroup *action_group, 00342 const gchar **action_names, 00343 const gchar *property_name, 00344 gboolean value) 00345 { 00346 GtkAction *action; 00347 GValue gvalue = { 0 }; 00348 gint i; 00349 00350 g_value_init (&gvalue, G_TYPE_BOOLEAN); 00351 g_value_set_boolean (&gvalue, value); 00352 00353 for (i = 0; action_names[i]; i++) 00354 { 00355 action = gtk_action_group_get_action (action_group, action_names[i]); 00356 if (action) 00357 { 00358 g_object_set_property (G_OBJECT(action), property_name, &gvalue); 00359 } 00360 else 00361 { 00362 g_warning("No such action with name '%s' in action group %s (size %d)", 00363 action_names[i], gtk_action_group_get_name(action_group), 00364 g_list_length(gtk_action_group_list_actions(action_group))); 00365 } 00366 } 00367 } 00368 00369 00373 gint 00374 gnc_plugin_add_actions (GtkUIManager *ui_merge, 00375 GtkActionGroup *action_group, 00376 const gchar *filename) 00377 { 00378 GError *error = NULL; 00379 gchar *pathname; 00380 gint merge_id; 00381 00382 g_return_val_if_fail (ui_merge, 0); 00383 g_return_val_if_fail (action_group, 0); 00384 g_return_val_if_fail (filename, 0); 00385 00386 ENTER("ui_merge %p, action_group %p, filename %s", 00387 ui_merge, action_group, filename); 00388 gtk_ui_manager_insert_action_group (ui_merge, action_group, 0); 00389 00390 pathname = gnc_gnome_locate_ui_file (filename); 00391 if (pathname == NULL) 00392 { 00393 LEAVE("fail"); 00394 return 0; 00395 } 00396 00397 merge_id = gtk_ui_manager_add_ui_from_file (ui_merge, pathname, &error); 00398 DEBUG("merge_id is %d", merge_id); 00399 00400 g_assert(merge_id || error); 00401 if (merge_id) 00402 { 00403 gtk_ui_manager_ensure_update (ui_merge); 00404 } 00405 else 00406 { 00407 g_critical("Failed to load ui file.\n Filename %s\n Error %s", 00408 filename, error->message); 00409 g_error_free(error); 00410 } 00411 00412 g_free(pathname); 00413 LEAVE(" "); 00414 return merge_id; 00415 } 00416 00417 #if 0 00418 static void 00419 gnc_plugin_base_init (gpointer klass) 00420 { 00421 static gboolean initialized = FALSE; 00422 00423 if (!initialized) 00424 { 00425 initialized = TRUE; 00426 00427 signals[MERGE_ACTIONS] = g_signal_new ("merge-actions", 00428 G_OBJECT_CLASS_TYPE (klass), 00429 G_SIGNAL_RUN_FIRST, 00430 G_STRUCT_OFFSET (GncPluginClass, merge_actions), 00431 NULL, NULL, 00432 g_cclosure_marshal_VOID__POINTER, 00433 G_TYPE_NONE, 00434 1, 00435 GTK_TYPE_MENU_MERGE); 00436 signals[UNMERGE_ACTIONS] = g_signal_new ("unmerge-actions", 00437 G_OBJECT_CLASS_TYPE (klass), 00438 G_SIGNAL_RUN_FIRST, 00439 G_STRUCT_OFFSET (GncPluginClass, unmerge_actions), 00440 NULL, NULL, 00441 g_cclosure_marshal_VOID__POINTER, 00442 G_TYPE_NONE, 00443 1, 00444 GTK_TYPE_MENU_MERGE); 00445 } 00446 } 00447 #endif 00448
1.7.4