diff options
-rw-r--r-- | divelist.c | 99 | ||||
-rw-r--r-- | divelist.h | 2 | ||||
-rw-r--r-- | gtk-gui.c | 19 |
3 files changed, 120 insertions, 0 deletions
diff --git a/divelist.c b/divelist.c index 2a6829e27..2240ff40e 100644 --- a/divelist.c +++ b/divelist.c @@ -2627,3 +2627,102 @@ void remove_autogen_trips() remove_dive_from_trip(dive); } } + +struct iteridx { + int idx; + GtkTreeIter *iter; +}; + +static gboolean iter_has_idx(GtkTreeModel *model, GtkTreePath *path, + GtkTreeIter *iter, gpointer _data) +{ + struct iteridx *iteridx = _data; + int idx; + /* Get the dive number */ + gtk_tree_model_get(model, iter, DIVE_INDEX, &idx, -1); + if (idx == iteridx->idx) { + iteridx->iter = gtk_tree_iter_copy(iter); + return TRUE; /* end foreach */ + } + return FALSE; +} + +static GtkTreeIter *get_iter_from_idx(int idx) +{ + struct iteridx iteridx = {idx, }; + gtk_tree_model_foreach(MODEL(dive_list), iter_has_idx, &iteridx); + return iteridx.iter; +} + +void select_next_dive(void) +{ + GtkTreeIter *nextiter; + GtkTreeIter *iter = get_iter_from_idx(selected_dive); + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view)); + GtkTreePath *treepath; + int idx; + + if (!iter) + return; + nextiter = gtk_tree_iter_copy(iter); + if (!gtk_tree_model_iter_next(MODEL(dive_list), nextiter)) { + if (!gtk_tree_model_iter_parent(MODEL(dive_list), nextiter, iter)) + /* we're at the last top level node */ + return; + if (!gtk_tree_model_iter_next(MODEL(dive_list), nextiter)) + /* last trip */ + return; + gtk_tree_model_get(MODEL(dive_list), nextiter, DIVE_INDEX, &idx, -1); + if (idx < 0) { + /* need the first child */ + GtkTreeIter *parent = gtk_tree_iter_copy(nextiter); + if (! gtk_tree_model_iter_children(MODEL(dive_list), nextiter, parent)) + return; + } + } + treepath = gtk_tree_model_get_path(MODEL(dive_list), nextiter); + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath); + gtk_tree_selection_select_iter(selection, nextiter); + gtk_tree_selection_unselect_iter(selection, iter); + gtk_tree_path_free(treepath); +} + +void select_prev_dive(void) +{ + GtkTreeIter previter; + GtkTreeIter *iter = get_iter_from_idx(selected_dive); + GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(dive_list.tree_view)); + GtkTreePath *treepath; + int idx; + + if (!iter) + return; + treepath = gtk_tree_model_get_path(MODEL(dive_list), iter); + if (!gtk_tree_path_prev(treepath)) { + if (!gtk_tree_model_iter_parent(MODEL(dive_list), &previter, iter)) + /* we're at the last top level node */ + return; + treepath = gtk_tree_model_get_path(MODEL(dive_list), &previter); + if (!gtk_tree_path_prev(treepath)) + /* first trip */ + return; + if (!gtk_tree_model_get_iter(MODEL(dive_list), &previter, treepath)) + return; + gtk_tree_model_get(MODEL(dive_list), &previter, DIVE_INDEX, &idx, -1); + if (idx < 0) { + /* need the last child */ + GtkTreeIter *parent = gtk_tree_iter_copy(&previter); + if (! gtk_tree_model_iter_nth_child(MODEL(dive_list), &previter, parent, + gtk_tree_model_iter_n_children(MODEL(dive_list), parent) - 1)) + return; + } + treepath = gtk_tree_model_get_path(MODEL(dive_list), &previter); + } else { + if (!gtk_tree_model_get_iter(MODEL(dive_list), &previter, treepath)) + return; + } + gtk_tree_view_expand_to_path(GTK_TREE_VIEW(dive_list.tree_view), treepath); + gtk_tree_selection_select_iter(selection, &previter); + gtk_tree_selection_unselect_iter(selection, iter); + gtk_tree_path_free(treepath); +} diff --git a/divelist.h b/divelist.h index 0a635c2ed..b309e9a54 100644 --- a/divelist.h +++ b/divelist.h @@ -13,4 +13,6 @@ extern int unsaved_changes(void); extern void remove_autogen_trips(void); extern void remember_tree_state(void); extern void restore_tree_state(void); +extern void select_next_dive(void); +extern void select_prev_dive(void); #endif @@ -5,6 +5,7 @@ */ #include <libintl.h> #include <glib/gi18n.h> +#include <gdk/gdkkeysyms.h> #include <stdio.h> #include <string.h> #include <stdlib.h> @@ -1130,6 +1131,21 @@ static void switch_page(GtkNotebook *notebook, gint arg1, gpointer user_data) repaint_dive(); } +static gboolean on_key_press(GtkWidget *w, GdkEventKey *event, GtkWidget *divelist) +{ + if (event->type != GDK_KEY_PRESS) + return FALSE; + switch (event->keyval) { + case GDK_KEY_Up: + select_prev_dive(); + return TRUE; + case GDK_KEY_Down: + select_next_dive(); + return TRUE; + } + return FALSE; +} + void init_ui(int *argcp, char ***argvp) { GtkWidget *win; @@ -1325,6 +1341,9 @@ void init_ui(int *argcp, char ***argvp) nb_page = total_stats_widget(); gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new(_("Stats"))); + /* handle some keys globally (to deal with gtk focus issues) */ + g_signal_connect (G_OBJECT (win), "key_press_event", G_CALLBACK (on_key_press), dive_list); + gtk_widget_set_app_paintable(win, TRUE); gtk_widget_show_all(win); |