Track books referenced by each page. Add an event handler to close

pages when books they reference are deleted.


git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/branches/gnucash-gnome2-dev@9457 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
David Hampton
2003-10-11 01:10:20 +00:00
parent de6ad5530b
commit 368a25aba1
5 changed files with 216 additions and 28 deletions

View File

@@ -26,10 +26,7 @@
#include "config.h"
#include <gdk/gdkpixbuf.h>
#include <gtk/gtkwindow.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtkstatusbar.h>
#include <gtk/gtk.h>
#include "eggtoolbar.h"
#include "egg-action-group.h"
@@ -44,32 +41,24 @@
#include "dialog-scheduledxaction.h"
#include "dialog-sxsincelast.h"
#include "dialog-transfer.h"
#include "dialog-utils.h"
#include "druid-loan.h"
#include "gnc-engine.h"
#include "gnc-component-manager.h"
#include "gnc-engine-util.h"
#include "gnc-gnome-utils.h"
#include "gnc-dir.h"
#include "gnc-file.h"
#include "gnc-gui-query.h"
#include "gnc-plugin.h"
#include "gnc-plugin-manager.h"
#include "gnc-split-reg.h"
#include "gnc-session.h"
#include "gnc-totd-dialog.h"
#include "gnc-ui.h"
#include "gnc-version.h"
#include "mainwindow-account-tree.h"
#include "window-acct-tree.h"
#include "window-main.h"
#include "window-reconcile.h"
#include "window-register.h"
#include "window-report.h"
#include "messages.h"
/** Static Globals *******************************************************/
static short module = MOD_GUI;
static GList *active_windows = NULL;
static GList *installed_pages = NULL;
/** Declarations *********************************************************/
static void gnc_main_window_class_init (GncMainWindowClass *klass);
@@ -124,10 +113,13 @@ struct GncMainWindowPrivate
GtkWidget *toolbar_dock;
GtkWidget *notebook;
GtkWidget *statusbar;
GtkWidget *progressbar;
EggActionGroup *action_group;
GncPluginPage *current_page;
GList *installed_pages;
gint event_handler_id;
GHashTable *merged_actions_table;
};
@@ -261,6 +253,85 @@ static GObjectClass *parent_class = NULL;
static GQuark window_type = 0;
/************************************************************
* *
************************************************************/
/** Look through the list of pages installed in this window and see if
* the specified page is there.
*
* @param page The page to search for.
*
* @return TRUE if the page is present in the window, FALSE otherwise.
*/
static gboolean
gnc_main_window_page_exists (GncPluginPage *page)
{
GncMainWindow *window;
GList *walker;
for (walker = active_windows; walker; walker = g_list_next(walker)) {
window = walker->data;
if (g_list_find(window->priv->installed_pages, page)) {
return TRUE;
}
}
return FALSE;
}
/** This function handles any event notifications from the engine.
* The only event it currently cares about is the deletion of a book.
* When a book is deleted, it runs through all installed pages
* looking for pages that reference the just (about to be?) deleted
* book. It closes any page it finds so there are no dangling
* references to the book.
*
* @param entity The guid the item being added, deleted, etc.
*
* @param type The type of the item being added, deleted, etc. This
* function only cares about a type of GNC_ID_BOOK.
*
* @param event_type The type of the event. This function only cares
* about an event type of GNC_EVENT_DESTROY.
*
* @param user_data A pointer to the window data structure.
*/
static void
gnc_main_window_event_handler (GUID *entity, QofIdType type,
GNCEngineEventType event_type,
gpointer user_data)
{
GncMainWindow *window;
GncPluginPage *page;
GList *item, *next;
/* hard failures */
g_return_if_fail(GNC_IS_MAIN_WINDOW(user_data));
/* soft failures */
if (safe_strcmp(type, GNC_ID_BOOK) != 0)
return;
if (event_type != GNC_EVENT_DESTROY)
return;
ENTER("entity %p of type %s, event %d, window %p",
entity, type, event_type, user_data);
window = GNC_MAIN_WINDOW(user_data);
for (item = window->priv->installed_pages; item; item = next) {
next = g_list_next(item);
page = GNC_PLUGIN_PAGE(item->data);
if (!gnc_plugin_page_has_book (page, entity))
continue;
gnc_main_window_close_page (window, page);
}
LEAVE(" ");
}
/************************************************************
* *
************************************************************/
GType
gnc_main_window_get_type (void)
{
@@ -306,15 +377,14 @@ gnc_main_window_open_page (GncMainWindow *window,
const gchar *icon;
GtkWidget *image;
GtkNotebook *notebook;
GList *item;
gint page_num;
if (window)
g_return_if_fail (GNC_IS_MAIN_WINDOW (window));
g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
g_return_if_fail (gnc_plugin_page_has_books(page));
item = g_list_find (installed_pages, page);
if (item) {
if (gnc_main_window_page_exists(page)) {
window = GNC_MAIN_WINDOW (page->window);
notebook = GTK_NOTEBOOK (window->priv->notebook);
page_num = gtk_notebook_page_num(notebook, page->notebook_page);
@@ -351,7 +421,8 @@ gnc_main_window_open_page (GncMainWindow *window,
gnc_plugin_page_inserted (page);
gtk_notebook_set_current_page (notebook, -1);
installed_pages = g_list_append (installed_pages, page);
window->priv->installed_pages =
g_list_append (window->priv->installed_pages, page);
}
void
@@ -361,8 +432,6 @@ gnc_main_window_close_page (GncMainWindow *window,
GtkNotebook *notebook;
gint page_num;
installed_pages = g_list_remove (installed_pages, page);
if (!page->notebook_page)
return;
@@ -376,7 +445,8 @@ gnc_main_window_close_page (GncMainWindow *window,
notebook = GTK_NOTEBOOK (window->priv->notebook);
page_num = gtk_notebook_page_num(notebook, page->notebook_page);
gtk_notebook_remove_page (notebook, page_num);
installed_pages = g_list_remove (installed_pages, page);
window->priv->installed_pages =
g_list_remove (window->priv->installed_pages, page);
gnc_plugin_page_removed (page);
@@ -497,6 +567,10 @@ gnc_main_window_init (GncMainWindow *window)
window->priv->merged_actions_table =
g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
window->priv->event_handler_id =
gnc_engine_register_event_handler(gnc_main_window_event_handler,
window);
gnc_main_window_setup_window (window);
}
@@ -513,6 +587,7 @@ gnc_main_window_finalize (GObject *object)
g_return_if_fail (window->priv != NULL);
gnc_engine_unregister_event_handler(window->priv->event_handler_id);
g_hash_table_destroy (window->priv->merged_actions_table);
g_free (window->priv);

View File

@@ -24,9 +24,7 @@
#include "config.h"
#include <gtk/gtkcellrenderertext.h>
#include <gtk/gtktreeview.h>
#include <gtk/gtkvbox.h>
#include <gtk/gtk.h>
#include "egg-action-group.h"
#include "gnc-plugin-page-account-tree.h"
@@ -317,6 +315,9 @@ gnc_plugin_page_account_tree_init (GncPluginPageAccountTree *plugin_page)
parent->tab_name = g_strdup(_("Accounts"));
parent->uri = g_strdup("default:");
/* change me when the system supports multiple books */
gnc_plugin_page_add_book(parent, gnc_get_current_book());
/* Create menu and toolbar information */
action_group = egg_action_group_new ("GncPluginPageAccountTreeActions");
priv->action_group = action_group;
@@ -403,7 +404,7 @@ gnc_plugin_page_account_tree_finalize (GObject *object)
gnc_options_dialog_destroy(priv->editor_dialog);
priv->editor_dialog = NULL;
}
gnc_option_db_destroy(priv->odb);
free_tree = scm_c_eval_string("gnc:free-acct-tree-window");

View File

@@ -38,11 +38,13 @@
#include "egg-action-group.h"
#include "egg-radio-action.h"
#include "global-options.h"
#include "gnc-book.h"
#include "gnc-date.h"
#include "gnc-date-edit.h"
#include "gnc-gnome-utils.h"
#include "gnc-icons.h"
#include "gnc-split-reg.h"
#include "gnc-ui-util.h"
#include "lot-viewer.h"
#include "QueryNew.h"
#include "window-reconcile.h"
@@ -336,7 +338,8 @@ gnc_plugin_page_register_new_common (GNCLedgerDisplay *ledger)
GncPluginPageRegister *register_page;
GncPluginPage *plugin_page;
GNCSplitReg *gsr;
GList *item;
GList *item, *book_list;
QofQuery *q;
/* Is there an existing page? */
gsr = gnc_ledger_display_get_user_data (ledger);
@@ -355,6 +358,12 @@ gnc_plugin_page_register_new_common (GNCLedgerDisplay *ledger)
plugin_page->title = gnc_plugin_page_register_get_tab_name(plugin_page);
plugin_page->tab_name = gnc_plugin_page_register_get_tab_name(plugin_page);
q = gnc_ledger_display_get_query (ledger);
book_list = qof_query_get_books (q);
for (item = book_list; item; item = g_list_next(item))
gnc_plugin_page_add_book (plugin_page, (QofBook *)item->data);
// Do not free the list. It is owned by the query.
active_pages = g_list_append (active_pages, plugin_page);
return plugin_page;
@@ -1441,6 +1450,10 @@ gnc_plugin_page_register_cmd_schedule (EggAction *action,
LEAVE(" ");
}
/************************************************************/
/* Auxiliary functions */
/************************************************************/
void
gnc_plugin_page_register_set_options (GncPluginPage *plugin_page,
const char *lines_opt_page,

View File

@@ -42,6 +42,11 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
struct GncPluginPagePrivate
{
GList *books;
};
GType
gnc_plugin_page_get_type (void)
{
@@ -220,6 +225,10 @@ gnc_plugin_page_class_init (GncPluginPageClass *klass)
static void
gnc_plugin_page_init (GncPluginPage *plugin_page)
{
GncPluginPagePrivate *priv;
priv = plugin_page->priv = g_new0 (GncPluginPagePrivate, 1);
plugin_page->title = NULL;
plugin_page->tab_name = NULL;
plugin_page->uri = NULL;
@@ -230,8 +239,11 @@ gnc_plugin_page_init (GncPluginPage *plugin_page)
static void
gnc_plugin_page_finalize (GObject *object)
{
GncPluginPage *page = GNC_PLUGIN_PAGE (object);
GncPluginPagePrivate *priv;
GncPluginPage *page;
GList *item;
page = GNC_PLUGIN_PAGE (object);
if (page->title)
g_free(page->title);
if (page->tab_name)
@@ -239,7 +251,60 @@ gnc_plugin_page_finalize (GObject *object)
if (page->uri)
g_free(page->uri);
priv = page->priv;
if (priv->books) {
for (item = priv->books; item; item = g_list_next(item)) {
guid_free (item->data);
}
g_list_free(priv->books);
priv->books = NULL;
}
g_free (priv);
page->priv = NULL;
page->window = NULL; // Don't need to free it.
G_OBJECT_CLASS (parent_class)->finalize (object);
}
void
gnc_plugin_page_add_book (GncPluginPage *page, QofBook *book)
{
GncPluginPagePrivate *priv;
GUID *guid;
g_return_if_fail (GNC_IS_PLUGIN_PAGE (page));
g_return_if_fail (book != NULL);
priv = page->priv;
guid = guid_malloc();
*guid = *qof_book_get_guid(book);
priv->books = g_list_append(priv->books, guid);
}
gboolean
gnc_plugin_page_has_book (GncPluginPage *page, GUID *entity)
{
GncPluginPagePrivate *priv;
GList *item;
g_return_val_if_fail (GNC_IS_PLUGIN_PAGE (page), FALSE);
g_return_val_if_fail (entity != NULL, FALSE);
priv = page->priv;
for (item = priv->books; item; item = g_list_next(item)) {
if (guid_equal((GUID*)item->data, entity)) {
return TRUE;
}
}
return FALSE;
}
gboolean
gnc_plugin_page_has_books (GncPluginPage *page)
{
g_return_val_if_fail (GNC_IS_PLUGIN_PAGE (page), FALSE);
return (page->priv->books != NULL);
}

View File

@@ -26,8 +26,9 @@
#ifndef __GNC_PLUGIN_PAGE_H
#define __GNC_PLUGIN_PAGE_H
#include <gdk/gdkpixbuf.h>
#include "egg-menu-merge.h"
#include "guid.h"
#include "qofbook.h"
G_BEGIN_DECLS
@@ -40,8 +41,11 @@ G_BEGIN_DECLS
#define GNC_PLUGIN_PAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GNC_PLUGIN_PAGE, GncPluginPageClass))
/* typedefs & structures */
typedef struct GncPluginPagePrivate GncPluginPagePrivate;
typedef struct GncPluginPage {
GObject parent;
GncPluginPagePrivate *priv;
GtkWidget *window;
GtkWidget *notebook_page;
@@ -82,6 +86,36 @@ void gnc_plugin_page_merge_actions (GncPluginPage *plugin_pag
void gnc_plugin_page_unmerge_actions (GncPluginPage *plugin_page,
EggMenuMerge *merge);
/** Add a book reference to the specified page.
*
* @param page The page to be modified.
*
* @param book The book referenced by this page.
*/
void gnc_plugin_page_add_book (GncPluginPage *page, QofBook *book);
/** Query a page to see if it has a reference to a given book. This
* function takes a guid instead of a QofBook because that's what the
* engine event mechanism provides.
*
* @param page The page to query.
*
* @param book The guid of the book in question.
*
* @return TRUE if the page refers to the specified book. FALSE
* otherwise.
*/
gboolean gnc_plugin_page_has_book (GncPluginPage *page, GUID *book);
/** Query a page to see if it has a reference to any book.
*
* @param page The page to query.
*
* @return TRUE if the page references any books. FALSE otherwise.
*/
gboolean gnc_plugin_page_has_books (GncPluginPage *page);
/* Signals */
void gnc_plugin_page_inserted (GncPluginPage *plugin_page);
void gnc_plugin_page_removed (GncPluginPage *plugin_page);