Bug 436105 - esc key not working as expected in register

This patch enables the use of the Escape key to cancel an edit of a field in a transaction or a split restoring the value the field held when the user navigated to the transaction or split.
This commit is contained in:
Sherlock authored and John Ralls committed 2026-05-08 15:05:12 -07:00
1 parent d1117549e7
commit 99822a16c8
10 files changed
+204 -57

No files matched your search

@@ -54,6 +54,22 @@ gnc_cell_name_equal (const char * cell_name_1,
return (g_strcmp0 (cell_name_1, cell_name_2) == 0);
}
static void
gnc_basic_cell_gui_realize (BasicCell* bcell, gpointer data)
{
bcell->gui_private = data;
bcell->gui_realize = NULL;
}
static void
gnc_basic_cell_gui_destroy (BasicCell* bcell)
{
if (bcell->gui_realize == NULL)
{
bcell->gui_realize = gnc_basic_cell_gui_realize;
}
}
BasicCell *
gnc_basic_cell_new (void)
{
@@ -101,6 +117,9 @@ gnc_basic_cell_init (BasicCell *cell)
{
gnc_basic_cell_clear (cell);
cell->gui_realize = gnc_basic_cell_gui_realize;
cell->gui_destroy = gnc_basic_cell_gui_destroy;
cell->value = g_strdup ("");
}
+52 -47
View File
@@ -242,59 +242,58 @@ gnc_table_get_header_cell (Table *table)
}
static const char *
gnc_table_get_entry_internal (Table *table, VirtualLocation virt_loc,
gboolean *conditionally_changed)
table_get_model_entry (Table *table, VirtualLocation virt_loc,
gboolean translate, gboolean *conditionally_changed, const char *cell_name)
{
TableGetEntryHandler entry_handler;
const char *cell_name;
const char *entry;
TableGetEntryHandler entry_handler = gnc_table_model_get_entry_handler (
table->model, cell_name);
cell_name = gnc_table_get_cell_name (table, virt_loc);
if (entry_handler)
{
const char *entry = entry_handler (virt_loc, translate, conditionally_changed,
table->model->handler_user_data);
if (entry)
return entry;
}
entry_handler = gnc_table_model_get_entry_handler (table->model, cell_name);
if (!entry_handler) return "";
return "";
}
entry = entry_handler (virt_loc, FALSE,
conditionally_changed,
table->model->handler_user_data);
if (!entry)
entry = "";
static const char *
table_get_entry (Table *table, VirtualLocation virt_loc,
gboolean *conditionally_changed)
{
const char *cell_name = gnc_table_get_cell_name (table, virt_loc);
return entry;
return table_get_model_entry (table, virt_loc, FALSE, conditionally_changed,
cell_name);
}
const char *
gnc_table_get_entry (Table *table, VirtualLocation virt_loc)
{
TableGetEntryHandler entry_handler;
const char *entry;
BasicCell *cell;
BasicCell *cell = gnc_table_get_cell (table, virt_loc);
cell = gnc_table_get_cell (table, virt_loc);
if (!cell || !cell->cell_name)
return "";
if (virt_cell_loc_equal (table->current_cursor_loc.vcell_loc,
virt_loc.vcell_loc))
{
CellIOFlags io_flags;
io_flags = gnc_table_get_io_flags (table, virt_loc);
CellIOFlags io_flags = gnc_table_get_io_flags (table, virt_loc);
if (io_flags & XACC_CELL_ALLOW_INPUT)
return cell->value;
}
entry_handler = gnc_table_model_get_entry_handler (table->model,
cell->cell_name);
if (!entry_handler) return "";
return table_get_model_entry (table, virt_loc, TRUE, NULL, cell->cell_name);
}
entry = entry_handler (virt_loc, TRUE, NULL,
table->model->handler_user_data);
if (!entry)
entry = "";
return entry;
const char *
gnc_table_get_model_entry (Table *table, const char *cell_name)
{
return table_get_model_entry (table, table->current_cursor_loc, TRUE, NULL,
cell_name);
}
char *
@@ -307,8 +306,8 @@ gnc_table_get_tooltip (Table *table, VirtualLocation virt_loc)
if (!cell || !cell->cell_name)
return NULL;
tooltip_handler = gnc_table_model_get_tooltip_handler (table->model,
cell->cell_name);
tooltip_handler =
gnc_table_model_get_tooltip_handler (table->model, cell->cell_name);
if (!tooltip_handler)
return NULL;
@@ -328,8 +327,8 @@ gnc_table_get_io_flags (Table *table, VirtualLocation virt_loc)
cell_name = gnc_table_get_cell_name (table, virt_loc);
io_flags_handler = gnc_table_model_get_io_flags_handler (table->model,
cell_name);
io_flags_handler =
gnc_table_model_get_io_flags_handler (table->model, cell_name);
if (!io_flags_handler)
return XACC_CELL_ALLOW_NONE;
@@ -366,7 +365,7 @@ gnc_table_get_label (Table *table, VirtualLocation virt_loc)
guint32
gnc_table_get_color (Table *table, VirtualLocation virt_loc,
gboolean *hatching)
gboolean *hatching)
{
TableGetCellColorHandler color_handler;
const char *handler_name;
@@ -379,8 +378,8 @@ gnc_table_get_color (Table *table, VirtualLocation virt_loc,
handler_name = gnc_table_get_cell_name (table, virt_loc);
color_handler = gnc_table_model_get_cell_color_handler (table->model,
handler_name);
color_handler =
gnc_table_model_get_cell_color_handler (table->model, handler_name);
if (!color_handler)
return COLOR_UNDEFINED;
@@ -401,8 +400,8 @@ gnc_table_get_borders (Table *table, VirtualLocation virt_loc,
cell_name = gnc_table_get_cell_name (table, virt_loc);
cell_border_handler = gnc_table_model_get_cell_border_handler (table->model,
cell_name);
cell_border_handler =
gnc_table_model_get_cell_border_handler (table->model, cell_name);
if (!cell_border_handler)
return;
@@ -860,8 +859,8 @@ gnc_table_move_cursor_internal (Table *table,
const char *entry;
gboolean conditionally_changed = FALSE;
entry = gnc_table_get_entry_internal (table, virt_loc,
&conditionally_changed);
entry = table_get_entry (table, virt_loc,
&conditionally_changed);
gnc_basic_cell_set_value (cell, entry);
@@ -1333,16 +1332,21 @@ gnc_table_direct_update (Table *table,
ENTER ("");
if (cell->direct_update == NULL)
gboolean changed = cell->changed;
old_value = g_strdup (cell->value);
CellDirectUpdateFunc du = cell->direct_update;
if (du == NULL)
du = table->gui_handlers.default_direct_update;
if (du == NULL)
{
LEAVE("no direct update");
return FALSE;
}
old_value = g_strdup (cell->value);
result = cell->direct_update (cell, cursor_position, start_selection,
end_selection, gui_data);
result = du (cell, cursor_position, start_selection, end_selection, gui_data);
if (g_strcmp0 (old_value, cell->value) != 0)
{
@@ -1354,7 +1358,8 @@ gnc_table_direct_update (Table *table,
}
else
{
cell->changed = TRUE;
if (!changed)
cell->changed = TRUE;
*newval_ptr = cell->value;
}
}
@@ -154,6 +154,8 @@ typedef struct
TableRedrawHelpCB redraw_help;
TableDestroyCB destroy;
CellDirectUpdateFunc default_direct_update;
} TableGUIHandlers;
struct table
@@ -267,6 +269,8 @@ gboolean gnc_table_get_cell_location (Table *table,
VirtualCellLocation vcell_loc,
VirtualLocation *virt_loc);
const char * gnc_table_get_model_entry (Table *table, const char *cell_name);
void gnc_table_save_cells (Table *table, gpointer save_data);
@@ -560,7 +560,8 @@ gnc_combo_cell_type_ahead_search (const gchar* newval,
gtk_list_store_clear (box->tmp_store);
unblock_list_signals (cell);
if (strlen (newval) == 0) {
if (strlen (newval) == 0)
{
/* Deleting everything in the cell shouldn't provide a search result for
* "" because that will just be the first MAX_NUM_MATCHES accounts which
* isn't very useful.
@@ -737,6 +738,27 @@ gnc_combo_cell_direct_update (BasicCell* bcell,
unicode_value = gdk_keyval_to_unicode (event->keyval);
switch (event->keyval)
{
case GDK_KEY_Escape:
if (bcell->changed)
{
const char *value = gnc_table_get_model_entry (box->sheet->table, bcell->cell_name);
if (cell->shared_store && gnc_item_list_using_temp (box->item_list))
{
gnc_item_list_set_temp_store (box->item_list, NULL);
gtk_list_store_clear (box->tmp_store);
}
gnc_basic_cell_set_value_internal (bcell, value);
bcell->changed = FALSE;
block_list_signals (cell);
gnc_item_list_select (box->item_list, value);
unblock_list_signals (cell);
*cursor_position = -1;
*start_selection = 0;
*end_selection = -1;
return TRUE;
}
break;
case GDK_KEY_slash:
if (! (event->state & GDK_MOD1_MASK))
{
@@ -757,8 +779,7 @@ gnc_combo_cell_direct_update (BasicCell* bcell,
g_free (string);
return FALSE;
}
if (! (event->state & GDK_CONTROL_MASK) &&
!keep_on_going)
if (! (event->state & GDK_CONTROL_MASK) && !keep_on_going)
return FALSE;
match = gnc_quickfill_get_string_len_match
@@ -765,6 +765,19 @@ gnc_completion_cell_direct_update (BasicCell* bcell,
switch (event->keyval)
{
case GDK_KEY_Escape:
if (bcell->changed)
{
const char *value = gnc_table_get_model_entry (box->sheet->table, bcell->cell_name);
gnc_basic_cell_set_value_internal (bcell, value);
bcell->changed = FALSE;
*cursor_position = 0;
*start_selection = 0;
*end_selection = -1;
return TRUE;
}
break;
case GDK_KEY_Tab:
case GDK_KEY_ISO_Left_Tab:
{
@@ -499,6 +499,22 @@ gnc_date_cell_direct_update (BasicCell *bcell,
GdkEventKey *event = gui_data;
char buff[DATE_BUF];
if (event->keyval == GDK_KEY_Escape)
{
if (bcell->changed)
{
const char *value = gnc_table_get_model_entry (box->sheet->table, bcell->cell_name);
gnc_basic_cell_set_value_internal (bcell, value);
bcell->changed = FALSE;
*cursor_position = 0;
*start_selection = 0;
*end_selection = -1;
return TRUE;
}
return FALSE;
}
if (!gnc_handle_date_accelerator (event, &(box->date), bcell->value))
return FALSE;
@@ -39,6 +39,9 @@
#include "formulacell.h"
#include "formulacell-gnome.h"
#include "pricecell-gnome.h"
#include "gnucash-sheet.h"
#include "gnucash-sheetP.h"
#include "table-allgui.h"
#ifdef G_OS_WIN32
# include <gdk/gdkwin32.h>
@@ -74,6 +77,21 @@ gnc_formula_cell_direct_update( BasicCell *bcell,
switch (event->keyval)
{
case GDK_KEY_Escape:
if (bcell->changed)
{
GnucashSheet *sheet = (GnucashSheet *) bcell->gui_private;
const char *value = gnc_table_get_model_entry (sheet->table, bcell->cell_name);
gnc_basic_cell_set_value_internal (bcell, value);
bcell->changed = FALSE;
*cursor_position = 0;
*start_selection = 0;
*end_selection = -1;
return TRUE;
}
return FALSE;
case GDK_KEY_Return:
if (!(event->state &
(GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK)))
@@ -36,6 +36,9 @@
#include "gnc-ui-util.h"
#include "pricecell.h"
#include "pricecell-gnome.h"
#include "gnucash-sheet.h"
#include "gnucash-sheetP.h"
#include "table-allgui.h"
#ifdef G_OS_WIN32
# include <gdk/gdkwin32.h>
@@ -62,6 +65,21 @@ gnc_price_cell_direct_update (BasicCell *bcell,
switch (event->keyval)
{
case GDK_KEY_Escape:
if (bcell->changed)
{
GnucashSheet *sheet = (GnucashSheet *) bcell->gui_private;
const char *value = gnc_table_get_model_entry (sheet->table, bcell->cell_name);
gnc_basic_cell_set_value_internal (bcell, value);
bcell->changed = FALSE;
*cursor_position = 0;
*start_selection = 0;
*end_selection = -1;
return TRUE;
}
return FALSE;
case GDK_KEY_Return:
if (!(event->state &
(GDK_MODIFIER_INTENT_DEFAULT_MOD_MASK)))
@@ -34,6 +34,9 @@
#include "quickfillcell.h"
#include "quickfillcell-gnome.h"
#include "gnucash-sheet.h"
#include "gnucash-sheetP.h"
#include "table-allgui.h"
static gboolean
@@ -54,6 +57,20 @@ gnc_quickfill_cell_direct_update (BasicCell *bcell,
switch (event->keyval)
{
case GDK_KEY_Escape:
if (bcell->changed)
{
GnucashSheet *sheet = (GnucashSheet *) bcell->gui_private;
const char *value = gnc_table_get_model_entry (sheet->table, bcell->cell_name);
gnc_basic_cell_set_value_internal (bcell, value);
bcell->changed = FALSE;
*cursor_position = 0;
*start_selection = 0;
*end_selection = -1;
return TRUE;
}
return FALSE;
case GDK_KEY_slash:
if (!(event->state & GDK_MOD1_MASK))
return FALSE;
+23 -7
View File
@@ -145,20 +145,36 @@ table_destroy_cb (Table *table)
table->ui_data = NULL;
}
static gboolean
table_default_direct_update (BasicCell *bcell,
int *cursor_position,
int *start_selection,
int *end_selection,
void *gui_data)
{
GdkEventKey *event = gui_data;
/* Um, this function checks that data is not null but never uses it.
Weird. Also, since this function only works with a GnucashRegister
widget, maybe some of it should be moved to gnucash-sheet.c. */
/* Adding to previous note: Since data doesn't appear do anything and to
align the function with save_state() I've removed the check for
NULL and changed two calls in dialog_order.c and dialog_invoice.c
to pass NULL as second parameter. */
if (event->keyval == GDK_KEY_Escape && bcell->changed)
{
GnucashSheet *sheet = (GnucashSheet *) bcell->gui_private;
const char *value = gnc_table_get_model_entry (sheet->table, bcell->cell_name);
gnc_basic_cell_set_value_internal (bcell, value);
bcell->changed = FALSE;
*cursor_position = 0;
*start_selection = 0;
*end_selection = -1;
return TRUE;
}
return FALSE;
}
void
gnc_table_init_gui (Table *table)
{
table->gui_handlers.redraw_help = table_ui_redraw_cb;
table->gui_handlers.destroy = table_destroy_cb;
table->gui_handlers.default_direct_update = table_default_direct_update;
}
void