mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
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:
@@ -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);
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user