summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--divelist.c99
-rw-r--r--divelist.h2
-rw-r--r--gtk-gui.c19
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
diff --git a/gtk-gui.c b/gtk-gui.c
index a6ed46942..f241fd313 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -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);