[Gnucash-changes] New files for installing the report menu items into the main window(s).

David Hampton hampton at cvs.gnucash.org
Sun Jun 5 03:23:58 EDT 2005


Log Message:
-----------
New files for installing the report menu items into the main window(s).

Tags:
----
gnucash-gnome2-dev

Modified Files:
--------------
    gnucash/src/gnome:
        Makefile.am
        top-level.c

Added Files:
-----------
    gnucash/src/gnome:
        gnc-plugin-menu-additions.c
        gnc-plugin-menu-additions.h

Revision Data
-------------
--- /dev/null
+++ src/gnome/gnc-plugin-menu-additions.h
@@ -0,0 +1,85 @@
+/* 
+ * gnc-plugin-menu-additions.h -- 
+ * Copyright (C) 2005 David Hampton <hampton at employees.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org
+ */
+
+/** @addtogroup GUI
+    @{ */
+/** @addtogroup GuiImport Import GUI Utility functions.
+    @{ */
+/** @file gnc-plugin-menu-additions.h
+    @brief Utility functions for writing import modules.
+    @author Copyright (C) 2002 David Hampton <hampton at employees.org>
+*/
+
+#ifndef __GNC_PLUGIN_MENU_ADDITIONS_H
+#define __GNC_PLUGIN_MENU_ADDITIONS_H
+
+#include <gtk/gtk.h>
+#include "gnc-plugin.h"
+
+G_BEGIN_DECLS
+
+/* type macros */
+#define GNC_TYPE_PLUGIN_MENU_ADDITIONS            (gnc_plugin_menu_additions_get_type ())
+#define GNC_PLUGIN_MENU_ADDITIONS(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNC_TYPE_PLUGIN_MENU_ADDITIONS, GncPluginMenuAdditions))
+#define GNC_PLUGIN_MENU_ADDITIONS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GNC_TYPE_PLUGIN_MENU_ADDITIONS, GncPluginMenuAdditionsClass))
+#define GNC_IS_PLUGIN_MENU_ADDITIONS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GNC_TYPE_PLUGIN_MENU_ADDITIONS))
+#define GNC_IS_PLUGIN_MENU_ADDITIONS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GNC_TYPE_PLUGIN_MENU_ADDITIONS))
+#define GNC_PLUGIN_MENU_ADDITIONS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_TYPE_PLUGIN_MENU_ADDITIONS, GncPluginMenuAdditionsClass))
+
+#define GNC_PLUGIN_MENU_ADDITIONS_NAME "gnc-plugin-menu-additions"
+#define GNC_PLUGIN_HIDE_MENU_ADDITIONS_NAME "gnc-plugin-hide-menu-additions"
+
+/* typedefs & structures */
+typedef struct GncPluginMenuAdditionsPrivate GncPluginMenuAdditionsPrivate;
+
+typedef struct {
+	GncPlugin parent;
+	GncPluginMenuAdditionsPrivate *priv;
+} GncPluginMenuAdditions;
+
+typedef struct {
+	GncPluginClass parent;
+} GncPluginMenuAdditionsClass;
+
+/* function prototypes */
+
+
+/** Get the type of an extensions plugin.
+ *
+ *  @return A GType.
+ */
+GType gnc_plugin_menu_additions_get_type (void);
+
+
+/** Create a new menu_additions plugin.  This plugin attaches the menu
+ *  items from Scheme code to any window that is opened.
+ *
+ *  @return A pointer to the new object.
+ */
+GncPlugin *gnc_plugin_menu_additions_new (void);
+
+G_END_DECLS
+
+#endif /* __GNC_PLUGIN_MENU_ADDITIONS_H */
+
+/** @} */
+/** @} */
Index: Makefile.am
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/Makefile.am,v
retrieving revision 1.107.4.21
retrieving revision 1.107.4.22
diff -Lsrc/gnome/Makefile.am -Lsrc/gnome/Makefile.am -u -r1.107.4.21 -r1.107.4.22
--- src/gnome/Makefile.am
+++ src/gnome/Makefile.am
@@ -52,6 +52,7 @@
   gnc-main-window.c \
   gnc-plugin.c \
   gnc-plugin-file-history.c \
+  gnc-plugin-menu-additions.c \
   gnc-plugin-account-tree.c \
   gnc-plugin-register.c \
   gnc-plugin-manager.c \
@@ -101,6 +102,7 @@
   gnc-plugin.h \
   gnc-plugin-account-tree.h \
   gnc-plugin-file-history.h \
+  gnc-plugin-menu-additions.h \
   gnc-plugin-register.h \
   gnc-plugin-manager.h \
   gnc-plugin-page.h \
Index: top-level.c
===================================================================
RCS file: /home/cvs/cvsroot/gnucash/src/gnome/top-level.c,v
retrieving revision 1.140.4.17
retrieving revision 1.140.4.18
diff -Lsrc/gnome/top-level.c -Lsrc/gnome/top-level.c -u -r1.140.4.17 -r1.140.4.18
--- src/gnome/top-level.c
+++ src/gnome/top-level.c
@@ -47,6 +47,7 @@
 #include "gnc-file.h"
 #include "gnc-main-window.h"
 #include "gnc-menu-extensions.h"
+#include "gnc-plugin-menu-additions.h" /* FIXME Remove this line*/
 #include "gnc-plugin-account-tree.h" /* FIXME Remove this line*/
 #include "gnc-plugin-file-history.h" /* FIXME Remove this line*/
 #include "gnc-plugin-register.h" /* FIXME Remove this line*/
@@ -390,6 +391,7 @@
     /* FIXME Remove this test code */
     gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_account_tree_new ());
     gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_file_history_new ());
+    gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_menu_additions_new ());
     gnc_plugin_manager_add_plugin (gnc_plugin_manager_get (), gnc_plugin_register_new ());
     gnc_load_stock_icons ();
 
--- /dev/null
+++ src/gnome/gnc-plugin-menu-additions.c
@@ -0,0 +1,396 @@
+/* 
+ * gnc-plugin-menu-additions.c -- 
+ * Copyright (C) 2005 David Hampton hampton at employees.org>
+ *
+ * From:
+ * gnc-menu-extensions.c -- functions to build dynamic menus
+ * Copyright (C) 1999 Rob Browning
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, contact:
+ *
+ * Free Software Foundation           Voice:  +1-617-542-5942
+ * 59 Temple Place - Suite 330        Fax:    +1-617-542-2652
+ * Boston, MA  02111-1307,  USA       gnu at gnu.org
+ */
+
+/** @addtogroup GUI
+    @{ */
+/** @addtogroup GuiImport Import GUI Utility functions.
+    @{ */
+/** @internal
+    @file gnc-plugin-menu-additions.c
+    @brief Utility functions for writing import modules.
+    @author Copyright (C) 2002 David Hampton <hampton at employees.org>
+*/
+
+#include "config.h"
+
+#include <string.h>
+#include <glib/gprintf.h>
+#include <libgnome/libgnome.h>
+#include <g-wrap-wct.h>
+
+#include "guile-util.h"
+#include "gnc-engine-util.h"
+#include "gnc-main-window.h"
+#include "gnc-plugin-menu-additions.h"
+#include "gnc-window.h"
+#include "gnc-trace.h"
+#include "messages.h"
+#include "gnc-gconf-utils.h"
+#include "gnc-ui.h"
+#include "gnc-menu-extensions.h"
+
+static GList *active_plugins = NULL;
+static GObjectClass *parent_class = NULL;
+
+static void gnc_plugin_menu_additions_class_init (GncPluginMenuAdditionsClass *klass);
+static void gnc_plugin_menu_additions_init (GncPluginMenuAdditions *plugin);
+static void gnc_plugin_menu_additions_finalize (GObject *object);
+
+static void gnc_plugin_menu_additions_add_to_window (GncPlugin *plugin, GncMainWindow *window, GQuark type);
+static void gnc_plugin_menu_additions_remove_from_window (GncPlugin *plugin, GncMainWindow *window, GQuark type);
+
+/* Callbacks on other objects */
+static void gnc_plugin_menu_additions_main_window_page_changed (GncMainWindow *window,
+								GncPluginPage *page);
+
+/* Command callbacks */
+
+/* This static indicates the debugging module that this .o belongs to.  */
+static short module = MOD_GUI;
+
+
+#define PLUGIN_ACTIONS_NAME "gnc-plugin-menu-additions-actions"
+
+struct GncPluginMenuAdditionsPrivate
+{
+  gpointer dummy;
+};
+
+typedef struct _GncPluginMenuAdditionsPerWindow
+{
+  GncMainWindow  *window;
+  GtkUIManager   *ui_manager;
+  GtkActionGroup *group;
+  gint merge_id;
+} GncPluginMenuAdditionsPerWindow;
+
+/************************************************************
+ *                  Object Implementation                   *
+ ************************************************************/
+
+GType
+gnc_plugin_menu_additions_get_type (void)
+{
+  static GType gnc_plugin_menu_additions_type = 0;
+
+  if (gnc_plugin_menu_additions_type == 0) {
+    static const GTypeInfo our_info = {
+      sizeof (GncPluginMenuAdditionsClass),
+      NULL,		/* base_init */
+      NULL,		/* base_finalize */
+      (GClassInitFunc) gnc_plugin_menu_additions_class_init,
+      NULL,		/* class_finalize */
+      NULL,		/* class_data */
+      sizeof (GncPluginMenuAdditions),
+      0,
+      (GInstanceInitFunc) gnc_plugin_menu_additions_init
+    };
+
+    gnc_plugin_menu_additions_type = g_type_register_static (GNC_TYPE_PLUGIN,
+							 "GncPluginMenuAdditions",
+							 &our_info, 0);
+  }
+
+  return gnc_plugin_menu_additions_type;
+}
+
+#if DEBUG_REFERENCE_COUNTING
+static void
+dump_model (GncPluginMenuAdditions *plugin, gpointer dummy)
+{
+  g_warning("GncPluginMenuAdditions %p still exists.", plugin);
+}
+
+static gint
+gnc_plugin_menu_additions_report_references (void)
+{
+  g_list_foreach(active_plugins, (GFunc)dump_model, NULL);
+  return 0;
+}
+#endif
+
+static void
+gnc_plugin_menu_additions_class_init (GncPluginMenuAdditionsClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GncPluginClass *plugin_class = GNC_PLUGIN_CLASS (klass);
+
+  parent_class = g_type_class_peek_parent (klass);
+
+  object_class->finalize = gnc_plugin_menu_additions_finalize;
+
+  /* plugin info */
+  plugin_class->plugin_name   = GNC_PLUGIN_MENU_ADDITIONS_NAME;
+
+  /* function overrides */
+  plugin_class->add_to_window = gnc_plugin_menu_additions_add_to_window;
+  plugin_class->remove_from_window = gnc_plugin_menu_additions_remove_from_window;
+
+#if DEBUG_REFERENCE_COUNTING
+  gtk_quit_add (0,
+		(GtkFunction)gnc_plugin_menu_additions_report_references,
+		NULL);
+#endif
+}
+
+static void
+gnc_plugin_menu_additions_init (GncPluginMenuAdditions *plugin)
+{
+  ENTER("plugin %p", plugin);
+  plugin->priv = g_new0 (GncPluginMenuAdditionsPrivate, 1);
+
+  active_plugins = g_list_append (active_plugins, plugin);
+  LEAVE("");
+}
+
+static void
+gnc_plugin_menu_additions_finalize (GObject *object)
+{
+  GncPluginMenuAdditions *plugin;
+
+  g_return_if_fail (GNC_IS_PLUGIN_MENU_ADDITIONS (object));
+
+  plugin = GNC_PLUGIN_MENU_ADDITIONS (object);
+  ENTER("plugin %p", plugin);
+  active_plugins = g_list_remove (active_plugins, plugin);
+
+  g_return_if_fail (plugin->priv != NULL);
+  g_free (plugin->priv);
+
+  G_OBJECT_CLASS (parent_class)->finalize (object);
+  LEAVE("");
+}
+
+GncPlugin *
+gnc_plugin_menu_additions_new (void)
+{
+  GncPlugin *plugin_page = NULL;
+
+  ENTER("");
+  plugin_page = GNC_PLUGIN (g_object_new (GNC_TYPE_PLUGIN_MENU_ADDITIONS, NULL));
+  LEAVE("plugin %p", plugin_page);
+  return plugin_page;
+}
+
+/************************************************************
+ *              Plugin Function Implementation              *
+ ************************************************************/
+
+static SCM
+gnc_main_window_to_scm (GncMainWindow *window)
+{
+  static SCM main_window_type = SCM_UNDEFINED;
+
+  if (!window)
+    return SCM_BOOL_F;
+
+  if (main_window_type == SCM_UNDEFINED)
+  {
+    main_window_type = scm_c_eval_string ("<gnc:MainWindow*>");
+
+    /* don't really need this - types are bound globally anyway. */
+    if (main_window_type != SCM_UNDEFINED)
+      scm_gc_protect_object (main_window_type);
+  }
+  
+  return gw_wcp_assimilate_ptr ((void *)window, main_window_type);
+}
+
+/** The user has selected one of the items in the File History menu.
+ *  Close down the current session and start up a new one with the
+ *  requested file.
+ *
+ *  @param action A pointer to the action selected by the user.  This
+ *  action represents one of the items in the file history menu.
+ *
+ *  @param data A pointer to the gnc-main-window data to be used by
+ *  this function.  This is mainly to find out which window it was
+ *  that had a menu selected.  That's not really important for this
+ *  function and we're about to close all the windows anyway.
+ */
+static void
+gnc_plugin_menu_additions_action_cb (GtkAction *action,
+				     GncMainWindowActionData *data)
+{
+
+  g_return_if_fail(GTK_IS_ACTION(action));
+  g_return_if_fail(data != NULL);
+
+  gnc_extension_invoke_cb(data->data, gnc_main_window_to_scm(data->window));
+}
+
+static void
+gnc_menu_additions_menu_setup_one (ExtensionInfo *ext_info,
+				   GncPluginMenuAdditionsPerWindow *per_window)
+{
+  GncMainWindowActionData *cb_data;
+
+  DEBUG( "Adding %s/%s [%s] as [%s]\n", ext_info->path, ext_info->ae.label,
+	 ext_info->ae.name, ext_info->typeStr );
+
+  cb_data = g_new0 (GncMainWindowActionData, 1);
+  cb_data->window = per_window->window;
+  cb_data->data = ext_info->extension;
+
+  if (ext_info->type == GTK_UI_MANAGER_MENUITEM)
+    ext_info->ae.callback = (GCallback)gnc_plugin_menu_additions_action_cb;
+
+  gtk_action_group_add_actions_full(per_window->group, &ext_info->ae, 1,
+				    cb_data, g_free);
+  gtk_ui_manager_add_ui(per_window->ui_manager, per_window->merge_id,
+			ext_info->path, ext_info->ae.label, ext_info->ae.name,
+			ext_info->type, FALSE);
+  gtk_ui_manager_ensure_update(per_window->ui_manager);
+}
+
+/** Initialize the file history menu for a window.  This function is
+ *  called as part of the initialization of a window, after all the
+ *  plugin menu items have been added to the menu structure.  Its job
+ *  is to correctly initialize the file history menu.  It does this by
+ *  first calling a function that initializes the menu to the current
+ *  as maintained in gconf.  It then creates a gconf client that will
+ *  listens for any changes to the file history menu, and will update
+ *  the meny when they are signalled.
+ *
+ *  @param plugin A pointer to the gnc-plugin object responsible for
+ *  adding/removing the file history menu.
+ *
+ *  @param window A pointer the gnc-main-window that is being initialized.
+ *
+ *  @param type Unused
+ */
+static void
+gnc_plugin_menu_additions_add_to_window (GncPlugin *plugin,
+					 GncMainWindow *window,
+					 GQuark type)
+{
+  GncPluginMenuAdditionsPerWindow per_window;
+  GSList *menu_list;
+
+  ENTER(" ");
+
+  g_signal_connect (G_OBJECT(window), "page_changed",
+		    G_CALLBACK (gnc_plugin_menu_additions_main_window_page_changed),
+		    plugin);
+
+  per_window.window = window;
+  per_window.ui_manager = window->ui_merge;
+  per_window.group = gtk_action_group_new ("MenuAdditions" );
+  per_window.merge_id = gtk_ui_manager_new_merge_id(window->ui_merge);
+  gtk_ui_manager_insert_action_group(window->ui_merge, per_window.group, 0);
+
+  menu_list = gnc_extensions_get_menu_list();
+  g_slist_foreach(menu_list, (GFunc)gnc_menu_additions_menu_setup_one,
+		  &per_window);
+
+  /* Tell the window code about the actions that were just added
+   * behind its back (so to speak) */
+  gnc_main_window_manual_merge_actions (window, PLUGIN_ACTIONS_NAME,
+					per_window.group, per_window.merge_id);
+
+  LEAVE(" ");
+}
+
+
+/** Finalize the file history menu for this window.  This function is
+ *  called as part of the destruction of a window.
+ *
+ *  @param plugin A pointer to the gnc-plugin object responsible for
+ *  adding/removing the file history menu.  It stops the gconf
+ *  notifications for this window, and destroys the gconf client
+ *  object.
+ *
+ *  @param window A pointer the gnc-main-window that is being destroyed.
+ *
+ *  @param type Unused
+ */
+static void
+gnc_plugin_menu_additions_remove_from_window (GncPlugin *plugin,
+					      GncMainWindow *window,
+					      GQuark type)
+{
+  GtkActionGroup *group;
+
+  ENTER(" ");
+
+  g_signal_handlers_disconnect_by_func(G_OBJECT(window),
+				       G_CALLBACK (gnc_plugin_menu_additions_main_window_page_changed),
+				       plugin);
+
+  /* Have to remove our actions manually. Its only automatic if the
+   * actions name is installed into the plugin class. */
+  group = gnc_main_window_get_action_group(window, PLUGIN_ACTIONS_NAME);
+  if (group)
+    gtk_ui_manager_remove_action_group(window->ui_merge, group);
+
+  LEAVE(" ");
+}
+
+/************************************************************
+ *                     Object Callbacks                     *
+ ************************************************************/
+
+static void
+our_gtk_action_set_visible(GtkAction *action, gboolean visible)
+{
+  g_object_set(G_OBJECT(action), "visible", visible, NULL);
+}
+
+
+/** Whenever the current page has changed, update the reports menus based
+ *  upon the page that is currently selected. */
+static void
+gnc_plugin_menu_additions_main_window_page_changed (GncMainWindow *window,
+						    GncPluginPage *page)
+{
+  GtkActionGroup *action_group;
+  GList *action_list;
+  gboolean visible;
+  gpointer tmp;
+
+  ENTER("main window %p, page %p", window, page);
+  action_group = gnc_main_window_get_action_group(window,PLUGIN_ACTIONS_NAME);
+  if (action_group == NULL) {
+    LEAVE("Can't find action group");
+    return;
+  }
+
+  /* Does the now-visible page want menu-extensions to be visible? */
+  if (page) {
+    tmp = g_object_get_data(G_OBJECT(page),GNC_PLUGIN_HIDE_MENU_ADDITIONS_NAME);
+    visible = !GPOINTER_TO_INT(tmp);
+  } else {
+    visible = TRUE;
+  }
+
+  action_list = gtk_action_group_list_actions(action_group);
+  // Use the following line for gtk2.6
+  // g_list_foreach(action_list, (GFunc)gtk_action_set_visible, (gpointer)visible);
+  g_list_foreach(action_list, (GFunc)our_gtk_action_set_visible, (gpointer)visible);
+  g_list_free(action_list);
+
+  LEAVE(" ");
+}


More information about the gnucash-changes mailing list