Add option to save Layout for Register items

Add two menu items under windows, one to save an existing register
layout based on the register type to there respective default layouts
so the user set column widths will be used when opening registers. The
second menu item will reset the column widths to defaults and remove
the associated default layout.
Open registers will also save there column widths to the page section
so these could can temporarily have different widths.
This commit is contained in:
Robert Fewell 2020-05-02 14:37:40 +01:00
parent 74abd821b3
commit 2494ad1adf
4 changed files with 232 additions and 43 deletions

View File

@ -253,6 +253,10 @@ static void gnc_plugin_page_register_cmd_account_report (GtkAction* action,
GncPluginPageRegister* plugin_page);
static void gnc_plugin_page_register_cmd_transaction_report (GtkAction* action,
GncPluginPageRegister* plugin_page);
static void gnc_plugin_page_register_cmd_save_layout (GtkAction *action,
GncPluginPageRegister *plugin_page);
static void gnc_plugin_page_register_cmd_reset_layout (GtkAction *action,
GncPluginPageRegister *plugin_page);
static void gnc_plugin_page_register_cmd_associate_file_transaction (
GtkAction* action, GncPluginPageRegister* plugin_page);
static void gnc_plugin_page_register_cmd_associate_location_transaction (
@ -516,6 +520,18 @@ static GtkActionEntry gnc_plugin_page_register_actions [] =
N_ ("Open a register report for the selected Transaction"),
G_CALLBACK (gnc_plugin_page_register_cmd_transaction_report)
},
/* Windows menu */
{
"WindowsSaveLayoutAction", NULL, "_Use as Default Layout for this Register Group", NULL,
N_("Use the current layout as default for all registers in the group 'Currency account registers'"),
G_CALLBACK (gnc_plugin_page_register_cmd_save_layout)
},
{
"WindowsResetLayoutAction", NULL, "_Reset Default Layout for this Register Group", NULL,
N_("Reset default layout for all registers in the group 'Currency account registers' back to built-in defaults and update page accordingly"),
G_CALLBACK (gnc_plugin_page_register_cmd_reset_layout)
},
};
static guint gnc_plugin_page_register_n_actions = G_N_ELEMENTS (
@ -640,6 +656,8 @@ typedef struct GncPluginPageRegisterPrivate
GtkWidget* widget;
const gchar *page_state_name; /* Used for loading state information */
gint event_handler_id;
gint component_manager_id;
GncGUID key; /* The guid of the Account we're watching */
@ -904,6 +922,7 @@ gnc_plugin_page_register_init (GncPluginPageRegister* plugin_page)
priv->enable_refresh = TRUE;
priv->search_query = NULL;
priv->filter_query = NULL;
priv->page_state_name = NULL;
}
static void
@ -953,8 +972,10 @@ gnc_plugin_page_register_focus_widget (GncPluginPage* register_plugin_page)
{
if (GNC_IS_PLUGIN_PAGE_REGISTER (register_plugin_page))
{
GNCSplitReg* gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE (
register_plugin_page));
GNCSplitReg *gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(register_plugin_page));
gnc_plugin_page_register_ui_update (NULL, GNC_PLUGIN_PAGE_REGISTER(register_plugin_page));
gnc_split_reg_focus_on_sheet (gsr);
}
return FALSE;
@ -1190,6 +1211,26 @@ gnc_plugin_page_register_ui_update (gpointer various,
}
}
}
// update the register default layouts actions
{
gboolean has_default = FALSE;
const gchar *group = gnc_split_reg_get_register_state_group (priv->gsr);
GtkAction *layout_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), "WindowsSaveLayoutAction");
gchar *tt = g_strdup_printf (gettext ("Use the current layout as default for all registers in the group '%s'"), _(group));
gtk_action_set_tooltip (layout_action, tt);
g_free (tt);
layout_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(page), "WindowsResetLayoutAction");
tt = g_strdup_printf (gettext ("Reset default layout for all registers in the group '%s' back to built-in defaults and update page accordingly"), _(group));
gtk_action_set_tooltip (layout_action, tt);
g_free (tt);
// if there is no default layout do not enable reset action
if (gnc_split_reg_register_has_user_state (priv->gsr))
has_default = TRUE;
gtk_action_set_sensitive (layout_action, has_default);
}
}
static void
@ -1330,11 +1371,12 @@ gnc_plugin_page_register_create_widget (GncPluginPage* plugin_page)
numRows = priv->lines_default;
numRows = MIN (numRows, DEFAULT_LINES_AMOUNT);
gnc_window = GNC_WINDOW (GNC_PLUGIN_PAGE (page)->window);
gnc_window = GNC_WINDOW(GNC_PLUGIN_PAGE(page)->window);
gsr = gnc_split_reg_new (priv->ledger,
gnc_window_get_gtk_window (gnc_window),
numRows, priv->read_only);
priv->gsr = (GNCSplitReg*)gsr;
numRows, priv->read_only, priv->page_state_name);
priv->gsr = (GNCSplitReg *)gsr;
gtk_widget_show (gsr);
gtk_box_pack_start (GTK_BOX (priv->widget), gsr, TRUE, TRUE, 0);
@ -1696,7 +1738,10 @@ gnc_plugin_page_register_save_page (GncPluginPage* plugin_page,
g_key_file_set_boolean (key_file, group_name, KEY_DOUBLE_LINE,
reg->use_double_line);
LEAVE (" ");
// save the open table layout
gnc_table_save_state (reg->table, group_name, NULL);
LEAVE(" ");
}
@ -1833,6 +1878,7 @@ gnc_plugin_page_register_recreate_page (GtkWidget* window,
* sort/filter updates and double line/style changes */
priv = GNC_PLUGIN_PAGE_REGISTER_GET_PRIVATE (page);
priv->enable_refresh = FALSE;
priv->page_state_name = group_name;
/* Recreate page in given window */
gnc_plugin_page_set_use_new_window (page, FALSE);
@ -4977,6 +5023,46 @@ gnc_plugin_page_register_cmd_transaction_report (GtkAction* action,
LEAVE (" ");
}
static void
gnc_plugin_page_register_cmd_save_layout (GtkAction *action, GncPluginPageRegister *plugin_page)
{
GNCSplitReg *gsr;
GtkAction *layout_action;
ENTER("(action %p, plugin_page %p)", action, plugin_page);
g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(plugin_page));
gnc_split_reg_save_register_layout_to_user_state (gsr);
layout_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(plugin_page),
"WindowsResetLayoutAction");
gtk_action_set_sensitive (layout_action, TRUE);
LEAVE(" ");
}
static void
gnc_plugin_page_register_cmd_reset_layout (GtkAction *action, GncPluginPageRegister *plugin_page)
{
GNCSplitReg *gsr;
GtkAction *layout_action;
ENTER("(action %p, plugin_page %p)", action, plugin_page);
g_return_if_fail (GNC_IS_PLUGIN_PAGE_REGISTER(plugin_page));
gsr = gnc_plugin_page_register_get_gsr (GNC_PLUGIN_PAGE(plugin_page));
gnc_split_reg_reset_register_layout_and_clear_user_state (gsr);
layout_action = gnc_plugin_page_get_action (GNC_PLUGIN_PAGE(plugin_page),
"WindowsResetLayoutAction");
gtk_action_set_sensitive (layout_action, FALSE);
LEAVE(" ");
}
/************************************************************/
/* Auxiliary functions */
/************************************************************/

View File

@ -56,6 +56,7 @@
#include "gnucash-sheet.h"
#include "gnucash-register.h"
#include "table-allgui.h"
#include "gnc-state.h"
#include "dialog-utils.h"
@ -325,7 +326,8 @@ GtkWidget*
gnc_split_reg_new( GNCLedgerDisplay *ld,
GtkWindow *parent,
gint numberOfLines,
gboolean read_only )
gboolean read_only,
const gchar *group_name )
{
GNCSplitReg *gsrToRet;
@ -340,6 +342,8 @@ gnc_split_reg_new( GNCLedgerDisplay *ld,
gsrToRet->ledger = ld;
gsrToRet->window = GTK_WIDGET(parent);
gsrToRet->page_state_name = group_name;
gnc_split_reg_init2( gsrToRet );
LEAVE("%p", gsrToRet);
@ -359,6 +363,7 @@ gnc_split_reg_init( GNCSplitReg *gsr )
gsr->height = -1;
gsr->numRows = 10;
gsr->read_only = FALSE;
gsr->page_state_name = NULL;
}
static void
@ -402,6 +407,46 @@ gsr_setup_table( GNCSplitReg *gsr )
LEAVE(" ");
}
const gchar *
gnc_split_reg_get_register_state_group (GNCSplitReg *gsr)
{
SplitRegister *split_reg = gnc_ledger_display_get_split_register (gsr->ledger);
switch (gnc_split_register_get_register_group (split_reg))
{
case REG_TYPE_GROUP_CURRENCY:
{
return N_("Currency account registers");
break;
}
case REG_TYPE_GROUP_APAR:
{
return N_("Business account registers");
break;
}
case REG_TYPE_GROUP_JOURNAL:
{
return N_("Journal registers");
break;
}
case REG_TYPE_GROUP_STOCK:
{
return N_("Stock account registers");
break;
}
case REG_TYPE_GROUP_PORTFOLIO:
{
return N_("Portfolio registers");
break;
}
default:
{
return N_("Register group Unknown");
break;
}
}
}
static
void
gsr_create_table( GNCSplitReg *gsr )
@ -412,12 +457,31 @@ gsr_create_table( GNCSplitReg *gsr )
Account * account = gnc_ledger_display_leader(gsr->ledger);
const GncGUID * guid = xaccAccountGetGUID(account);
gchar guidstr[GUID_ENCODING_LENGTH+1];
const gchar *state_section = NULL;
guid_to_string_buff(guid, guidstr);
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
gchar *register_state_section;
const gchar *default_state_section;
const gchar *group;
guid_to_string_buff (guid, guidstr);
register_state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
ENTER("gsr=%p", gsr);
sr = gnc_ledger_display_get_split_register (gsr->ledger);
default_state_section = gnc_split_reg_get_register_state_group (gsr);
// if this is from a page recreate and no register state use those settings,
// register state is dropped at the end of function.
if (gsr->page_state_name && !g_key_file_has_group (gnc_state_get_current (), register_state_section))
group = gsr->page_state_name;
else
{
// if no default state, use register state if available
if (gnc_split_reg_register_has_user_state (gsr))
group = default_state_section;
else
group = register_state_section;
}
gnc_ledger_display_set_user_data( gsr->ledger, (gpointer)gsr );
gnc_ledger_display_set_handlers( gsr->ledger,
gnc_split_reg_ld_destroy,
@ -425,7 +489,7 @@ gsr_create_table( GNCSplitReg *gsr )
/* FIXME: We'd really rather pass this down... */
sr = gnc_ledger_display_get_split_register( gsr->ledger );
register_widget = gnucash_register_new( sr->table, state_section );
register_widget = gnucash_register_new( sr->table, group );
gsr->reg = GNUCASH_REGISTER( register_widget );
gtk_box_pack_start (GTK_BOX (gsr), GTK_WIDGET(gsr->reg), TRUE, TRUE, 0);
@ -440,6 +504,15 @@ gsr_create_table( GNCSplitReg *gsr )
g_signal_connect (gsr->reg, "show_popup_menu",
G_CALLBACK(gsr_emit_show_popup_menu), gsr);
// if no default state and register has state, copy it.
if (g_key_file_has_group (gnc_state_get_current (), register_state_section))
{
if (!gnc_split_reg_register_has_user_state (gsr))
gnc_table_save_state (sr->table, default_state_section, NULL);
// drop the register state
gnc_state_drop_sections_for (register_state_section);
}
g_free (register_state_section);
LEAVE(" ");
}
@ -721,37 +794,10 @@ gnc_split_reg_ld_destroy( GNCLedgerDisplay *ledger )
{
GNCSplitReg *gsr = gnc_ledger_display_get_user_data( ledger );
Account * account = gnc_ledger_display_leader(ledger);
const GncGUID * guid = xaccAccountGetGUID(account);
gchar guidstr[GUID_ENCODING_LENGTH+1];
gchar *state_section;
gchar *acct_fullname;
guid_to_string_buff(guid, guidstr);
state_section = g_strconcat (STATE_SECTION_REG_PREFIX, " ", guidstr, NULL);
if (g_strcmp0(guidstr, "00000000000000000000000000000000") == 0)
acct_fullname = g_strdup(_("General Journal"));
else
acct_fullname = gnc_account_get_full_name(account);
if (gsr)
{
SplitRegister *reg;
reg = gnc_ledger_display_get_split_register (ledger);
if (reg && reg->table)
gnc_table_save_state (reg->table, state_section, acct_fullname);
/*
* Don't destroy the window here any more. The register no longer
* owns it.
*/
}
g_free (state_section);
g_free (acct_fullname);
/*
* Don't destroy the window here any more. The register no longer
* owns it.
*/
gnc_ledger_display_set_user_data (ledger, NULL);
g_object_unref (gsr);
}
@ -1952,6 +1998,44 @@ gnc_split_reg_set_sheet_focus (GNCSplitReg *gsr, gboolean has_focus)
gnucash_sheet_set_has_focus (sheet, has_focus);
}
/* Save user state layout information to the register group that
* this register belongs to so it can be used as the default
* user layout
*/
void
gnc_split_reg_save_register_layout_to_user_state (GNCSplitReg *gsr)
{
SplitRegister *split_reg = gnc_ledger_display_get_split_register (gsr->ledger);
const gchar *group = gnc_split_reg_get_register_state_group (gsr);
gnc_table_save_state (split_reg->table, group, NULL);
}
/* Removes the user state layout information for the register group
* that this register belongs to and also resets the current layout to
* the built-in defaults
*/
void
gnc_split_reg_reset_register_layout_and_clear_user_state (GNCSplitReg *gsr)
{
GnucashRegister *reg = gsr->reg;
const gchar *group = gnc_split_reg_get_register_state_group (gsr);
gnucash_register_reset_sheet_layout (reg);
gnc_state_drop_sections_for (group);
}
/* Checks to see if there is user state layout information for the
* register group that this register belongs to.
*/
gboolean
gnc_split_reg_register_has_user_state (GNCSplitReg *gsr)
{
GKeyFile *state_file = gnc_state_get_current ();
const gchar *group = gnc_split_reg_get_register_state_group (gsr);
return g_key_file_has_group (state_file, group);
}
void
gnc_split_reg_balancing_entry(GNCSplitReg *gsr, Account *account,
time64 statement_date, gnc_numeric balancing_amount)

View File

@ -85,6 +85,8 @@ struct _GNCSplitReg
/** The actual gnucash register widget. **/
GnucashRegister *reg;
const gchar *page_state_name; /* Used for loading open state information */
gint numRows;
guint sort_type;
@ -179,11 +181,13 @@ GType gnc_split_reg_get_type(void);
* @param parent The containing window.
* @param numberOfLines The initial number of lines for the register.
* @param read_only If the contained register should be setup read-only.
* @param group_name The group name of the page state section for this page
**/
GtkWidget* gnc_split_reg_new( GNCLedgerDisplay *ld,
GtkWindow *parent,
gint numberOfLines,
gboolean read_only );
gboolean read_only,
const gchar *group_name );
/**
* Returns the GnucashRegister in effect for this GNCSplitReg.
@ -250,6 +254,14 @@ void gnc_split_reg_jump_to_split_amount(GNCSplitReg *gsr, Split *split);
void gnc_split_reg_focus_on_sheet (GNCSplitReg *gsr);
void gnc_split_reg_set_sheet_focus (GNCSplitReg *gsr, gboolean has_focus);
/**
* Save/Reset/Has functions used for the user default register layouts.
**/
void gnc_split_reg_save_register_layout_to_user_state (GNCSplitReg *gsr);
void gnc_split_reg_reset_register_layout_and_clear_user_state (GNCSplitReg *gsr);
gboolean gnc_split_reg_register_has_user_state (GNCSplitReg *gsr);
const gchar *gnc_split_reg_get_register_state_group (GNCSplitReg *gsr);
/*
* Create a transaction entry with given amount and date. One account is
* specified, the other is undefined i.e. it defaults to orphan account.

View File

@ -66,6 +66,13 @@
<menuitem name="ReportsAcctTransReport" action="ReportsAcctTransReportAction"/>
</placeholder>
</menu>
<menu name="Windows" action="WindowsAction">
<placeholder name="WindowsLayoutPlaceholder">
<menuitem name="WindowsSaveLayout" action="WindowsSaveLayoutAction"/>
<menuitem name="WindowsResetLayout" action="WindowsResetLayoutAction"/>
</placeholder>
</menu>
</menubar>
<toolbar name="DefaultToolbar">