mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Implement a keynav policy for the budget page. Addresses bug #339515.
git-svn-id: svn+ssh://svn.gnucash.org/repo/gnucash/trunk@13847 57a11ea4-9604-0410-9ed3-97b8803252fd
This commit is contained in:
parent
5179270a50
commit
a6644b75fc
@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include <gtk/gtk.h>
|
#include <gtk/gtk.h>
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
#include <gdk/gdkkeysyms.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "gnc-tree-view.h"
|
#include "gnc-tree-view.h"
|
||||||
@ -2084,4 +2085,98 @@ gnc_tree_view_append_column (GncTreeView *view,
|
|||||||
return gtk_tree_view_insert_column (GTK_TREE_VIEW(view), column, n);
|
return gtk_tree_view_insert_column (GTK_TREE_VIEW(view), column, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
get_column_next_to(GtkTreeView *tv, GtkTreeViewColumn **col, gboolean backward)
|
||||||
|
{
|
||||||
|
GList *cols, *node;
|
||||||
|
GtkTreeViewColumn *c = NULL;
|
||||||
|
gint seen = 0;
|
||||||
|
gboolean wrapped = FALSE;
|
||||||
|
|
||||||
|
cols = gtk_tree_view_get_columns(tv);
|
||||||
|
g_return_val_if_fail(g_list_length(cols) > 0, FALSE);
|
||||||
|
|
||||||
|
node = g_list_find(cols, *col);
|
||||||
|
g_return_val_if_fail(node, FALSE);
|
||||||
|
do {
|
||||||
|
node = backward ? node->prev : node->next;
|
||||||
|
if (!node) {
|
||||||
|
wrapped = TRUE;
|
||||||
|
node = backward ? g_list_last(cols) : cols;
|
||||||
|
}
|
||||||
|
c = GTK_TREE_VIEW_COLUMN(node->data);
|
||||||
|
if (c && gtk_tree_view_column_get_visible(c))
|
||||||
|
seen++;
|
||||||
|
if (c == *col) break;
|
||||||
|
} while (!seen);
|
||||||
|
|
||||||
|
g_list_free(cols);
|
||||||
|
*col = c;
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
gnc_tree_view_path_is_valid(GncTreeView *view, GtkTreePath *path)
|
||||||
|
{
|
||||||
|
GtkTreeView *tv = GTK_TREE_VIEW(view);
|
||||||
|
GtkTreeModel *s_model;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
s_model = gtk_tree_view_get_model(tv);
|
||||||
|
return gtk_tree_model_get_iter(s_model, &iter, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
gnc_tree_view_keynav(GncTreeView *view, GtkTreeViewColumn **col,
|
||||||
|
GtkTreePath *path, GdkEventKey *event)
|
||||||
|
{
|
||||||
|
GtkTreeView *tv = GTK_TREE_VIEW(view);
|
||||||
|
gint depth;
|
||||||
|
gboolean shifted;
|
||||||
|
|
||||||
|
if (event->type != GDK_KEY_PRESS) return;
|
||||||
|
|
||||||
|
switch (event->keyval) {
|
||||||
|
case GDK_Tab:
|
||||||
|
case GDK_ISO_Left_Tab:
|
||||||
|
case GDK_KP_Tab:
|
||||||
|
shifted = event->state & GDK_SHIFT_MASK;
|
||||||
|
if (get_column_next_to(tv, col, shifted)) {
|
||||||
|
/* This is the end (or beginning) of the line, buddy. */
|
||||||
|
depth = gtk_tree_path_get_depth(path);
|
||||||
|
if (shifted) {
|
||||||
|
if (!gtk_tree_path_prev(path) && depth > 1) {
|
||||||
|
gtk_tree_path_up(path);
|
||||||
|
}
|
||||||
|
} else if (gtk_tree_view_row_expanded(tv, path)) {
|
||||||
|
gtk_tree_path_down(path);
|
||||||
|
} else {
|
||||||
|
gtk_tree_path_next(path);
|
||||||
|
if (!gnc_tree_view_path_is_valid(view, path) && depth > 1) {
|
||||||
|
gtk_tree_path_prev(path);
|
||||||
|
gtk_tree_path_up(path);
|
||||||
|
gtk_tree_path_next(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GDK_Return:
|
||||||
|
case GDK_KP_Enter:
|
||||||
|
if (gtk_tree_view_row_expanded(tv, path)) {
|
||||||
|
gtk_tree_path_down(path);
|
||||||
|
} else {
|
||||||
|
gtk_tree_path_next(path);
|
||||||
|
if (!gnc_tree_view_path_is_valid(view, path) && depth > 1) {
|
||||||
|
gtk_tree_path_prev(path);
|
||||||
|
gtk_tree_path_up(path);
|
||||||
|
gtk_tree_path_next(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -369,6 +369,19 @@ gnc_tree_view_get_show_column_menu (GncTreeView *view);
|
|||||||
GtkCellRenderer *
|
GtkCellRenderer *
|
||||||
gnc_tree_view_column_get_renderer(GtkTreeViewColumn *column);
|
gnc_tree_view_column_get_renderer(GtkTreeViewColumn *column);
|
||||||
|
|
||||||
|
|
||||||
|
/* Takes a GdkEventKey and the current path and column for the
|
||||||
|
* treeview. Interprets the event as something that might move the
|
||||||
|
* cursor. Returns the new column and the possibly changed (if
|
||||||
|
* navigation wrapped a row) path. */
|
||||||
|
void
|
||||||
|
gnc_tree_view_keynav(GncTreeView *view, GtkTreeViewColumn **col,
|
||||||
|
GtkTreePath *path, GdkEventKey *event);
|
||||||
|
|
||||||
|
/* Returns TRUE if path is a vaid path for the treeview */
|
||||||
|
gboolean
|
||||||
|
gnc_tree_view_path_is_valid(GncTreeView *view, GtkTreePath *path);
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
@ -95,12 +95,14 @@ static GncPluginPage *gnc_plugin_page_budget_recreate_page (
|
|||||||
GtkWidget *window, GKeyFile *file, const gchar *group);
|
GtkWidget *window, GKeyFile *file, const gchar *group);
|
||||||
|
|
||||||
|
|
||||||
static gboolean gnc_plugin_page_budget_button_press_cb(
|
static gboolean gppb_button_press_cb(
|
||||||
GtkWidget *widget, GdkEventButton *event, GncPluginPage *page);
|
GtkWidget *widget, GdkEventButton *event, GncPluginPage *page);
|
||||||
static void gnc_plugin_page_budget_double_click_cb(
|
static gboolean gppb_key_press_cb(
|
||||||
|
GtkWidget *treeview, GdkEventKey *event, gpointer userdata);
|
||||||
|
static void gppb_double_click_cb(
|
||||||
GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col,
|
GtkTreeView *treeview, GtkTreePath *path, GtkTreeViewColumn *col,
|
||||||
GncPluginPageBudget *page);
|
GncPluginPageBudget *page);
|
||||||
static void gnc_plugin_page_budget_selection_changed_cb(
|
static void gppb_selection_changed_cb(
|
||||||
GtkTreeSelection *selection, GncPluginPageBudget *page);
|
GtkTreeSelection *selection, GncPluginPageBudget *page);
|
||||||
|
|
||||||
static void gnc_plugin_page_budget_view_refresh (GncPluginPageBudget *page);
|
static void gnc_plugin_page_budget_view_refresh (GncPluginPageBudget *page);
|
||||||
@ -394,17 +396,16 @@ gnc_plugin_page_budget_create_widget (GncPluginPage *plugin_page)
|
|||||||
selection = gtk_tree_view_get_selection(tree_view);
|
selection = gtk_tree_view_get_selection(tree_view);
|
||||||
gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
|
gtk_tree_selection_set_mode(selection, GTK_SELECTION_MULTIPLE);
|
||||||
|
|
||||||
g_signal_connect (G_OBJECT (selection), "changed",
|
g_signal_connect(G_OBJECT(selection), "changed",
|
||||||
G_CALLBACK (gnc_plugin_page_budget_selection_changed_cb),
|
G_CALLBACK(gppb_selection_changed_cb), plugin_page);
|
||||||
plugin_page);
|
g_signal_connect(G_OBJECT(tree_view), "button-press-event",
|
||||||
g_signal_connect (G_OBJECT (tree_view), "button-press-event",
|
G_CALLBACK(gppb_button_press_cb), plugin_page);
|
||||||
G_CALLBACK (gnc_plugin_page_budget_button_press_cb),
|
g_signal_connect(G_OBJECT(tree_view), "row-activated",
|
||||||
plugin_page);
|
G_CALLBACK(gppb_double_click_cb), page);
|
||||||
g_signal_connect (G_OBJECT (tree_view), "row-activated",
|
g_signal_connect_after(G_OBJECT(tree_view), "key-press-event",
|
||||||
G_CALLBACK (gnc_plugin_page_budget_double_click_cb),
|
G_CALLBACK(gppb_key_press_cb), NULL);
|
||||||
page);
|
|
||||||
|
|
||||||
gnc_plugin_page_budget_selection_changed_cb (NULL, page);
|
gppb_selection_changed_cb (NULL, page);
|
||||||
gtk_tree_view_set_headers_visible(tree_view, TRUE);
|
gtk_tree_view_set_headers_visible(tree_view, TRUE);
|
||||||
gtk_widget_show (GTK_WIDGET (tree_view));
|
gtk_widget_show (GTK_WIDGET (tree_view));
|
||||||
gtk_container_add (GTK_CONTAINER (scrolled_window),
|
gtk_container_add (GTK_CONTAINER (scrolled_window),
|
||||||
@ -564,9 +565,8 @@ gnc_plugin_page_budget_recreate_page (GtkWidget *window, GKeyFile *key_file,
|
|||||||
* Button presses on all other pages are caught by the signal
|
* Button presses on all other pages are caught by the signal
|
||||||
* registered in gnc-main-window.c. */
|
* registered in gnc-main-window.c. */
|
||||||
static gboolean
|
static gboolean
|
||||||
gnc_plugin_page_budget_button_press_cb (GtkWidget *widget,
|
gppb_button_press_cb(GtkWidget *widget, GdkEventButton *event,
|
||||||
GdkEventButton *event,
|
GncPluginPage *page)
|
||||||
GncPluginPage *page)
|
|
||||||
{
|
{
|
||||||
gboolean result;
|
gboolean result;
|
||||||
|
|
||||||
@ -578,11 +578,36 @@ gnc_plugin_page_budget_button_press_cb (GtkWidget *widget,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gppb_key_press_cb(GtkWidget *treeview, GdkEventKey *event, gpointer userdata)
|
||||||
|
{
|
||||||
|
GtkTreeView *tv = GTK_TREE_VIEW(treeview);
|
||||||
|
GtkTreeViewColumn *col;
|
||||||
|
GtkTreePath *path = NULL;
|
||||||
|
|
||||||
|
if (event->type != GDK_KEY_PRESS) return TRUE;
|
||||||
|
|
||||||
|
switch (event->keyval) {
|
||||||
|
case GDK_Tab:
|
||||||
|
case GDK_ISO_Left_Tab:
|
||||||
|
case GDK_KP_Tab:
|
||||||
|
case GDK_Return:
|
||||||
|
case GDK_KP_Enter:
|
||||||
|
gtk_tree_view_get_cursor(tv, &path, &col);
|
||||||
|
if (!path) return TRUE;
|
||||||
|
//finish_edit(col);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
gnc_tree_view_keynav(GNC_TREE_VIEW(tv), &col, path, event);
|
||||||
|
|
||||||
|
if (path && gnc_tree_view_path_is_valid(GNC_TREE_VIEW(tv), path))
|
||||||
|
gtk_tree_view_set_cursor(tv, path, col, TRUE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnc_plugin_page_budget_double_click_cb (GtkTreeView *treeview,
|
gppb_double_click_cb(GtkTreeView *treeview, GtkTreePath *path,
|
||||||
GtkTreePath *path,
|
GtkTreeViewColumn *col, GncPluginPageBudget *page)
|
||||||
GtkTreeViewColumn *col,
|
|
||||||
GncPluginPageBudget *page)
|
|
||||||
{
|
{
|
||||||
GtkWidget *window;
|
GtkWidget *window;
|
||||||
GncPluginPage *new_page;
|
GncPluginPage *new_page;
|
||||||
@ -600,8 +625,8 @@ gnc_plugin_page_budget_double_click_cb (GtkTreeView *treeview,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gnc_plugin_page_budget_selection_changed_cb (GtkTreeSelection *selection,
|
gppb_selection_changed_cb(GtkTreeSelection *selection,
|
||||||
GncPluginPageBudget *page)
|
GncPluginPageBudget *page)
|
||||||
{
|
{
|
||||||
GtkActionGroup *action_group;
|
GtkActionGroup *action_group;
|
||||||
GtkTreeView *view;
|
GtkTreeView *view;
|
||||||
@ -628,7 +653,6 @@ gnc_plugin_page_budget_selection_changed_cb (GtkTreeSelection *selection,
|
|||||||
"sensitive", sensitive);
|
"sensitive", sensitive);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Command callbacks */
|
/* Command callbacks */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
Loading…
Reference in New Issue
Block a user