kee

Offline IOU signer with QR as transport
git clone https://holbrook.no/src/kee
Info | Log | Files | Refs | README | LICENSE

commit 9eb5c0e41d3f49d1581b8974572a80f790bd722c
parent 5de2d1091c5095a8da40712baed63e9f82414be0
Author: lash <dev@holbrook.no>
Date:   Sat, 30 Mar 2024 12:06:12 +0000

Implement entry view, simplify nav

Diffstat:
MMakefile | 8++++----
MREADME.md | 2+-
Msrc/gtk/kee-entry-list.c | 48+++++++++++++++++++++++++++++++++++++++---------
Msrc/gtk/kee-entry-list.h | 4+++-
Msrc/gtk/kee-entry.c | 17+++++++++++++++++
Msrc/gtk/kee-entry.h | 1+
Msrc/gtk/kee-menu.c | 25++++++++++++++++++++-----
Msrc/gtk/kee-menu.h | 2+-
Msrc/gtk/nav.c | 78++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------
Msrc/gtk/nav.h | 6+++++-
Msrc/gtk/scan.c | 1+
Msrc/gtk/tests/Makefile | 6++++--
Msrc/gtk/tests/nav.c | 19++++++++++++++++---
Msrc/gtk/ui.c | 5++++-
Msrc/tests/Makefile | 6++++--
Msrc/tests/cadir.c | 4+++-
16 files changed, 185 insertions(+), 47 deletions(-)

diff --git a/Makefile b/Makefile @@ -15,18 +15,18 @@ clean: make -C src clean run: gtk all - G_MESSAGES_DEBUG=all ./src/gtk/a.out + G_DEBUG=3 G_MESSAGES_DEBUG=all ./src/gtk/a.out debug: gtk all - G_DEBUG=all G_MESSAGES_DEBUG=all ./src/gtk/a.out + G_DEBUG=all G_MESSAGES_DEBUG=all gdb ./src/gtk/a.out #test: gtk all test_src test_gtk -test: test_src +test: test_src test_gtk test_src: all make -C src/tests test -test_gtk: gtk all test_src +test_gtk: gtk all make -C src/gtk/tests test testdata: diff --git a/README.md b/README.md @@ -102,7 +102,7 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/lash/src/build/varint.c/0.1.0:/hom export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/home/lash/src/build/libcmime/0.2.2/build/usr/local/lib64/pkgconfig export C_INCLUDE_PATH=$C_INCLUDE_PATH:/home/lash/src/build/varint.c/0.1.0:/home/lash/src/build/libcmime/0.2.2/build/usr/local/include -make debug +make run set +x ``` diff --git a/src/gtk/kee-entry-list.c b/src/gtk/kee-entry-list.c @@ -3,6 +3,7 @@ #include "kee-entry-list.h" #include "kee-entry.h" +#include "kee-menu.h" #include "err.h" typedef struct { @@ -16,20 +17,48 @@ struct _KeeEntryList { G_DEFINE_TYPE(KeeEntryList, kee_entry_list, GTK_TYPE_BOX); -static void kee_entry_handle_setup(KeeEntryList* o, GtkListItem *item) { +static void kee_entry_list_handle_select(GtkListView *view, guint i, KeeMenu *menu) { + GtkSingleSelection *sel; + KeeEntry *o; + GtkWidget *widget; + GtkWidget *container; + KeeEntry *showentry; + + sel = GTK_SINGLE_SELECTION(gtk_list_view_get_model(view)); + + o = KEE_ENTRY(gtk_single_selection_get_selected_item(sel)); + showentry = kee_entry_new(NULL); + kee_entry_apply_entry(showentry, o); + + container = kee_menu_next(menu, "entry"); + widget = gtk_widget_get_first_child(container); + if (widget) { + gtk_box_remove(GTK_BOX(container), widget); + } + kee_entry_apply_display_widget(showentry); + gtk_box_append(GTK_BOX(container), showentry); + + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "list item selected %d", i); +} + + +static void kee_entry_list_handle_setup(KeeEntryList* o, GtkListItem *item) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "entry list setup"); } -static void kee_entry_handle_bind(KeeEntryList *o, GtkListItem *item) { +static void kee_entry_list_handle_bind(KeeEntryList *o, GtkListItem *item) { KeeEntry *go; + GtkGesture *ctrl; g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "entry list bind"); go = gtk_list_item_get_item(item); g_object_take_ref(G_OBJECT(go)); gtk_list_item_set_child(item, GTK_WIDGET(go)); + //ctrl = gtk_gesture_long_press_new(); + //gtk_widget_add_controller(item, GtkEventController(ctrl)); } -static void kee_entry_handle_unbind(KeeEntryList* o, GtkListItem *item) { +static void kee_entry_list_handle_unbind(KeeEntryList* o, GtkListItem *item) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "entry list unbind"); //GObject *go; //go = gtk_list_item_get_child(item); @@ -37,7 +66,7 @@ static void kee_entry_handle_unbind(KeeEntryList* o, GtkListItem *item) { //g_object_unref(go); } -static void kee_entry_handle_teardown(KeeEntryList* o, GtkListItem *item) { +static void kee_entry_list_handle_teardown(KeeEntryList* o, GtkListItem *item) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "entry list teardown"); } @@ -46,13 +75,13 @@ static void kee_entry_list_class_init(KeeEntryListClass *kls) { static void kee_entry_list_init(KeeEntryList *o) { o->factory = gtk_signal_list_item_factory_new(); - g_signal_connect(o->factory, "setup", G_CALLBACK(kee_entry_handle_setup), NULL); - g_signal_connect(o->factory, "bind", G_CALLBACK(kee_entry_handle_bind), NULL); - g_signal_connect(o->factory, "unbind", G_CALLBACK(kee_entry_handle_unbind), NULL); - g_signal_connect(o->factory, "teardown", G_CALLBACK(kee_entry_handle_teardown), NULL); + g_signal_connect(o->factory, "setup", G_CALLBACK(kee_entry_list_handle_setup), NULL); + g_signal_connect(o->factory, "bind", G_CALLBACK(kee_entry_list_handle_bind), NULL); + g_signal_connect(o->factory, "unbind", G_CALLBACK(kee_entry_list_handle_unbind), NULL); + g_signal_connect(o->factory, "teardown", G_CALLBACK(kee_entry_list_handle_teardown), NULL); } -GtkWidget* kee_entry_list_new(GListModel *model) { +GtkWidget* kee_entry_list_new(GListModel *model, KeeMenu *win) { KeeEntryList *o; GtkSingleSelection *sel; GtkWidget *view; @@ -62,6 +91,7 @@ GtkWidget* kee_entry_list_new(GListModel *model) { sel = gtk_single_selection_new(model); view = gtk_list_view_new(GTK_SELECTION_MODEL(sel), o->factory); + g_signal_connect(view, "activate", G_CALLBACK(kee_entry_list_handle_select), win); gtk_box_append(GTK_BOX(o), view); diff --git a/src/gtk/kee-entry-list.h b/src/gtk/kee-entry-list.h @@ -4,12 +4,14 @@ #include <glib-object.h> #include <gtk/gtk.h> +#include "kee-menu.h" + G_BEGIN_DECLS #define KEE_TYPE_ENTRY_LIST kee_entry_list_get_type() G_DECLARE_FINAL_TYPE(KeeEntryList, kee_entry_list, KEE, ENTRY_LIST, GtkBox); -GtkWidget* kee_entry_list_new(GListModel *model); +GtkWidget* kee_entry_list_new(GListModel *model, KeeMenu *menu); G_END_DECLS diff --git a/src/gtk/kee-entry.c b/src/gtk/kee-entry.c @@ -158,3 +158,20 @@ void kee_entry_apply_list_item_widget(KeeEntry *o) { gtk_box_append(GTK_BOX(o), widget); return; } + +void kee_entry_apply_display_widget(KeeEntry *o) { + GtkWidget *widget; + + widget = gtk_label_new(o->subject); + gtk_box_append(GTK_BOX(o), widget); + return; +} + + +void kee_entry_apply_entry(KeeEntry *target, KeeEntry *orig) { + KeeEntry *o; + + target->resolver = orig->resolver; + target->subject = orig->subject; + return target; +} diff --git a/src/gtk/kee-entry.h b/src/gtk/kee-entry.h @@ -20,6 +20,7 @@ G_DECLARE_FINAL_TYPE(KeeEntry, kee_entry, KEE, ENTRY, GtkBox); int kee_entry_load(KeeEntry *o, struct db_ctx *db, const char *id); int kee_entry_deserialize(KeeEntry *o, const char *key, size_t key_len, const char *data, size_t data_len); void kee_entry_apply_list_item_widget(KeeEntry *o); +void kee_entry_apply_display_widget(KeeEntry *o); KeeEntry* kee_entry_new(struct Cadiz *resolver); G_END_DECLS diff --git a/src/gtk/kee-menu.c b/src/gtk/kee-menu.c @@ -23,6 +23,10 @@ struct _KeeMenuClass { G_DEFINE_TYPE(KeeMenu, kee_menu, GTK_TYPE_APPLICATION_WINDOW); +static void kee_menu_act_back(GAction *act, GVariant *param, KeeMenu *menu) { + kee_menu_prev(menu); +} + static void kee_menu_act_import(GAction *act, GVariant *param, GtkStack *stack) { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, "act impot"); gtk_stack_set_visible_child_name(stack, "import"); @@ -36,7 +40,10 @@ static void kee_menu_class_init(KeeMenuClass *kls) { } static void kee_menu_init(KeeMenu *o) { - memset(&o->nav, 0, sizeof(struct KeeNav)); + //memset(&o->nav, 0, sizeof(struct KeeNav)); + o->nav.c = 0; + o->nav.widgets[0] = 0; + o->nav.now = 0; o->head = GTK_HEADER_BAR(gtk_header_bar_new()); o->stack = GTK_STACK(gtk_stack_new()); } @@ -54,9 +61,14 @@ KeeMenu* kee_menu_new(GtkApplication *gapp) { butt = menu_button_setup(G_OBJECT(o->head), gapp); gtk_header_bar_pack_end(GTK_HEADER_BAR(o->head), butt); + act = g_simple_action_new("back", NULL); + g_action_map_add_action(G_ACTION_MAP(o), G_ACTION(act)); + g_simple_action_set_enabled(act, false); butt = gtk_button_new_from_icon_name("go-previous"); gtk_header_bar_pack_start(GTK_HEADER_BAR(o->head), butt); - gtk_widget_set_visible(butt, false); + //gtk_widget_set_visible(butt, false); + gtk_actionable_set_action_name(GTK_ACTIONABLE(butt), "win.back"); + g_signal_connect(act, "activate", G_CALLBACK(kee_menu_act_back), o); act = g_simple_action_new("import", NULL); g_action_map_add_action(G_ACTION_MAP(o), G_ACTION(act)); @@ -86,6 +98,9 @@ static void kee_menu_header_update(KeeMenu *o, const char *label) { } else if (!(strcmp(label, "view"))) { act = g_action_map_lookup_action(G_ACTION_MAP(o), "import"); g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); + } else if (!(strcmp(label, "entry"))) { + act = g_action_map_lookup_action(G_ACTION_MAP(o), "back"); + g_simple_action_set_enabled(G_SIMPLE_ACTION(act), true); } else if (!(strcmp(label, "import"))) { } else { g_log(G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "unknown nav label: %s", label); @@ -97,13 +112,14 @@ int kee_menu_add(KeeMenu *o, const char *label, GtkWidget *widget) { return ERR_OK; } -int kee_menu_next(KeeMenu *o, const char *label) { +GtkWidget* kee_menu_next(KeeMenu *o, const char *label) { GtkWidget *widget; widget = gtk_stack_get_child_by_name(o->stack, label); kee_nav_push(&o->nav, widget); gtk_stack_set_visible_child(o->stack, widget); - return ERR_OK; + kee_menu_header_update(o, label); + return widget; } int kee_menu_prev(KeeMenu *o) { @@ -112,7 +128,6 @@ int kee_menu_prev(KeeMenu *o) { kee_nav_pop(&o->nav); gtk_stack_set_visible_child(o->stack, o->nav.now); label = gtk_stack_get_visible_child_name(o->stack); - kee_menu_header_update(o, label); return ERR_OK; diff --git a/src/gtk/kee-menu.h b/src/gtk/kee-menu.h @@ -20,7 +20,7 @@ G_DECLARE_FINAL_TYPE(KeeMenu, kee_menu, KEE, MENU, GtkApplicationWindow); KeeMenu* kee_menu_new(GtkApplication *app); int kee_menu_add(KeeMenu *o, const char *k, GtkWidget *v); -int kee_menu_next(KeeMenu *o, const char *k); +GtkWidget* kee_menu_next(KeeMenu *o, const char *k); int kee_menu_prev(KeeMenu *o); G_END_DECLS diff --git a/src/gtk/nav.c b/src/gtk/nav.c @@ -2,29 +2,75 @@ #include "nav.h" +static void kee_nav_log(struct KeeNav *nav) { + char s[128]; + char out[1024]; + int c; + int i; -void kee_nav_push(struct KeeNav *nav, GtkWidget *page) { - struct KeeNav *nav_old; + c = 0; + for (i = 0; i < nav->c + 1; i++) { + sprintf(s, "[%d:%p] ", i, nav->widgets[i]); + sprintf(out+c, s); + c += strlen(s); + } + g_log(G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "nav now %p: %s", nav->now, out); +} - nav_old = malloc(sizeof(struct KeeNav)); - nav_old->prev = nav->prev; - nav_old->now = nav->now; - nav->prev = nav_old; - nav->now = page; +void kee_nav_push(struct KeeNav *nav, GtkWidget *page) { + nav->c++; + nav->widgets[nav->c] = page; + nav->now = nav->widgets[nav->c]; + kee_nav_log(nav); } GtkWidget* kee_nav_pop(struct KeeNav *nav) { - struct KeeNav *nav_old; GtkWidget *r; - if (!nav->prev) { + if (nav->c == 0) { return NULL; } - - r = nav->now; - nav_old = nav->prev->prev; - nav->now = nav->prev->now; - free(nav->prev); - nav->prev = nav_old; - return r; + r = nav->widgets[nav->c]; + nav->c--; + nav->now = nav->widgets[nav->c]; + kee_nav_log(nav); } + + +int kee_nav_is_top(struct KeeNav *nav) { + return nav->c == 0; +} + + +// +//void kee_nav_push(struct KeeNav *nav, GtkWidget *page) { +// struct KeeNav *nav_old; +// +// nav_old = malloc(sizeof(struct KeeNav)); +// nav_old->prev = nav->prev; +// nav_old->now = nav->now; +// nav->prev = nav_old; +// nav->now = page; +//} +// +// +//GtkWidget* kee_nav_pop(struct KeeNav *nav) { +// struct KeeNav *nav_old; +// GtkWidget *r; +// +// if (!nav->prev) { +// return NULL; +// } +// +// r = nav->now; +// nav_old = nav->prev->prev; +// nav->now = nav->prev->now; +// free(nav->prev); +// nav->prev = nav_old; +// return r; +//} +// +// +//int kee_nav_is_top(struct KeeNav *nav) { +// return !nav->prev; +//} diff --git a/src/gtk/nav.h b/src/gtk/nav.h @@ -4,11 +4,15 @@ #include <gtk/gtk.h> struct KeeNav { +// GtkWidget *now; +// struct KeeNav *prev; GtkWidget *now; - struct KeeNav *prev; + GtkWidget *widgets[128]; + int c; }; void kee_nav_push(struct KeeNav *nav, GtkWidget *page); GtkWidget* kee_nav_pop(struct KeeNav *nav); +int kee_nav_is_top(struct KeeNav *nav); #endif // _KEE_NAV_H diff --git a/src/gtk/scan.c b/src/gtk/scan.c @@ -13,6 +13,7 @@ void scan_init(struct kee_scanner *scan, const char *device) { strcpy(scan->device, device); } +/// \todo determine caps from environment int scan_begin(struct kee_scanner *scan) { GstElement *tee; GstElement *zbar; diff --git a/src/gtk/tests/Makefile b/src/gtk/tests/Makefile @@ -1,8 +1,10 @@ +# TODO: test files are only generated on second run + OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) -LINKOBJS := $(wildcard ../../*.o) $(wildcard ../*.o) ../../aux/varint/varint.o +LINKOBJS := $(wildcard ../../*.o) $(wildcard ../*.o) INCLUDES := -I../.. -I.. CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0` $(INCLUDES) -g3 -Wall -LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 +LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -lvarint -lcmime LDFLAGS += $(LIBS) all: $(OBJS) diff --git a/src/gtk/tests/nav.c b/src/gtk/tests/nav.c @@ -4,13 +4,15 @@ int main(int argc, char **argv) { struct KeeNav nav; - GtkWidget *a; - GtkWidget *b; - GtkWidget *r; + GtkLabel *a; + GtkLabel *b; + GtkLabel *c; + GtkLabel *r; gtk_init(); a = gtk_label_new("foo"); b = gtk_label_new("bar"); + c = gtk_label_new("baz"); kee_nav_push(&nav, a); kee_nav_push(&nav, b); @@ -28,6 +30,17 @@ int main(int argc, char **argv) { return 1; } + kee_nav_push(&nav, c); + r = kee_nav_pop(&nav); + if (r != c) { + return 1; + } + + r = kee_nav_pop(&nav); + if (r) { + return 1; + } + r = kee_nav_pop(&nav); if (r) { return 1; diff --git a/src/gtk/ui.c b/src/gtk/ui.c @@ -58,7 +58,7 @@ void ui_build(GtkApplication *app, KeeEntryStore *store) { kee_menu_add(win, "unlock", widget); g_signal_connect (widget, "unlock", G_CALLBACK(ui_handle_unlock), win); - widget = kee_entry_list_new(G_LIST_MODEL(store)); + widget = kee_entry_list_new(G_LIST_MODEL(store), win); kee_menu_add(win, "view", widget); kee_menu_next(win, "view"); @@ -67,6 +67,9 @@ void ui_build(GtkApplication *app, KeeEntryStore *store) { import = kee_import_new(win); kee_menu_add(win, "import", GTK_WIDGET(import)); + widget = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0); + kee_menu_add(win, "entry", widget); + gtk_window_present(GTK_WINDOW (win)); } diff --git a/src/tests/Makefile b/src/tests/Makefile @@ -1,8 +1,10 @@ +# TODO: test files are only generated on second run +# OBJS := $(patsubst %.c,%.o,$(wildcard *.c)) -LINKOBJS := $(wildcard ../*.o) ../aux/varint/varint.o +LINKOBJS := $(wildcard ../*.o) INCLUDES := -I.. CFLAGS += `pkg-config --cflags gtk4 gstreamer-1.0` $(INCLUDES) -g3 -Wall -LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 +LIBS := `pkg-config --libs gtk4 zlib lmdb libgcrypt libxdg-basedir gstreamer-1.0` -lb64 -lvarint LDFLAGS += $(LIBS) all: obj_debug $(OBJS) diff --git a/src/tests/cadir.c b/src/tests/cadir.c @@ -9,10 +9,12 @@ int main(int argc, char **argv) { char digest[64]; char result[256]; size_t l; + Cadiz cadiz; calculate_digest_algo(data, 3, digest, GCRY_MD_SHA512); l = 256; - r = cadiz_resolve("./testdata_resource", CADIZ_KEY_TYPE_ANY, digest, result, &l); + cadiz.locator = "./testdata_resource"; + r = cadiz_resolve(&cadiz, digest, result, &l); if (r) { return 1; }