Follow up to previous commit 94cb965

This commit moves the setting up of the page changed signal callback to
when the plugin page is inserted and also records the id used. This is
used to disconnect this callback when the page is moved to a different
window and also when the page is destroyed.
This commit is contained in:
Robert Fewell 2020-02-05 14:41:01 +00:00
parent 58ddb47f56
commit f66b7ed275
13 changed files with 303 additions and 267 deletions

View File

@ -2795,6 +2795,9 @@ gnc_main_window_disconnect (GncMainWindow *window,
g_signal_handlers_disconnect_by_func(G_OBJECT(page->notebook_page),
G_CALLBACK(gnc_main_window_button_press_cb), page);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(page));
/* Disconnect the page and summarybar from the window */
priv = GNC_MAIN_WINDOW_GET_PRIVATE(window);
if (priv->current_page == page)
@ -3712,7 +3715,7 @@ gnc_quartz_shutdown (GtkosxApplication *theApp, gpointer data)
/* Do Nothing. It's too late. */
}
/* Should quit responds to NSApplicationBlockTermination; returning
* TRUE means "don't terminate", FALSE means "do terminate".
* TRUE means "don't terminate", FALSE means "do terminate".
*/
static gboolean
gnc_quartz_should_quit (GtkosxApplication *theApp, GncMainWindow *window)
@ -4325,6 +4328,9 @@ gnc_main_window_cmd_window_move_page (GtkAction *action, GncMainWindow *window)
tab_widget = gtk_notebook_get_tab_label (notebook, page->notebook_page);
menu_widget = gtk_notebook_get_menu_label (notebook, page->notebook_page);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(page));
/* Ref the page components, then remove it from its old window */
g_object_ref(page);
g_object_ref(tab_widget);

View File

@ -58,6 +58,9 @@ static void gnc_plugin_page_get_property (GObject *object,
GValue *value,
GParamSpec *pspec);
static void gnc_plugin_page_default_focus (GncPluginPage *plugin_page,
gboolean on_current_page);
enum
{
INSERTED,
@ -102,6 +105,9 @@ typedef struct _GncPluginPagePrivate
gchar *page_color;
gchar *uri;
gchar *statusbar_text;
gulong page_changed_id;
} GncPluginPagePrivate;
GNC_DEFINE_TYPE_WITH_CODE(GncPluginPage, gnc_plugin_page, G_TYPE_OBJECT,
@ -371,6 +377,7 @@ gnc_plugin_page_class_init (GncPluginPageClass *klass)
klass->tab_icon = NULL;
klass->plugin_name = NULL;
klass->focus_page = gnc_plugin_page_default_focus;
g_object_class_install_property
(gobject_class,
@ -506,18 +513,19 @@ static void
gnc_plugin_page_init (GncPluginPage *page, void *data)
{
GncPluginPagePrivate *priv;
GncPluginPageClass *klass = (GncPluginPageClass*)data;
priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
priv->page_name = NULL;
priv->page_color = NULL;
priv->uri = NULL;
priv->page_changed_id = 0;
page->window = NULL;
page->summarybar = NULL;
gnc_gobject_tracking_remember(G_OBJECT(page),
gnc_gobject_tracking_remember(G_OBJECT(page),
G_OBJECT_CLASS(klass));
}
@ -848,6 +856,96 @@ gnc_plugin_page_set_page_color (GncPluginPage *page, const gchar *color)
}
static void
gnc_plugin_page_default_focus (GncPluginPage *plugin_page,
gboolean on_current_page)
{
GncPluginPagePrivate *priv;
if (!on_current_page)
return;
g_return_if_fail (GNC_IS_PLUGIN_PAGE(plugin_page));
priv = GNC_PLUGIN_PAGE_GET_PRIVATE(plugin_page);
if (G_LIKELY(GNC_PLUGIN_PAGE_GET_CLASS(plugin_page)->focus_page_function))
{
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus
g_idle_remove_by_data (GNC_PLUGIN_PAGE(plugin_page));
g_idle_add ((GSourceFunc)(GNC_PLUGIN_PAGE_GET_CLASS(plugin_page)->focus_page_function),
GNC_PLUGIN_PAGE(plugin_page));
}
}
/* this is the callback for the plugin "page_changed" signal */
static void
gnc_plugin_page_main_window_changed (GtkWindow *window,
GObject *object,
gpointer user_data)
{
GncPluginPage *current_plugin_page = GNC_PLUGIN_PAGE(object);
GncPluginPage *plugin_page = GNC_PLUGIN_PAGE(user_data);
GncPluginPagePrivate *priv;
gboolean on_current_page = FALSE;
// Continue if current_plugin_page is valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE(current_plugin_page))
return;
// Continue only if the plugin_page is valid
if (!plugin_page || !GNC_IS_PLUGIN_PAGE(plugin_page))
return;
priv = GNC_PLUGIN_PAGE_GET_PRIVATE(plugin_page);
if (current_plugin_page == plugin_page)
on_current_page = TRUE;
(GNC_PLUGIN_PAGE_GET_CLASS(plugin_page)->focus_page)(plugin_page, on_current_page);
}
/* this is the callback for the plugin "inserted" signal which will setup
* the callback for the "page_changed" signal and save a pointer to the
* page focus function. */
void
gnc_plugin_page_inserted_cb (GncPluginPage *page, gpointer user_data)
{
GncPluginPagePrivate *priv;
g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
priv->page_changed_id = g_signal_connect (G_OBJECT(page->window), "page_changed",
G_CALLBACK(gnc_plugin_page_main_window_changed),
page);
// on initial load try and set the page focus
(GNC_PLUGIN_PAGE_GET_CLASS(page)->focus_page)(page, TRUE);
}
/* disconnect the page_changed callback */
void
gnc_plugin_page_disconnect_page_changed (GncPluginPage *page)
{
GncPluginPagePrivate *priv;
g_return_if_fail (GNC_IS_PLUGIN_PAGE(page));
priv = GNC_PLUGIN_PAGE_GET_PRIVATE(page);
if (priv->page_changed_id > 0)
{
g_signal_handler_disconnect (G_OBJECT(page->window), priv->page_changed_id);
priv->page_changed_id = 0;
}
}
/* Retrieve the Uniform Resource Identifier for this page. */
const gchar *
gnc_plugin_page_get_uri (GncPluginPage *page)

View File

@ -156,6 +156,21 @@ typedef struct
* @param window The window where the page was added. */
void (* window_changed) (GncPluginPage *plugin_page, GtkWidget *window);
/** Perform plugin specific actions to set the focus.
*
* @param page The page that was added to a window.
*
* @param on_current_pgae Whether this page is the currentone. */
void (* focus_page) (GncPluginPage *plugin_page, gboolean on_current_page);
/** This function performs specific actions to set the focus on a specific
* widget.
*
* @param page The page that was added to a window.
*
* @param on_current_pgae Whether this page is the currentone. */
gboolean (* focus_page_function) (GncPluginPage *plugin_page);
/** This function vector allows page specific actions to occur
* when the page name is changed.
*
@ -393,12 +408,30 @@ const gchar *gnc_plugin_page_get_page_color (GncPluginPage *page);
*
* @param page The page whose name should be retrieved.
*
* @return The color for this page. This string is owned by the page and
* @param The color for this page. This string is owned by the page and
* should not be freed by the caller.
*/
void gnc_plugin_page_set_page_color (GncPluginPage *page, const char *color);
/** Set up the page_changed callback for when the current page is changed.
* This will store a pointer to the page focus funtion passed as a parameter
* so that it can be used in setting up the g_idle_add
*
* @param page The page the callback is setup for.
*
* @param user_data The page focus function
*/
void gnc_plugin_page_inserted_cb (GncPluginPage *page, gpointer user_data);
/** Disconnect the page_changed_id signal callback.
*
* @param page The page whose name should be retrieved.
*/
void gnc_plugin_page_disconnect_page_changed (GncPluginPage *page);
/** Retrieve the Uniform Resource Identifier for this page.
*
* @param page The page whose URI should be retrieved.

View File

@ -114,6 +114,7 @@ static void gnc_plugin_page_account_tree_init (GncPluginPageAccountTree *plugin_
static void gnc_plugin_page_account_tree_finalize (GObject *object);
static void gnc_plugin_page_account_tree_selected (GObject *object, gpointer user_data);
static gboolean gnc_plugin_page_account_tree_focus_widget (GncPluginPage *plugin_page);
static GtkWidget *gnc_plugin_page_account_tree_create_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_account_tree_destroy_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_account_tree_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
@ -405,6 +406,7 @@ gnc_plugin_page_account_tree_class_init (GncPluginPageAccountTreeClass *klass)
gnc_plugin_class->destroy_widget = gnc_plugin_page_account_tree_destroy_widget;
gnc_plugin_class->save_page = gnc_plugin_page_account_tree_save_page;
gnc_plugin_class->recreate_page = gnc_plugin_page_account_tree_recreate_page;
gnc_plugin_class->focus_page_function = gnc_plugin_page_account_tree_focus_widget;
plugin_page_signals[ACCOUNT_SELECTED] =
g_signal_new ("account_selected",
@ -573,12 +575,16 @@ gnc_plugin_page_account_tree_get_current_account (GncPluginPageAccountTree *page
return account;
}
gboolean
gnc_plugin_page_account_tree_focus (GncPluginPageAccountTree *page)
/**
* Whenever the current page is changed, if an account page is
* the current page, set focus on the tree view.
*/
static gboolean
gnc_plugin_page_account_tree_focus_widget (GncPluginPage *account_plugin_page)
{
if (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(page))
if (GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(account_plugin_page))
{
GncPluginPageAccountTreePrivate *priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(page);
GncPluginPageAccountTreePrivate *priv = GNC_PLUGIN_PAGE_ACCOUNT_TREE_GET_PRIVATE(account_plugin_page);
GtkTreeView *view = GTK_TREE_VIEW(priv->tree_view);
if (!gtk_widget_is_focus (GTK_WIDGET(view)))
@ -636,32 +642,11 @@ gnc_plugin_page_account_editing_finished_cb (gpointer various, GncPluginPageRegi
gtk_action_set_sensitive (action, TRUE);
}
static void
gnc_plugin_account_tree_main_window_page_changed (GncMainWindow *window,
GncPluginPage *current_plugin_page,
GncPluginPage *account_plugin_page)
{
// We continue only if the plugin_page is a valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(current_plugin_page)||
!account_plugin_page || !GNC_IS_PLUGIN_PAGE_ACCOUNT_TREE(account_plugin_page))
return;
if (current_plugin_page == account_plugin_page)
{
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus to the tree view
g_idle_remove_by_data (GNC_PLUGIN_PAGE_ACCOUNT_TREE (account_plugin_page));
g_idle_add ((GSourceFunc)gnc_plugin_page_account_tree_focus,
GNC_PLUGIN_PAGE_ACCOUNT_TREE (account_plugin_page));
}
}
static GtkWidget *
gnc_plugin_page_account_tree_create_widget (GncPluginPage *plugin_page)
{
GncPluginPageAccountTree *page;
GncPluginPageAccountTreePrivate *priv;
GncMainWindow *window;
GtkTreeSelection *selection;
GtkTreeView *tree_view;
GtkWidget *scrolled_window;
@ -759,10 +744,9 @@ gnc_plugin_page_account_tree_create_widget (GncPluginPage *plugin_page)
gnc_plugin_page_account_tree_summarybar_position_changed,
page);
window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(page)->window);
g_signal_connect (window, "page_changed",
G_CALLBACK(gnc_plugin_account_tree_main_window_page_changed),
plugin_page);
g_signal_connect (G_OBJECT(plugin_page), "inserted",
G_CALLBACK(gnc_plugin_page_inserted_cb),
NULL);
// Read account filter state information from account section
gnc_tree_view_account_restore_filter (GNC_TREE_VIEW_ACCOUNT(priv->tree_view), &priv->fd,
@ -798,8 +782,11 @@ gnc_plugin_page_account_tree_destroy_widget (GncPluginPage *plugin_page)
// Destroy the filter override hash table
g_hash_table_destroy(priv->fd.filter_override);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
// Remove the page focus idle function if present
g_idle_remove_by_data (GNC_PLUGIN_PAGE_ACCOUNT_TREE (plugin_page));
g_idle_remove_by_data (plugin_page);
if (priv->widget)
{

View File

@ -95,15 +95,6 @@ GncPluginPage *gnc_plugin_page_account_tree_new (void);
Account * gnc_plugin_page_account_tree_get_current_account (GncPluginPageAccountTree *page);
/** Given a pointer to an account tree plugin page, set the focus to
* the GtkTreeView. This is used in a g_idle_add so return FALSE.
*
* @param page The "account tree" page.
*
* @return FALSE;
*/
gboolean gnc_plugin_page_account_tree_focus (GncPluginPageAccountTree *page);
/** Given a pointer to an account, the account tree will open
* and the account will be selected (if any).
*

View File

@ -58,6 +58,7 @@
#include "gnc-tree-view-account.h"
#include "gnc-ui.h"
#include "gnc-ui-util.h"
#include "gnc-window.h"
#include "option-util.h"
#include "gnc-main-window.h"
#include "gnc-component-manager.h"
@ -85,6 +86,7 @@ static void gnc_plugin_page_budget_finalize (GObject *object);
static GtkWidget *
gnc_plugin_page_budget_create_widget (GncPluginPage *plugin_page);
static gboolean gnc_plugin_page_budget_focus_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_budget_destroy_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_budget_save_page (GncPluginPage *plugin_page,
GKeyFile *file,
@ -299,6 +301,7 @@ gnc_plugin_page_budget_class_init (GncPluginPageBudgetClass *klass)
gnc_plugin_class->destroy_widget = gnc_plugin_page_budget_destroy_widget;
gnc_plugin_class->save_page = gnc_plugin_page_budget_save_page;
gnc_plugin_class->recreate_page = gnc_plugin_page_budget_recreate_page;
gnc_plugin_class->focus_page_function = gnc_plugin_page_budget_focus_widget;
}
@ -372,12 +375,16 @@ gnc_plugin_page_budget_close_cb (gpointer user_data)
}
gboolean
gnc_plugin_page_budget_focus (GncPluginPageBudget *page)
/**
* Whenever the current page is changed, if a budget page is
* the current page, set focus on the budget tree view.
*/
static gboolean
gnc_plugin_page_budget_focus_widget (GncPluginPage *budget_plugin_page)
{
if (GNC_IS_PLUGIN_PAGE_BUDGET(page))
if (GNC_IS_PLUGIN_PAGE_BUDGET(budget_plugin_page))
{
GncPluginPageBudgetPrivate *priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(page);
GncPluginPageBudgetPrivate *priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(budget_plugin_page);
GncBudgetView *budget_view = priv->budget_view;
GtkWidget *account_view = gnc_budget_view_get_account_tree_view (budget_view);
@ -423,27 +430,6 @@ gnc_plugin_page_budget_refresh_cb (GHashTable *changes, gpointer user_data)
}
static void
gnc_plugin_budget_main_window_page_changed (GncMainWindow *window,
GncPluginPage *current_plugin_page,
GncPluginPage *budget_plugin_page)
{
// We continue only if the plugin_page is a valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_BUDGET(current_plugin_page) ||
!budget_plugin_page || !GNC_IS_PLUGIN_PAGE_BUDGET(budget_plugin_page))
return;
if (current_plugin_page == budget_plugin_page)
{
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus to the tree view
g_idle_remove_by_data (GNC_PLUGIN_PAGE_BUDGET(budget_plugin_page));
g_idle_add ((GSourceFunc)gnc_plugin_page_budget_focus,
GNC_PLUGIN_PAGE_BUDGET(budget_plugin_page));
}
}
/****************************
* GncPluginPage Functions *
***************************/
@ -452,7 +438,6 @@ gnc_plugin_page_budget_create_widget (GncPluginPage *plugin_page)
{
GncPluginPageBudget *page;
GncPluginPageBudgetPrivate *priv;
GncMainWindow *window;
ENTER("page %p", plugin_page);
page = GNC_PLUGIN_PAGE_BUDGET(plugin_page);
@ -487,10 +472,9 @@ gnc_plugin_page_budget_create_widget (GncPluginPage *plugin_page)
gnc_budget_get_guid (priv->budget),
QOF_EVENT_DESTROY | QOF_EVENT_MODIFY);
window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(page)->window);
g_signal_connect (window, "page_changed",
G_CALLBACK(gnc_plugin_budget_main_window_page_changed),
plugin_page);
g_signal_connect (G_OBJECT(plugin_page), "inserted",
G_CALLBACK(gnc_plugin_page_inserted_cb),
NULL);
LEAVE("widget = %p", priv->budget_view);
return GTK_WIDGET(priv->budget_view);
@ -505,8 +489,11 @@ gnc_plugin_page_budget_destroy_widget (GncPluginPage *plugin_page)
ENTER("page %p", plugin_page);
priv = GNC_PLUGIN_PAGE_BUDGET_GET_PRIVATE(plugin_page);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
// Remove the page focus idle function if present
g_idle_remove_by_data (GNC_PLUGIN_PAGE_BUDGET(plugin_page));
g_idle_remove_by_data (plugin_page);
if (priv->budget_view)
{

View File

@ -70,16 +70,6 @@ GncPluginPage *gnc_plugin_page_budget_new (GncBudget *budget);
void gnc_budget_gui_delete_budget (GncBudget *budget);
/** Given a pointer to a budget plugin page, set the focus to
* the Account GtkTreeView. This is used in a g_idle_add so
* return FALSE.
*
* @param page The "budget" page.
*
* @return FALSE
*/
gboolean gnc_plugin_page_budget_focus (GncPluginPageBudget *page);
G_END_DECLS
#endif /* __GNC_PLUGIN_PAGE_BUDGET_H */

View File

@ -52,6 +52,7 @@ static void gnc_plugin_page_invoice_init (GncPluginPageInvoice *plugin_page);
static void gnc_plugin_page_invoice_finalize (GObject *object);
static GtkWidget *gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page);
static gboolean gnc_plugin_page_invoice_focus_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_invoice_destroy_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_invoice_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
static GncPluginPage *gnc_plugin_page_invoice_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
@ -448,6 +449,7 @@ gnc_plugin_page_invoice_class_init (GncPluginPageInvoiceClass *klass)
gnc_plugin_class->save_page = gnc_plugin_page_invoice_save_page;
gnc_plugin_class->recreate_page = gnc_plugin_page_invoice_recreate_page;
gnc_plugin_class->window_changed = gnc_plugin_page_invoice_window_changed;
gnc_plugin_class->focus_page_function = gnc_plugin_page_invoice_focus_widget;
}
static void
@ -572,56 +574,39 @@ gnc_plugin_page_invoice_update_menus (GncPluginPage *page, gboolean is_posted, g
}
static gboolean
gnc_plugin_page_invoice_focus (InvoiceWindow *iw)
{
GtkWidget *regWidget = gnc_invoice_get_register(iw);
GtkWidget *notes = gnc_invoice_get_notes(iw);
GnucashSheet *sheet;
if (!GNUCASH_IS_REGISTER(regWidget))
return FALSE;
sheet = gnucash_register_get_sheet (GNUCASH_REGISTER(regWidget));
// Test for the sheet being read only
if (!gnucash_sheet_is_read_only (sheet))
{
if (!gtk_widget_is_focus (GTK_WIDGET(sheet)))
gtk_widget_grab_focus (GTK_WIDGET(sheet));
}
else // set focus to the notes field
{
if (!gtk_widget_is_focus (GTK_WIDGET(notes)))
gtk_widget_grab_focus (GTK_WIDGET(notes));
}
return FALSE;
}
/**
* Whenever the current page is changed, if an invoice page is
* the current page, set focus on the sheet or notes field.
*/
static void
gnc_plugin_page_invoice_main_window_page_changed (GncMainWindow *window,
GncPluginPage *current_plugin_page,
GncPluginPage *invoice_plugin_page)
static gboolean
gnc_plugin_page_invoice_focus_widget (GncPluginPage *invoice_plugin_page)
{
// We continue only if the plugin_page is a valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_INVOICE(current_plugin_page) ||
!invoice_plugin_page || !GNC_IS_PLUGIN_PAGE_INVOICE(invoice_plugin_page))
return;
if (current_plugin_page == invoice_plugin_page)
if (GNC_IS_PLUGIN_PAGE_INVOICE(invoice_plugin_page))
{
GncPluginPageInvoicePrivate *priv = GNC_PLUGIN_PAGE_INVOICE_GET_PRIVATE(invoice_plugin_page);
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus to the sheet
g_idle_remove_by_data (priv->iw);
g_idle_add ((GSourceFunc)gnc_plugin_page_invoice_focus, priv->iw);
GtkWidget *regWidget = gnc_invoice_get_register(priv->iw);
GtkWidget *notes = gnc_invoice_get_notes(priv->iw);
GnucashSheet *sheet;
if (!GNUCASH_IS_REGISTER(regWidget))
return FALSE;
sheet = gnucash_register_get_sheet (GNUCASH_REGISTER(regWidget));
// Test for the sheet being read only
if (!gnucash_sheet_is_read_only (sheet))
{
if (!gtk_widget_is_focus (GTK_WIDGET(sheet)))
gtk_widget_grab_focus (GTK_WIDGET(sheet));
}
else // set focus to the notes field
{
if (!gtk_widget_is_focus (GTK_WIDGET(notes)))
gtk_widget_grab_focus (GTK_WIDGET(notes));
}
}
return FALSE;
}
@ -633,7 +618,6 @@ gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page)
GncPluginPageInvoice *page;
GncPluginPageInvoicePrivate *priv;
GtkWidget *regWidget, *widget;
GncMainWindow *window;
ENTER("page %p", plugin_page);
page = GNC_PLUGIN_PAGE_INVOICE (plugin_page);
@ -680,10 +664,9 @@ gnc_plugin_page_invoice_create_widget (GncPluginPage *plugin_page)
gnc_plugin_page_invoice_refresh_cb,
NULL, page);
window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
g_signal_connect(window, "page_changed",
G_CALLBACK(gnc_plugin_page_invoice_main_window_page_changed),
plugin_page);
g_signal_connect (G_OBJECT(plugin_page), "inserted",
G_CALLBACK(gnc_plugin_page_inserted_cb),
NULL);
LEAVE("");
return priv->widget;
@ -708,8 +691,11 @@ gnc_plugin_page_invoice_destroy_widget (GncPluginPage *plugin_page)
gnc_plugin_page_invoice_summarybar_position_changed,
page);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
// Remove the page focus idle function if present
g_idle_remove_by_data (priv->iw);
g_idle_remove_by_data (plugin_page);
if (priv->widget == NULL)
{

View File

@ -58,6 +58,7 @@
#include "gnc-tree-view-owner.h"
#include "gnc-ui.h"
#include "gnc-ui-util.h"
#include "gnc-window.h"
#include "guile-mappings.h"
#include "dialog-lot-viewer.h"
#include "dialog-object-references.h"
@ -365,43 +366,25 @@ gnc_plugin_page_owner_tree_new (GncOwnerType owner_type)
return GNC_PLUGIN_PAGE(plugin_page);
}
static gboolean
gnc_plugin_page_owner_focus (GtkTreeView *tree_view)
{
if (GTK_IS_TREE_VIEW(tree_view))
{
if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
gtk_widget_grab_focus (GTK_WIDGET(tree_view));
}
return FALSE;
}
/**
* Whenever the current page is changed, if an owner page is
* the current page, set focus on the treeview.
* the current page, set focus on the tree view.
*/
static void
gnc_plugin_page_owner_main_window_page_changed (GncMainWindow *window,
GncPluginPage *current_plugin_page,
GncPluginPage *owner_plugin_page)
static gboolean
gnc_plugin_page_owner_focus_widget (GncPluginPage *owner_plugin_page)
{
// We continue only if the plugin_page is a valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_OWNER_TREE(current_plugin_page) ||
!owner_plugin_page || !GNC_IS_PLUGIN_PAGE_OWNER_TREE(owner_plugin_page))
return;
if (current_plugin_page == owner_plugin_page)
if (GNC_IS_PLUGIN_PAGE_OWNER_TREE(owner_plugin_page))
{
GncPluginPageOwnerTreePrivate *priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(owner_plugin_page);
GtkTreeView *tree_view = priv->tree_view;
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus to the tree view
g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
g_idle_add ((GSourceFunc)gnc_plugin_page_owner_focus,
GTK_TREE_VIEW (priv->tree_view));
if (GTK_IS_TREE_VIEW(tree_view))
{
if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
gtk_widget_grab_focus (GTK_WIDGET(tree_view));
}
}
return FALSE;
}
G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageOwnerTree, gnc_plugin_page_owner_tree, GNC_TYPE_PLUGIN_PAGE)
@ -422,6 +405,7 @@ gnc_plugin_page_owner_tree_class_init (GncPluginPageOwnerTreeClass *klass)
gnc_plugin_class->destroy_widget = gnc_plugin_page_owner_tree_destroy_widget;
gnc_plugin_class->save_page = gnc_plugin_page_owner_tree_save_page;
gnc_plugin_class->recreate_page = gnc_plugin_page_owner_tree_recreate_page;
gnc_plugin_class->focus_page_function = gnc_plugin_page_owner_focus_widget;
plugin_page_signals[OWNER_SELECTED] =
g_signal_new ("owner_selected",
@ -571,7 +555,6 @@ gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
{
GncPluginPageOwnerTree *page;
GncPluginPageOwnerTreePrivate *priv;
GncMainWindow *window;
GtkTreeSelection *selection;
GtkTreeView *tree_view;
GtkWidget *scrolled_window;
@ -686,10 +669,9 @@ gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
gnc_gui_component_set_session (priv->component_id,
gnc_get_current_session());
window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
g_signal_connect(window, "page_changed",
G_CALLBACK(gnc_plugin_page_owner_main_window_page_changed),
plugin_page);
g_signal_connect (G_OBJECT(plugin_page), "inserted",
G_CALLBACK(gnc_plugin_page_inserted_cb),
NULL);
LEAVE("widget = %p", priv->widget);
return priv->widget;
@ -705,8 +687,11 @@ gnc_plugin_page_owner_tree_destroy_widget (GncPluginPage *plugin_page)
page = GNC_PLUGIN_PAGE_OWNER_TREE (plugin_page);
priv = GNC_PLUGIN_PAGE_OWNER_TREE_GET_PRIVATE(page);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
// Remove the page focus idle function if present
g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
g_idle_remove_by_data (plugin_page);
if (priv->widget)
{

View File

@ -102,6 +102,8 @@ static void gnc_plugin_page_register_finalize (GObject *object);
static GtkWidget *gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_register_window_changed (GncPluginPage *plugin_page, GtkWidget *window);
static gboolean gnc_plugin_page_register_focus_widget (GncPluginPage *plugin_page);
static void gnc_plugin_page_register_focus (GncPluginPage *plugin_page, gboolean current_page);
static void gnc_plugin_page_register_save_page (GncPluginPage *plugin_page, GKeyFile *file, const gchar *group);
static GncPluginPage *gnc_plugin_page_register_recreate_page (GtkWidget *window, GKeyFile *file, const gchar *group);
static void gnc_plugin_page_register_update_edit_menu (GncPluginPage *page, gboolean hide);
@ -750,10 +752,12 @@ gnc_plugin_page_register_class_init (GncPluginPageRegisterClass *klass)
gnc_plugin_class->create_widget = gnc_plugin_page_register_create_widget;
gnc_plugin_class->destroy_widget = gnc_plugin_page_register_destroy_widget;
gnc_plugin_class->window_changed = gnc_plugin_page_register_window_changed;
gnc_plugin_class->focus_page = gnc_plugin_page_register_focus;
gnc_plugin_class->save_page = gnc_plugin_page_register_save_page;
gnc_plugin_class->recreate_page = gnc_plugin_page_register_recreate_page;
gnc_plugin_class->update_edit_menu_actions = gnc_plugin_page_register_update_edit_menu;
gnc_plugin_class->finish_pending = gnc_plugin_page_register_finish_pending;
gnc_plugin_class->focus_page_function = gnc_plugin_page_register_focus_widget;
gnc_ui_register_account_destroy_callback (gppr_account_destroy_cb);
}
@ -843,12 +847,16 @@ gnc_plugin_page_register_get_current_txn (GncPluginPageRegister *page)
return gnc_split_register_get_current_trans(reg);
}
gboolean
gnc_plugin_page_register_focus (GncPluginPageRegister *page)
/**
* Whenever the current page is changed, if a register page is
* the current page, set focus on the sheet.
*/
static gboolean
gnc_plugin_page_register_focus_widget (GncPluginPage *register_plugin_page)
{
if (GNC_IS_PLUGIN_PAGE_REGISTER(page))
if (GNC_IS_PLUGIN_PAGE_REGISTER(register_plugin_page))
{
GNCSplitReg *gsr = gnc_plugin_page_register_get_gsr(GNC_PLUGIN_PAGE(page));
GNCSplitReg *gsr = gnc_plugin_page_register_get_gsr(GNC_PLUGIN_PAGE(register_plugin_page));
gnc_split_reg_focus_on_sheet (gsr);
}
return FALSE;
@ -1145,31 +1153,33 @@ get_filter_default_num_of_days (GNCLedgerDisplayType ledger_type)
return "0";
}
/* For setting the focus on a register page, the default gnc_plugin
* function for 'focus_page' is overridden so that the page focus
* can be condionally set. This is to allow for enabling the setting
* of the sheet focus only when the page is the current one.
*/
static void
gnc_plugin_register_main_window_page_changed (GncMainWindow *window,
GncPluginPage *current_plugin_page,
GncPluginPage *register_plugin_page)
gnc_plugin_page_register_focus (GncPluginPage *plugin_page,
gboolean on_current_page)
{
GncPluginPageRegister *page;
GncPluginPageRegisterPrivate *priv;
GNCSplitReg *gsr;
// We continue only if the plugin_page is a valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_REGISTER(current_plugin_page) ||
!register_plugin_page || !GNC_IS_PLUGIN_PAGE_REGISTER(register_plugin_page))
return;
g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER (plugin_page));
priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(register_plugin_page);
gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(register_plugin_page));
page = GNC_PLUGIN_PAGE_REGISTER(plugin_page);
priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE(page);
if (current_plugin_page == register_plugin_page)
gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(plugin_page));
if (on_current_page)
{
priv->page_focus = TRUE;
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus to the register
g_idle_remove_by_data (GNC_PLUGIN_PAGE_REGISTER (register_plugin_page));
g_idle_add ((GSourceFunc)gnc_plugin_page_register_focus,
GNC_PLUGIN_PAGE_REGISTER (register_plugin_page));
// Chain up to use parent version of 'focus_page' which will
// use an idle_add as the page changed signal is emitted multiple times.
GNC_PLUGIN_PAGE_CLASS(parent_class)->focus_page (plugin_page, TRUE);
}
else
priv->page_focus = FALSE;
@ -1183,7 +1193,6 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
{
GncPluginPageRegister *page;
GncPluginPageRegisterPrivate *priv;
GncMainWindow *window;
GNCLedgerDisplayType ledger_type;
GncWindow *gnc_window;
guint numRows;
@ -1398,10 +1407,9 @@ gnc_plugin_page_register_create_widget (GncPluginPage *plugin_page)
gnc_split_reg_set_moved_cb
(priv->gsr, (GFunc)gnc_plugin_page_register_ui_update, page);
window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
g_signal_connect (window, "page_changed",
G_CALLBACK(gnc_plugin_register_main_window_page_changed),
plugin_page);
g_signal_connect (G_OBJECT(plugin_page), "inserted",
G_CALLBACK(gnc_plugin_page_inserted_cb),
NULL);
/* DRH - Probably lots of other stuff from regWindowLedger should end up here. */
LEAVE(" ");
@ -1427,6 +1435,9 @@ gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page)
gnc_plugin_page_register_summarybar_position_changed,
page);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
// Remove the page focus idle function if present
g_idle_remove_by_data (GNC_PLUGIN_PAGE_REGISTER (plugin_page));
@ -1468,7 +1479,7 @@ gnc_plugin_page_register_destroy_widget (GncPluginPage *plugin_page)
static void
gnc_plugin_page_register_window_changed (GncPluginPage *plugin_page,
GtkWidget *window)
GtkWidget *window)
{
GncPluginPageRegister *page;
GncPluginPageRegisterPrivate *priv;

View File

@ -163,16 +163,6 @@ gnc_plugin_page_register_get_account (GncPluginPageRegister *page);
Transaction *
gnc_plugin_page_register_get_current_txn (GncPluginPageRegister *page);
/** Given a pointer to a register plugin page, set the focus to
* the sheet. This is used in a g_idle_add so return FALSE.
*
* @param page The "register" page.
*
* @return FALSE
*/
gboolean
gnc_plugin_page_register_focus (GncPluginPageRegister *page);
G_END_DECLS
/** @} */
/** @} */

View File

@ -73,6 +73,7 @@
#include "gnc-tree-view-sx-list.h"
#include "gnc-ui-util.h"
#include "gnc-ui.h"
#include "gnc-window.h"
#undef G_LOG_DOMAIN
#define G_LOG_DOMAIN "gnc.gui.plugin-page.sx-list"
@ -187,42 +188,25 @@ gnc_plugin_page_sx_list_new (void)
}
static gboolean
gnc_plugin_page_sx_list_focus (GtkTreeView *tree_view)
{
if (GTK_IS_TREE_VIEW(tree_view))
{
if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
gtk_widget_grab_focus (GTK_WIDGET(tree_view));
}
return FALSE;
}
/**
* Whenever the current page is changed, if a schedule editor page is
* the current page, set focus on the treeview.
* Whenever the current page is changed, if a sx page is
* the current page, set focus on the tree view.
*/
static void
gnc_plugin_page_sx_list_main_window_page_changed (GncMainWindow *window,
GncPluginPage *current_plugin_page,
GncPluginPage *sx_plugin_page)
static gboolean
gnc_plugin_page_sx_list_focus_widget (GncPluginPage *sx_plugin_page)
{
// We continue only if the plugin_page is a valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_SX_LIST(current_plugin_page) ||
!sx_plugin_page || !GNC_IS_PLUGIN_PAGE_SX_LIST(sx_plugin_page))
return;
if (current_plugin_page == sx_plugin_page)
if (GNC_IS_PLUGIN_PAGE_SX_LIST(sx_plugin_page))
{
GncPluginPageSxListPrivate *priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(sx_plugin_page);
GtkTreeView *tree_view = priv->tree_view;
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus to the tree view
g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
g_idle_add ((GSourceFunc)gnc_plugin_page_sx_list_focus,
GTK_TREE_VIEW (priv->tree_view));
if (GTK_IS_TREE_VIEW(tree_view))
{
if (!gtk_widget_is_focus (GTK_WIDGET(tree_view)))
gtk_widget_grab_focus (GTK_WIDGET(tree_view));
}
}
return FALSE;
}
G_DEFINE_TYPE_WITH_PRIVATE(GncPluginPageSxList, gnc_plugin_page_sx_list, GNC_TYPE_PLUGIN_PAGE)
@ -244,6 +228,7 @@ gnc_plugin_page_sx_list_class_init (GncPluginPageSxListClass *klass)
gnc_plugin_class->destroy_widget = gnc_plugin_page_sx_list_destroy_widget;
gnc_plugin_class->save_page = gnc_plugin_page_sx_list_save_page;
gnc_plugin_class->recreate_page = gnc_plugin_page_sx_list_recreate_page;
gnc_plugin_class->focus_page_function = gnc_plugin_page_sx_list_focus_widget;
}
@ -371,7 +356,6 @@ gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
{
GncPluginPageSxList *page;
GncPluginPageSxListPrivate *priv;
GncMainWindow *window;
GtkWidget *widget;
GtkWidget *vbox;
GtkWidget *label;
@ -498,10 +482,9 @@ gnc_plugin_page_sx_list_create_widget (GncPluginPage *plugin_page)
gnc_gui_component_set_session (priv->gnc_component_id,
gnc_get_current_session());
window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(plugin_page)->window);
g_signal_connect(window, "page_changed",
G_CALLBACK(gnc_plugin_page_sx_list_main_window_page_changed),
plugin_page);
g_signal_connect (G_OBJECT(plugin_page), "inserted",
G_CALLBACK(gnc_plugin_page_inserted_cb),
NULL);
return priv->widget;
}
@ -516,8 +499,11 @@ gnc_plugin_page_sx_list_destroy_widget (GncPluginPage *plugin_page)
page = GNC_PLUGIN_PAGE_SX_LIST (plugin_page);
priv = GNC_PLUGIN_PAGE_SX_LIST_GET_PRIVATE(page);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
// Remove the page focus idle function if present
g_idle_remove_by_data (GTK_TREE_VIEW (priv->tree_view));
g_idle_remove_by_data (plugin_page);
if (priv->widget)
{

View File

@ -233,41 +233,25 @@ gnc_plugin_page_report_set_property( GObject *obj,
}
static gboolean
gnc_plugin_page_report_focus (GtkWidget *widget)
{
if (GTK_IS_WIDGET(widget))
{
if (!gtk_widget_is_focus (GTK_WIDGET(widget)))
gtk_widget_grab_focus (GTK_WIDGET(widget));
}
return FALSE;
}
/**
* Whenever the current page is changed, if a report page is
* the current page, set focus on the report.
*/
static void
gnc_plugin_page_report_main_window_page_changed (GncMainWindow *window,
GncPluginPage *current_plugin_page,
GncPluginPage *report_plugin_page)
static gboolean
gnc_plugin_page_report_focus_widget (GncPluginPage *report_plugin_page)
{
// We continue only if the plugin_page is a valid
if (!current_plugin_page || !GNC_IS_PLUGIN_PAGE_REPORT(current_plugin_page) ||
!report_plugin_page || !GNC_IS_PLUGIN_PAGE_REPORT(report_plugin_page))
return;
if (current_plugin_page == report_plugin_page)
if (GNC_IS_PLUGIN_PAGE_REPORT(report_plugin_page))
{
GncPluginPageReportPrivate *priv = GNC_PLUGIN_PAGE_REPORT_GET_PRIVATE(report_plugin_page);
GtkWidget *widget = gnc_html_get_widget (priv->html);
// The page changed signal is emitted multiple times so we need
// to use an idle_add to change the focus to the webkit widget
g_idle_remove_by_data (widget);
g_idle_add ((GSourceFunc)gnc_plugin_page_report_focus, widget);
if (GTK_IS_WIDGET(widget))
{
if (!gtk_widget_is_focus (GTK_WIDGET(widget)))
gtk_widget_grab_focus (GTK_WIDGET(widget));
}
}
return FALSE;
}
static void
@ -294,6 +278,7 @@ gnc_plugin_page_report_class_init (GncPluginPageReportClass *klass)
gnc_plugin_page_class->page_name_changed = gnc_plugin_page_report_name_changed;
gnc_plugin_page_class->update_edit_menu_actions = gnc_plugin_page_report_update_edit_menu;
gnc_plugin_page_class->finish_pending = gnc_plugin_page_report_finish_pending;
gnc_plugin_page_class->focus_page_function = gnc_plugin_page_report_focus_widget;
// create the "reportId" property
g_object_class_install_property( object_class,
@ -412,7 +397,6 @@ gnc_plugin_page_report_create_widget( GncPluginPage *page )
{
GncPluginPageReport *report;
GncPluginPageReportPrivate *priv;
GncMainWindow *window;
GtkWindow *topLvl;
GtkAction *action;
URLType type;
@ -477,10 +461,9 @@ gnc_plugin_page_report_create_widget( GncPluginPage *page )
g_signal_connect (G_OBJECT(GTK_WIDGET(priv->container)), "realize",
G_CALLBACK(gnc_plugin_page_report_realize_uri), page);
window = GNC_MAIN_WINDOW(GNC_PLUGIN_PAGE(page)->window);
g_signal_connect(window, "page_changed",
G_CALLBACK(gnc_plugin_page_report_main_window_page_changed),
page);
g_signal_connect (G_OBJECT(page), "inserted",
G_CALLBACK(gnc_plugin_page_inserted_cb),
NULL);
gtk_widget_show_all( GTK_WIDGET(priv->container) );
LEAVE("container %p", priv->container);
@ -783,8 +766,11 @@ gnc_plugin_page_report_destroy_widget(GncPluginPage *plugin_page)
widget = gnc_html_get_widget(priv->html);
// Remove the page_changed signal callback
gnc_plugin_page_disconnect_page_changed (GNC_PLUGIN_PAGE(plugin_page));
// Remove the page focus idle function if present
g_idle_remove_by_data (widget);
g_idle_remove_by_data (plugin_page);
if (priv->component_manager_id)
{